Skip to main content
Every Crossmint Checkout order moves through the same lifecycle, regardless of whether you integrate with Embedded, Headless, or Hosted checkout. Embedded and Hosted handle most of this for you; Headless integrations drive each transition explicitly through the Orders API. The lifecycle has four phases: quote → payment → delivery → completed. An order can also move backwards — for example, from payment back to quote if the quote expires.

Quote Phase

In the quote phase you construct the order: the items being purchased (lineItems), the payment method, the locale, and the recipient. The result is a price quote for the purchase. You can complete the quote phase in a single POST /api/2022-06-09/orders call, or create a minimal order and iteratively update it with the recipient, locale, and payment details as the buyer makes selections.
  • The lineItems array cannot be edited after creation — to change what is being purchased, create a new order
  • Every order requires a recipient (email or wallet address) to leave the quote phase
  • Quotes expire. Check quote.expiresAt for validity; an expired quote means creating a new order
  • Items are identified by collectionLocator (new tokens from a registered collection) or tokenLocator (existing tokens on a marketplace). See Select Items
During the quote phase payment.status is requires-quote. See the full list of statuses in Error & Status Codes.

Payment Phase

Once the order has everything it needs, it enters the payment phase with payment.status set to awaiting-payment — or requires-crypto-payer-address if the buyer’s wallet address is still missing. How the buyer pays depends on the method:
For card payments, the create/update order response returns a clientSecret and the order object. Your application renders the Crossmint Embedded Component with them to collect the card details securely — the buyer completes payment inside that component.
While the payment is underway, poll GET /api/2022-06-09/orders/{orderId} (about every 2500ms, never below 500ms) or use webhooks to track payment.status as it moves to in-progress and then completed.

Declines and Refunds

When a card payment is declined, the order usually returns to awaiting-payment with a payment.failureReason object carrying a normalized code, category, retryPolicy, and a user-safe message. Render the message to the buyer and use retryPolicy to decide whether to offer a retry. See Handle Errors. An order can also show payment.status as completed together with a payment.refunded object — the payment succeeded but was later refunded. In that state, display a refund notice and prevent further delivery expectations.

Delivery Phase

Once payment completes, the order enters the delivery phase. The buyer is guaranteed to receive the items or an automatic refund for any unfulfilled items. Poll the GET order API and watch each line item’s delivery.status: awaiting-payment → in-progress → completed or failed. Show delivery progress in your UI while items are minted or transferred.

Completed Phase

The order reaches phase: "completed" when every line item reaches a final state.
order.phase === "completed" does not mean every line item succeeded. The phase completes once all items are final — whether completed or failed. Always check each line item’s delivery.status individually.
At completion, point the buyer to their purchase — for example https://www.crossmint.com/user/collection/<chain>:<contractAddress>:<tokenId> for items minted to a Crossmint wallet — and suggest next steps like staking or trading.
Key takeaway: build your UI around order.phase for the big picture and the quote, payment, and delivery statuses for detail. Never assume a completed phase means every item was delivered.

See Also

Track Orders

Poll the Orders API or subscribe to webhook events

Error & Status Codes

The full list of quote, payment, and delivery statuses