Payment Statuses
┌──────────────┐
create ──▶ │ pending │ ──── TTL elapsed ────▶ expired ──┐
└──────┬───────┘ │ (late successful
callback / │ verify │ verification)
▼ ▼
┌──────────────┐ gateway confirms ┌────────┐
│ processing │ ─────────────────────────▶ │ paid │
└──────┬───────┘ └────────┘
│ gateway says not paid / payer cancelled
▼
failed · cancelled
| Status | Terminal | Meaning | Webhook |
|---|---|---|---|
pending |
no | Created; payer has not completed payment (or has, but Cartino Pay has not verified yet). payment_url is valid until expires_at. |
— |
processing |
no | Verification with the gateway is in progress. Usually lasts a second or two. | — |
paid |
yes | Verified server-to-server with the gateway. Only this status means money was received. | payment.paid |
failed |
yes | Gateway reported the payment as not paid, refused, or amount mismatch. failure_code/failure_reason explain why. |
payment.failed |
cancelled |
yes | Payer cancelled on the gateway/bank page. | payment.cancelled |
expired |
yes | No completion before expires_at (default 30 min). Can still become paid if a later verification proves payment. |
payment.expired (then possibly payment.paid) |
Rules
- Statuses only move forward as drawn.
paidis final and never reverts. - A payment gets exactly one terminal webhook, except
expired → paid, which sends bothpayment.expiredand laterpayment.paid. Handle both idempotently. - Treat anything other than
paidas "not paid" for fulfilment. processingis transient; if you observe it, poll again in a few seconds or wait for the webhook.