Status codes & responses
Purchase endpoints return different HTTP codes for success, pending, async accept, and terminal failure. Always read data.status as well as the HTTP status.
HTTP outcomes
| Code | Meaning | What to do |
|---|---|---|
| 200 | Success (including instant successful purchase) | Mark your order complete. |
| 201 | Processing / pending purchase accepted | Keep polling — do not retry with a new key. |
| 202 | Async purchase accepted (mobile data) | Fulfillment continues in background — poll. |
| 400 | Terminal purchase failure / refunded | Show the message; wallet credited when applicable. |
| 401 | Missing or invalid X-API-Key | Fix the key and retry. |
| 403 | Key not permitted for biller/product | Request the product on API Access. |
| 404 | Resource not found | Check transaction id / reference. |
| 409 | Duplicate idempotency key | Requery the existing transaction — no second debit. |
| 422 | Validation / business-rule failure | Fix the payload and retry with a new key if needed. |
| 429 | Too many requests / risk block | Back off and retry later. |
| 503 | Service unavailable / upstream issue | Retry later; keep the same key if the request may have reached us. |
Transaction status values
| Status | Meaning |
|---|---|
| processing | Accepted; provider still working |
| pending | Awaiting provider confirmation |
| success | Delivered — terminal |
| failed | Not delivered — terminal |
| refunded | Failed and wallet credited — terminal |
Never treat pending as failure
Do not create a new purchase with a newidempotency_key while the first is still processing or pending. Poll or requery instead.