Orders
If CheckoutSession is what the buyer sees, Order is what you care about. It’s the permanent record of:
- What was being bought (line items)
- How much was owed and how much has actually been paid
- Refunds outstanding and applied
- Your external reference (
external_ref) — typically your own order ID, stored on the Order and returned onGET /b2b/v1/orders/{id}(not echoed in webhook payloads — see below)
An order does not need line items: send amount instead of items to bill a plain amount (an invoice, a deposit, a custom payment link). Send one or the other, never both.
A CheckoutSession dies after one of its PaymentIntents settles or the TTL expires. The Order lives forever.
When an Order is created
When you call POST /b2b/v1/checkout-sessions/quick, InfraIO Pay
creates both a new Order and a new CheckoutSession
in one transaction. If you already have an Order and want to retry
checkout (e.g., after the buyer abandoned), use
POST /b2b/v1/checkout-sessions instead to attach a fresh session
to the existing order — preserving the audit trail.
Lifecycle
| State | Means |
|---|---|
PENDING | A CheckoutSession is live and unresolved. |
PAID | Full amount settled. The webhook payment.settled fires here. Safe to fulfill. |
PARTIAL_PAID | Money arrived but less than total. See “Underpayment” below. |
CANCELED | Session expired or merchant cancelled. metadata.canceled_reason explains why (payment_timeout, merchant_canceled, …). |
REFUNDED | All paid amount has been refunded. |
PARTIALLY_REFUNDED | Some refund executed but balance remains paid. |
The state to switch your fulfillment logic on is PAID — not
the CheckoutSession’s COMPLETED. The payment.settled webhook
is the canonical signal.
The external_ref field
When creating a session you can include external_ref (any string
up to 255 chars — typically your own order ID). It threads through
the whole pipeline:
- Stored on the Order
- Visible in the merchant dashboard for support lookups
- Returned on
GET /b2b/v1/orders/{id}so a webhook handler can fetch it after receivingpayment.settled
Webhook payloads do not include external_ref. To map a payment.*
webhook back to your own record, take order_id from the payload and
fetch the order.
Underpayment
If the buyer’s on-chain transfer clears for less than the order
total, the Order goes to PARTIAL_PAID. You have three options:
- Accept and resolve. Flips the order to
PAIDand firesorder.resolved. This isn’t available through the REST API, so for a self-serve flow use option 2 (collect the remainder). - Wait for the remainder. Create a new CheckoutSession against
the same Order with
amount_due= residual. The buyer pays the difference; when that settles, Order moves toPAID. - Cancel and refund. Refund the partial amount and cancel the Order. The buyer is responsible for any chain fees.
Refunds
Refunds are a separate API surface and a separate concept page. See Concepts → Refunds.
API endpoints
| Method | Path | Notes |
|---|---|---|
POST | /b2b/v1/orders | Create an Order without a session (rare) |
GET | /b2b/v1/orders/:order_id | Read full order with line items + payment history |
PATCH | /b2b/v1/orders/:order_id/cancel | Cancel an unpaid order |
PATCH | /b2b/v1/orders/:order_id/reopen | Reopen an auto-canceled (payment_timeout) order |
What’s next
- Concepts → Sessions — the buyer-facing shell that wraps an Order.
- Concepts → Refunds — refund states and the manual on-chain submission step.
- Webhooks → Overview — every event fired during an Order’s lifecycle.