API reference
Checkout statuses
Six statuses cover the whole life of a checkout. Only one of them, paid, means you should ship.
Lifecycle#
awaiting_payment. Each status after confirming sends a webhook.All statuses#
| Status | What it means | What to do |
|---|---|---|
| awaiting_payment | Created; the buyer hasn't paid yet. | Nothing. Keep the order pending. |
| confirming | A payment has been detected and is waiting for confirmation. | Nothing yet. Don't ship. |
| paid | The full amount arrived and confirmed. Your payout has been sent; payout.tx_hash shows the transfer. | Fulfil the order. Webhook: checkout.paid. |
| underpaid | Less than amount arrived. paid_amount shows how much. | Hold the order and contact the buyer. Webhook: checkout.underpaid. |
| expired | No payment within 60 minutes. | Cancel or release stock. Webhook: checkout.expired. Rarely, a payment sent before expiry confirms later and a checkout.paid follows; see Expired. |
| review | Something needs a manual look, for example a payment sent after expiry or in a token we can't credit automatically. | Hold the order. Webhook: checkout.review. |
Fulfil only on paid#
Ship when you receive a verified checkout.paid webhook, or when GET /v1/checkouts/{id} returns "status": "paid". Not when the buyer lands on your return_url, and not on confirming.
Underpaid#
This mostly happens when a buyer pays with crypto directly and sends less than the total. Compare paid_amount with amount, then decide with the buyer: accept it, ask for the difference, or refund. Refunds are sent by you, from your wallet.
Review#
A checkout goes to review when a payment doesn't fit the normal path: it was sent after the checkout expired, or as a token or network we don't credit automatically. Keep the order on hold. If it can be resolved you get a follow-up webhook; if you have questions, email hello@caravelpay.app with the checkout id.
Expired#
Checkouts expire 60 minutes after creation. An expired checkout can't be paid by the buyer anymore. To let the buyer try again, create a new checkout with a new order_id, for example 1042-2.
Rarely, a payment sent before expiry confirms after it. Then the checkout moves from expired to paid and you get checkout.paid; fulfil it as normal, even if you already cancelled the order. A payment sent after expiry goes to review.