# Checkout statuses

Source: https://caravelpay.app/docs/statuses · Caravel Pay docs · Last updated 2026-11-10

Six statuses cover the whole life of a checkout. Only one of them, `paid`, means you should ship.

## Lifecycle

```
  awaiting_payment ---- buyer pays ----> confirming ---- enough paid ----> paid
         |                                   |
      60 minutes                         too little
         v                                   v
      expired                            underpaid

  Anything unusual, like a payment sent after expiry or an unexpected token  ---->  review
```

*Every checkout starts in `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` | At least 85% of `amount` arrived and confirmed. Your payout has been sent; `payout.tx_hash` shows the transfer. | Fulfil the order. Webhook: `checkout.paid`. |
| `underpaid` | Too little arrived: less than 85% of `amount`. `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](https://caravelpay.app/docs/statuses#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. A card payment is expected to arrive a little short, because most card providers keep their fee out of it. So a payment counts as `paid` when at least 85% of the order amount arrives, and as `underpaid` below that. 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](mailto: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`.
