Skip to main content

Order States

Understanding order states is crucial for building reliable payment integrations. HashNut uses a numeric state system to track orders throughout their lifecycle.

State Overview

Active States (In Progress)

State 0: Unpaid

Code: 0
Status: unpaid

Description: Order has been created but no payment has been received.

What Happens:

  • Order is waiting for customer payment
  • Payment link is active
  • Customer can proceed with payment

Merchant Actions:

  • ✅ View payment link
  • ✅ Cancel order
  • ✅ Monitor order status

Next States:

  • 1 (Not Completed) - Customer initiates payment
  • -2 (Expired) - Order expires
  • -3 (Cancelled) - Merchant cancels

State 1: Not Completed

Code: 1
Status: notCompleted

Description: Payment transaction has been initiated but not yet completed.

What Happens:

  • Customer has started payment
  • Transaction is being prepared
  • Waiting for wallet confirmation

Merchant Actions:

  • ✅ Monitor order
  • ✅ Can cancel if needed
  • ⚠️ Wait for completion

Next States:

  • 2 (Waiting for Confirmation) - Transaction broadcast
  • -1 (Failed) - Transaction rejected

State 2: Waiting for Blockchain Confirmation

Code: 2
Status: waitingForBlockchainConfirmation

Description: Transaction has been broadcast to blockchain, awaiting confirmation.

What Happens:

  • Transaction is on blockchain
  • Waiting for block inclusion
  • Confirmation count increasing

Merchant Actions:

  • ✅ Monitor confirmation progress
  • ✅ Check transaction on blockchain explorer
  • ⚠️ Wait for confirmations

Next States:

  • 3 (Confirming) - Block confirmed
  • -1 (Failed) - Transaction failed

State 3: Confirming

Code: 3
Status: confirming

Description: Transaction confirmed on blockchain, system is verifying payment details.

What Happens:

  • Transaction confirmed
  • HashNut verifying:
    • Amount matches
    • Address is correct
    • Token is correct
    • Sufficient confirmations

Merchant Actions:

  • ✅ Order is being processed
  • ⚠️ Wait for verification

Next States:

  • 4 (Success) - Payment verified
  • -1 (Failed) - Verification failed

State 4: Success

Code: 4
Status: success

Description: Payment successfully received and verified, order is complete.

What Happens:

  • ✅ Payment verified
  • ✅ Funds in smart contract
  • ✅ Webhook sent (if configured)
  • ✅ Order complete

Merchant Actions:

  • ✅ Fulfill order
  • ✅ Update database
  • ✅ Process business logic

Next States: None (terminal state)

Terminal States (Final)

State -1: Failed

Code: -1
Status: failed

Description: Payment transaction failed or was rejected.

Common Causes:

  • Customer rejected transaction
  • Insufficient balance
  • Transaction execution failed
  • Network error

Merchant Actions:

  • ✅ Review failure reason
  • ✅ Create new order if needed
  • ✅ Contact customer if necessary

Next States: None (terminal state)

State -2: Expired

Code: -2
Status: expired

Description: Order expired without payment within the configured time limit.

What Happens:

  • Order is no longer valid
  • Payment link is inactive
  • Customer cannot pay

Merchant Actions:

  • ✅ Create new order if needed
  • ✅ Notify customer
  • ✅ Clean up expired orders

Next States: None (terminal state)

State -3: Cancelled

Code: -3
Status: cancelled

Description: Order was cancelled by merchant or system.

What Happens:

  • Order intentionally cancelled
  • Payment link is inactive
  • No payment can be made

Merchant Actions:

  • ✅ Order closed
  • ✅ Create new order if needed

Next States: None (terminal state)

State Reference Table

StateCodeStatusTypeDescription
Unpaid0unpaidActiveAwaiting payment
Not Completed1notCompletedActivePayment initiated
Waiting for Confirmation2waitingForBlockchainConfirmationActiveTransaction broadcast
Confirming3confirmingActiveVerifying payment
Success4successTerminalPayment complete
Failed-1failedTerminalPayment failed
Expired-2expiredTerminalOrder expired
Cancelled-3cancelledTerminalOrder cancelled

Handling States in Code

Check Order State

import { QueryOrderRequest } from '@hashnut/sdk';

const queryRequest = new QueryOrderRequest.Builder()
.withPayOrderId(payOrderId)
.withMerchantOrderId(merchantOrderId)
.withAccessSign(accessSign)
.build();

const queryResponse = await service.queryOrder(queryRequest);
const order = queryResponse.data;

// Handle different states
switch (order.state) {
case 0:
console.log('Order unpaid - waiting for payment');
break;
case 1:
case 2:
case 3:
console.log('Payment in progress...');
break;
case 4:
console.log('Payment successful!');
await fulfillOrder(merchantOrderId);
break;
case -1:
console.log('Payment failed');
await handlePaymentFailure(merchantOrderId);
break;
case -2:
console.log('Order expired');
await handleExpiredOrder(merchantOrderId);
break;
case -3:
console.log('Order cancelled');
break;
}

Webhook State Handling

app.post('/webhook', async (req, res) => {
const { state, merchantOrderId } = req.body;

// Only process terminal states
if (state === 4) {
// Payment successful
await fulfillOrder(merchantOrderId);
} else if (state < 0) {
// Payment failed, expired, or cancelled
await handleOrderTermination(merchantOrderId, state);
}
// Active states (0-3) are informational only

res.send('success');
});

State Transitions

Normal Flow

0 (Unpaid) 
→ 1 (Not Completed)
→ 2 (Waiting for Confirmation)
→ 3 (Confirming)
→ 4 (Success)

Failure Flow

0 (Unpaid) 
→ 1 (Not Completed)
→ -1 (Failed) [Transaction rejected]
0 (Unpaid) 
→ 1 (Not Completed)
→ 2 (Waiting for Confirmation)
→ -1 (Failed) [Transaction failed]

Expiration Flow

0 (Unpaid) 
→ -2 (Expired) [Timeout]

Cancellation Flow

0 (Unpaid) 
→ -3 (Cancelled) [Manual cancellation]

Best Practices

State Monitoring

  1. Poll Active Orders: Regularly check orders in states 0-3
  2. Handle Terminal States: Always handle states 4, -1, -2, -3
  3. Idempotency: Ensure state changes are idempotent
  4. Logging: Log all state transitions for debugging

State-Based Actions

const stateHandlers = {
0: () => console.log('Waiting for payment'),
1: () => console.log('Payment initiated'),
2: () => console.log('Transaction confirming'),
3: () => console.log('Verifying payment'),
4: async (orderId) => {
await fulfillOrder(orderId);
await sendConfirmationEmail(orderId);
},
'-1': async (orderId) => {
await notifyCustomer(orderId, 'Payment failed');
await createRetryOrder(orderId);
},
'-2': async (orderId) => {
await notifyCustomer(orderId, 'Order expired');
},
'-3': () => console.log('Order cancelled'),
};

Next Steps


Understand states? Learn about Order Management →