Checkout
Payer-facing, publishable-key endpoints
GET /v1/checkout/exchanges
Exchange withdrawal networks and fees.
For each exchange: the network's name in that exchange's withdrawal screen and its withdrawal fee, so
the checkout can say "choose Tron (TRC20) and send 51.50 (includes Binance's 1.50 fee)". A label or
fee is present only if it was verified against the exchange's own public page (source_url, on
verified_at); otherwise it is null and the checkout uses generic wording.
Authentication: Publishable key or Publishable key as a query parameter (for EventSource) or Secret key
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
key | query | string | Publishable key, when it cannot go in the Authorization header |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | ExchangeList application/json |
GET /v1/checkout/invoices/{id}
The payer's view of an invoice.
Every payment option carries address_derivation: the checkout must recompute the deposit
address from it, compare the destination with the merchant destination pinned in its own config, and
refuse to display the address on any mismatch.
Authentication: Publishable key or Publishable key as a query parameter (for EventSource) or Secret key
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
idrequired | path | string | Invoice id (inv_…) |
key | query | string | Publishable key, when it cannot go in the Authorization header |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | CheckoutInvoice application/json | |
| 404 | ErrorResponse application/json |
GET /v1/checkout/invoices/{id}/lookup
"Already sent? Find my payment."
Looks a transaction hash up on this invoice's networks and says where the transfer went and whether
it is attributed to this invoice. Informational only: a lookup never credits a payment. Payments
are attributed only by the deposit address lease (or a bound sender), from our own chain
observations. Rate-limited per key and client address (429 with Retry-After).
Authentication: Publishable key or Publishable key as a query parameter (for EventSource) or Secret key
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
idrequired | path | string | Invoice id (inv_…) |
tx_hashrequired | query | string | Transaction hash: 0x + 64 hex digits, or 64 hex digits (TRON), or a Solana signature (base58) |
key | query | string | Publishable key, when it cannot go in the Authorization header |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | TxLookup application/json | |
| 400 | ErrorResponse application/json | |
| 404 | ErrorResponse application/json | |
| 429 | Too many lookups; retry after | ErrorResponse application/json |
POST /v1/checkout/invoices/{id}/notify
Email me a receipt.
The payer may leave an email address (never required). A receipt is sent once the invoice is paid
(right away if it already is), and a notice of any refund the merchant creates for it (never the
claim link: this route takes only the publishable key, so the address proves nothing). Nothing
is sent before a payment arrived. Send the checkout view's session_token: the first address binds
the invoice's receipt to that session, and only the same session may replace it (at most 3
different addresses per invoice). Emails come from the merchant's name. Rate-limited per key and
client address.
Authentication: Publishable key or Secret key
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
idrequired | path | string | Invoice id (inv_…) |
Idempotency-Keyrequired | header | string | Unique per submission |
Request body
application/json
| Field | Type | Description |
|---|---|---|
emailrequired | string | Where to send the receipt (and any refund link).
|
locale | string or null | The payer's language for the emails (
|
session_tokenrequired | string | The checkout view's
|
Responses
| Status | Description | Body |
|---|---|---|
| 200 | PayerNotice application/json | |
| 400 | Not a valid email address or locale, or | ErrorResponse application/json |
| 404 | ErrorResponse application/json | |
| 409 | Too many different addresses for this invoice, the address was set from another checkout session ( | ErrorResponse application/json |
| 429 | Too many requests; retry after | ErrorResponse application/json |
POST /v1/checkout/invoices/{id}/payment_option
Pick a payment option: lease its deposit address.
A payment-link invoice holds no deposit address until its payer picks a network: its options are
listed in pending_options, and this call leases the chosen network's address (the same address
covers every EVM network the invoice offers) and returns the invoice with that option in
payment_options, ready to verify and show. Picking an option that already has its address changes
nothing, so a retry is safe. If no network is picked by select_by, the invoice expires. 409 invoice_not_awaiting_payment once it is closed, 409 deposit_addresses_exhausted when no address
is free right now. Rate-limited per key and client address.
Authentication: Publishable key or Secret key
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
idrequired | path | string | Invoice id (inv_…) |
Idempotency-Keyrequired | header | string | Unique per pick; a retry returns the same answer |
Request body
application/json
| Field | Type | Description |
|---|---|---|
assetrequired | string | One of the invoice's
|
Responses
| Status | Description | Body |
|---|---|---|
| 200 | CheckoutInvoice application/json | |
| 400 | Not one of the invoice's options | ErrorResponse application/json |
| 404 | ErrorResponse application/json | |
| 409 | The invoice is closed, or no deposit address is free right now | ErrorResponse application/json |
| 429 | Too many requests; retry after | ErrorResponse application/json |
POST /v1/checkout/invoices/{id}/wallet_binding
Pay from a connected wallet.
Binds the invoice to the payer's wallet address for one payment option and returns the exact transfer to build: the token, the merchant's registered destination and the amount (the amount due plus a sub-cent suffix when the same wallet has another open payment of the same amount). A transfer is attributed when its sender, exact amount and time all match; a transaction hash is never an input. Binding the same wallet again returns the same binding. A different wallet (the payer switched) gets its own binding, and the earlier one stays valid; at most 5 wallets per invoice and network. Only while the invoice is awaiting payment. Rate-limited per key and client address.
Authentication: Publishable key or Secret key
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
idrequired | path | string | Invoice id (inv_…) |
Idempotency-Keyrequired | header | string | Unique per submission |
Request body
application/json
| Field | Type | Description |
|---|---|---|
assetrequired | string | The payment option to pay: its asset code,
|
senderrequired | string | The connected wallet's address on that network, in its display form (
|
Responses
| Status | Description | Body |
|---|---|---|
| 200 | WalletBinding application/json | |
| 400 | Not an address on that network, or not one of the invoice's payment options | ErrorResponse application/json |
| 404 | ErrorResponse application/json | |
| 409 | The invoice is not awaiting payment, too many wallets, no unique amount left, or wallet payments are unavailable on this server | ErrorResponse application/json |
| 429 | Too many requests; retry after | ErrorResponse application/json |
GET /v1/checkout/links/{slug}
A payment link, as the payer sees it.
The landing screen: the merchant, the description, and either the fixed price or the bounds of the
amount the payer may choose. status says whether the link still takes payments.
Authentication: Publishable key or Publishable key as a query parameter (for EventSource) or Secret key
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
slugrequired | path | string | The link's slug (22 characters) |
key | query | string | Publishable key, when it cannot go in the Authorization header |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | CheckoutPaymentLink application/json | |
| 404 | ErrorResponse application/json |
POST /v1/checkout/links/{slug}/invoices
Create this payer's invoice from a payment link.
Fixed-price links take no body fields; payer-chosen links need amount (within the link's bounds).
Returns the payer's view of the new invoice; continue with the normal checkout for its id. The
invoice reserves one unit of the link's quantity_limit and holds no deposit address yet: its options
are in pending_options until the payer picks one (POST /v1/checkout/invoices/{id}/payment_option)
before select_by. 409 when the link is deactivated, expired or sold out
(payment_link_inactive, _expired, _sold_out), when every remaining unit is reserved by unpaid
invoices (payment_link_fully_reserved), or when too many unpaid link invoices are open
(payment_link_busy). Rate-limited per key and client address.
Authentication: Publishable key or Secret key
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
slugrequired | path | string | The link's slug (22 characters) |
Idempotency-Keyrequired | header | string | Unique per payer attempt; a retry returns the same invoice |
Request body
application/json
| Field | Type | Description |
|---|---|---|
amount | string or null | The amount the payer chose, in the link's currency, as a decimal string. Required for
|
Responses
| Status | Description | Body |
|---|---|---|
| 201 | Created | CheckoutInvoice application/json |
| 400 | Missing or out-of-bounds amount | ErrorResponse application/json |
| 404 | ErrorResponse application/json | |
| 409 | The link is inactive, expired, sold out, fully reserved, or busy | ErrorResponse application/json |
| 429 | Too many requests; retry after | ErrorResponse application/json |
GET /v1/invoices/{id}/events
Live invoice status as Server-Sent Events.
Each event: id: is the per-invoice sequence number, event: is invoice.created or
invoice.{status} (invoice.detected, invoice.confirming, invoice.paid, …), and data: is a
complete [InvoiceEvent] JSON object. On connect, every past event is sent first. Resume after a
disconnect with the Last-Event-ID header (browsers do this automatically) or ?last_event_id=.
Authentication: Publishable key or Publishable key as a query parameter (for EventSource) or Secret key
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
idrequired | path | string | Invoice id (inv_…) |
Last-Event-ID | header | string or null | Resume after this sequence number |
last_event_id | query | integer (int64) | Same as the header, for the first connection
|
key | query | string | Publishable key (EventSource cannot set headers) |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | An event stream | InvoiceEvent text/event-stream |
| 404 | ErrorResponse application/json |