Skip to content

Hosted checkout

Everything between choosing how to pay and the receipt, on one hosted page.

Your server and hosted checkout

Recommended
Code needed
One API call and a webhook handler
Time
An afternoon
Customization
Amount, reference, metadata, redirects and expiry on every payment
Best for
Stores and apps with their own orders

Every link, and every payment you create through the API, has a hosted checkout at its url. It handles everything between the customer choosing how to pay and their receipt, on any screen. A payment made through a link has no url of its own: the customer paid on the link's.

What the customer sees

  • The customer picks card or crypto, then a coin and network from the ones you accept.
  • A card goes straight to the card payment page, in a new tab or, on a phone, the same one, and checkout waits on it. See card payments.
  • Each crypto checkout pays to a fresh address in your wallet, at a rate that holds while it's open, so every transfer matches one payment.
  • Checkout spots the transfer and follows it until it has the confirmations it needs.
  • A short transfer gets a request for exactly what's left, and an overpayment lands in your wallet in full. See underpayments.
  • When it's paid, the customer gets a receipt, or goes to your success_url.

What checkout handles, and what you own

Checkout handlesYou own
Coin, network and card choiceWhich coins, networks and rails you accept, in Settings
Fresh addresses and locked ratesThe price, currency and reference of each payment
Detection, confirmations and short transfersFulfilling the order when the webhook arrives
The receiptYour success and cancel pages

Checkout statuses

StatusMeaning
openWaiting for the customer to pay.
awaiting_customerWaiting for the customer to finish paying by card.
processingA card payment is being approved.
confirmingThe transfer arrived and is collecting confirmations.
underpaidPart of the amount arrived. The customer can send the rest.
completedPaid in full.
expiredNothing arrived in time, or the transfer landed on a sibling quote, which replaced_by names.
canceledThe customer or you canceled it. canceled_by says which.
failedThe payment couldn't be completed.
needs_reviewFunds arrived but need your decision, such as after expiry or on another network.

Build your own

The hosted page runs on public endpoints you can call yourself. Create a checkout with the payment's code, the last part of its url, then read it every few seconds until its status is completed. When the customer goes back to choose again, supersede the old checkout and pass its ID as replaces on the new one, so the same choice keeps the same quote and address. If the transfer then lands on the quote the customer left, that quote is the one being paid and the new one closes with replaced_by naming it: read that one instead, and never offer a new quote for a checkout closed that way.

For a card, send the customer to the checkout's card.payment_url as it is. Browsers only let a tab open during the customer's tap, so open a blank one as they press your button, before you create the checkout, then point it at the URL; where it can't open, go there in the same tab. The card payment page returns the customer to the checkout's page on the hosted checkout.