- Check an order’s status and know which fields to watch
- Follow an order through each phase of its lifecycle
- Map each status to the right UI state and next action
- Receive order updates through webhooks instead of polling
- Troubleshoot expired quotes and rejected payouts
Check order status
Fetch an order any time with itsorderId (see the Get Order API reference for the complete response schema):
phase: the high-level stage of the orderpayment.status: whether the stablecoin deposit has been receivedlineItems[0].delivery.status: whether the fiat payout is pending, in transit, completed, or failed
A completed order can still show
quote.status: "expired" because the quote time window closes independently of payment and delivery. By itself, this does not indicate a problem. Rely on phase, payment.status, and lineItems[].delivery.status to determine the order outcome.Order lifecycle
The full status model has four phases. Offramp orders start inpayment, with the quote included inside the order, then move through delivery to completed when the payout reaches a terminal outcome. The quote phase appears if the quote expires before the deposit arrives.

Payment: waiting for the deposit
After the order is created and the quote is locked, the order sits in the If no deposit arrives before the quote expires, the order returns to the
payment phase until the stablecoin deposit arrives on-chain and is matched by memo.quote phase with payment.status: "requires-quote". See Quote expired below.Delivery: fiat payout in progress
Once the deposit lands, Crossmint converts the stablecoin and initiates the fiat payout. The order moves to the
delivery phase.Offramp settlement has two asynchronous parts: receiving the stablecoin deposit and completing the fiat payout. After
payment.status becomes completed, the order may remain in delivery while the payout is being prepared, processed by the rail, or delayed by weekends and bank holidays. For rail-specific timing, see Payment Schemes.Order status reference
Each field below returns one of a fixed set of values. Expand a field for the full list.phase
phase
| Value | Meaning |
|---|---|
quote | Quote pending or expired; no deposit has been taken yet |
payment | Quote locked; waiting for or processing the on-chain stablecoin deposit |
delivery | Stablecoin deposit received; fiat payout is pending or in progress |
completed | Terminal. Check delivery.status for the outcome |
payment.status
payment.status
In the standard offramp flow,
payment.status typically moves through awaiting-payment, in-progress, and completed. The other statuses listed below represent missing setup steps, verification requirements, or payer-wallet conditions.| Value | Meaning |
|---|---|
requires-quote | A new or refreshed quote is needed (for example, the previous quote expired) |
requires-crypto-payer-address | The payer wallet address has not been set yet |
requires-email | A receipt email is required before payment can proceed |
requires-kyc | Identity verification (KYC) is required before payment can proceed |
pending-kyc-review | KYC submission is under review |
manual-kyc | KYC requires manual review |
failed-kyc | KYC verification was rejected |
requires-recipient-verification | The recipient must complete wallet ownership verification |
awaiting-deposit-instructions | Deposit instructions are being prepared; wait until the order returns awaiting-payment before asking the user to send the deposit |
awaiting-payment | Quote accepted; waiting for the user to send the stablecoin deposit |
crypto-payer-insufficient-funds | The payer wallet does not have enough funds for the deposit |
crypto-payer-insufficient-funds-for-gas | The payer wallet does not have enough native token to pay network gas |
in-progress | Stablecoin deposit detected; waiting for on-chain confirmations |
completed | Stablecoin deposit received and matched to the order |
lineItems[0].delivery.status
lineItems[0].delivery.status
| Value | Meaning |
|---|---|
awaiting-payment | Fiat payout not yet initiated |
in-progress | Fiat payout initiated; awaiting rail completion |
completed | Fiat payout completed |
failed | Payout could not be completed (for example, bank rejected the transfer) |
Failure reasons
Failure reasons
When a deposit cannot be processed or a payout fails, the order response may include a structured failure reason:
payment.failureReason: may be present when the deposit cannot be processed. Shape:{ code, message?, developerMessage? }.lineItems[].delivery.failureReason: may be present when the fiat payout fails. Shape:{ code, message? }. Possible codes:transfer-failed,slippage-tolerance-exceeded,payment-refunded.
Payment failure reasons are returned on the order object. If you need to detect deposit-processing issues before a delivery event fires, refetch the order with the Get Order API and inspect
payment.status and payment.failureReason.Status-handling reference
Use this table to decide what to show the user and what action to take:phase | payment.status | delivery.status | Meaning | Developer action |
|---|---|---|---|---|
payment | awaiting-payment | awaiting-payment | Waiting for stablecoin deposit | Show deposit instructions |
payment | in-progress | awaiting-payment | Stablecoin deposit detected; waiting for on-chain confirmations | Show “Payment confirming”; do not ask the user to resend funds |
delivery | completed | awaiting-payment | Stablecoin deposit received; fiat payout not yet initiated | Show “Payout pending”; do not ask the user to resend funds |
delivery | completed | in-progress | Stablecoin deposit received; fiat payout awaiting rail completion | Show “Payout on the way”; do not ask the user to resend funds |
completed | completed | completed | Payout completed successfully | Show “Funds sent” confirmation |
completed | completed | failed | Payout failed | Check payment.refunded for refund details; prompt user to retry with corrected bank details |
quote | requires-quote | awaiting-payment | Quote expired before deposit | Create a new order with a fresh quote |
Less common payment statuses
Less common payment statuses
These statuses may appear during order setup or when the payer wallet has issues. Use
payment.status as the key to decide what to show:payment.status | Meaning | Developer action |
|---|---|---|
requires-crypto-payer-address | Payer wallet address is missing | Provide the payer wallet address, then refetch the order |
requires-email | Receipt email is required | Collect the email, then refetch the order |
requires-kyc | Identity verification is required | Send the user through verification before showing deposit instructions |
pending-kyc-review, manual-kyc | Identity verification is under review | Show verification pending and wait for the status to update |
failed-kyc | Identity verification was rejected | Do not ask the user to send funds; show the verification failure state |
requires-recipient-verification | Wallet ownership verification is required | Complete recipient verification, then refetch the order |
awaiting-deposit-instructions | Deposit instructions are being prepared | Wait until the order returns awaiting-payment before showing deposit instructions |
crypto-payer-insufficient-funds | Payer wallet does not have enough stablecoin for the deposit | Ask the user to fund the wallet or use another wallet |
crypto-payer-insufficient-funds-for-gas | Payer wallet does not have enough native token for gas | Ask the user to add gas or use a wallet with gas sponsorship |
Webhooks
Instead of polling, subscribe to order events so Crossmint notifies your backend as the order progresses. Configure an endpoint in the Crossmint console and subscribe to events using the Webhooks guide. The events relevant to the standard offramp progression are:| Event | Fires when |
|---|---|
orders.payment.succeeded | The on-chain stablecoin deposit is matched to the order |
orders.delivery.initiated | The fiat payout has been initiated |
orders.delivery.completed | The fiat payout has completed |
orders.delivery.failed | The payout could not be completed |
orders.delivery.initiated and “funds sent” when you receive orders.delivery.completed.
Troubleshooting
An offramp order spans two independent systems: an on-chain stablecoin deposit and a fiat payout over banking rails. Most orders complete on their own, but a few situations can interrupt the standard flow, most often a quote that expires before the deposit arrives or a payout the bank declines. Both are expected and recoverable. Expand a case below to see how to detect and resolve it.Quote expired
Quote expired
If the user does not send the stablecoin deposit before the quote expires, the order returns to the The exchange rate is stale. Create a new order to get a fresh quote.
quote phase. No funds are collected.Bank rejection
Bank rejection
If the bank rejects the payout after the stablecoin deposit has been received (for example, invalid account details), the order moves to Check
completed with a failed delivery. The buyer deposit is automatically refunded.payment.refunded to confirm the refund details. Listen for orders.delivery.failed so you can surface the issue in your app and prompt the user to try again with corrected bank details.Next steps
Quickstart
Build the full flow
Launch in Production
Move from staging to live payouts

