On this pageSequence DiagramStep-by-StepState FlowUnderpayment HandlingOrder Expiration

Payment Flow

The complete payment lifecycle from order creation to settlement.

Sequence Diagram

View diagram source
sequenceDiagram
    participant M as Merchant Server
    participant H as HashNut API
    participant B as Blockchain
    participant C as Customer

    M->>H: 1. Create Order
    H-->>M: payOrderId, receiptAddress, payUrl

    M->>C: 2. Redirect to payUrl / show receiptAddress

    C->>B: 3. Transfer tokens to receiptAddress
    B-->>H: 4. Detect incoming transfer
    Note over H: Order state → PAID (1)

    B-->>H: 5. Block confirmations
    Note over H: Order state → CONFIRMING (2)
    Note over H: Order state → SUCCESS (3)

    H->>M: 6. POST webhook to Notify URL
    M-->>H: 7. HTTP 200 "success"

Step-by-Step

StepActionDescription
1Create OrderMerchant calls POST /v4.0.0/pay/orders/api. HashNut returns receiptAddress and payOrderId.
2Display PaymentRedirect customer to payUrl, or build your own page with receiptAddress and amount.
3Customer PaysCustomer sends the token amount to receiptAddress on the specified chain.
4DetectionHashNut detects the transfer. Order state → PAID (1).
5ConfirmationsHashNut waits for required block confirmations. State → CONFIRMING (2), then SUCCESS (3).
6WebhookHashNut POSTs to the merchant's Notify URL with the payment result.
7AcknowledgeMerchant responds with HTTP 200 + body success.

State Flow

View diagram source
stateDiagram-v2
    [*] --> INIT: Create Order
    INIT --> PAID: Payment detected
    INIT --> EXPIRED: Timeout
    INIT --> CANCELED: Merchant cancels

    PAID --> CONFIRMING: Tx in block
    CONFIRMING --> SUCCESS: Confirmations reached
    CONFIRMING --> FAILED: Tx reverted

    SUCCESS --> FINISH: Funds settled

Underpayment Handling

If the customer sends less than the required amount, HashNut creates a supplement order for the remaining balance.

ScenarioBehavior
Partial paymentSupplement order created for the difference
Multiple partialsEach partial generates a new supplement until full amount covered
Query supplementsUse Query Supplements API

WARNING

Supplement orders share the same payOrderId. Always check the supplement list when the order state does not progress to SUCCESS.

Order Expiration

  • Default expiration: configurable via expireDuration (max 259,200 seconds = 3 days)
  • Expired orders release their receipt address back to the pool
  • Expired orders cannot be resumed — create a new order

DANGER

Do NOT reuse receipt addresses from expired orders. Always create a new order to get a fresh address.