Transaction lifecycle
The states a sale moves through, and the outcomes that are not simply delivered or failed.
Every sale is a transaction, named by its reference. Read status in the body, never only the HTTP code: a failed sale answers 200.
| Status | Meaning | Final |
|---|---|---|
created | Recorded, before its hold is placed. | No |
queued | Accepted and held, waiting to be sent. What ?wait=0 answers. | No |
processing | Being sent. | No |
pending | Sent, and the channel has not confirmed either way. Status queries follow. | No |
successful | Delivered, in full or in part. The hold is settled. | Unless refunded |
failed | Not delivered. The hold is released. | Yes |
refunded | Staff refunded a delivered sale. The charge is back in the wallet. | Yes |
reversed | Reserved. Nothing sets it today. | Yes |
How a call answers
A vend waits for the final state, up to 55 seconds, and answers 200 with successful or failed. If it is not final by then, it answers 202, and the state follows by webhook and on GET /api/v1/transactions/{reference}. ?wait=0 answers 202 at once, and ?wait=10 waits up to ten seconds.
Set your client's timeout above 60 seconds. If you time out first, the sale is still running: resend with the same Idempotency-Key and you get 409 IDEMPOTENCY_IN_PROGRESS until it finishes, then its answer. See idempotency.
Partial delivery
A sale sent from several lines, or an airtime sale sent as several transfers, can deliver part of the order and be unable to deliver the rest. What arrived stays with the customer, and the sale ends successful with its charges paid in full. metadata says what happened:
| Key | On | Meaning |
|---|---|---|
partial | Both | "true" when it fell short |
delivered_mb, requested_mb | Data | Megabytes sent and ordered |
delivered_amount, requested_amount | Airtime | Amounts sent and ordered |
So do not read successful alone as the whole order delivered. Check metadata.partial on the webhook and tell your customer, or make up the difference.
A sale still pending
A pending sale keeps its hold. Status queries run with growing waits for about 30 minutes. After that:
- A sale from a vendor or the mock goes to manual review with
failure_codePENDING_TIMEOUT, and Routegate staff settle it. - A sale from your own line waits for you.
A sale awaiting your confirmation
When a carrier answers with no clear outcome and the line's balances cannot confirm it either, the sale stays pending with metadata.awaiting_confirmation, and no webhook is sent for this step. You know from your customer whether it arrived, so confirm it in the dashboard on the transaction's page: the sale then settles as successful with its charges paid. It cannot be marked failed there. If it did not arrive, Routegate staff settle it, so contact support.
Refunds
Staff can refund a delivered sale. The charge goes back to the wallet, the status moves from successful to refunded, and transaction.refunded is sent.