Errors
HTTP statuses, machine-readable error codes and safe retry behaviour.
Failed requests return an HTTP status and a JSON body with a stable code and
a human-readable message.
HTTP/1.1 400 Bad Request
{
"code": "CURRENCY_NOT_SUPPORTED",
"message": "USD is not enabled for payments. Enabled: AED"
}Codes raised by the API
| Status | Code | Meaning |
|---|---|---|
| 400 | INVALID_REQUEST | A body, query parameter or field combination is invalid. |
| 400 | INVALID_REQUEST_BODY | A webhook URL is malformed, non-HTTPS, private or otherwise unsafe. |
| 400 | INVALID_CURSOR | The pagination cursor is malformed or no longer usable. |
| 400 | INVALID_IDEMPOTENCY_KEY | The key is not 1–255 printable ASCII characters. |
| 400 | PRODUCT_NOT_ACTIVE | A checkout contains a draft or archived product. |
| 400 | INVALID_PRICE | A price is zero, or a three-decimal currency checkout uses its third decimal place. |
| 400 | INVALID_CART | A recurring checkout does not contain exactly one recurring product. |
| 400 | MIXED_CURRENCIES | Products in one checkout use different currencies. |
| 400 | CURRENCY_NOT_SUPPORTED | The currency is not enabled for this account and mode. |
| 401 | UNAUTHORIZED | The API key is missing, wrong or revoked. |
| 403 | MERCHANT_NOT_APPROVED | The account is not approved to use the API. |
| 403 | FORBIDDEN | The authenticated key cannot perform the operation. |
| 404 | NOT_FOUND | The endpoint or object does not exist for this merchant and mode. |
| 405 | METHOD_NOT_ALLOWED | The path exists but not for that HTTP method. |
| 409 | CUSTOMER_EXISTS | A customer with this email already exists in this merchant and mode. |
| 409 | IDEMPOTENCY_KEY_IN_USE | Another request with the same key is still running; retry the same request. |
| 409 | TEST_MODE_UNAVAILABLE | Sandbox payments are not enabled for the account. |
| 409 | SUBSCRIPTION_CANCELLED | A cancelled subscription cannot be changed. |
| 409 | CANCELLATION_FINAL | Renewal was already stopped at the processor and cannot be resumed. |
| 409 | CONFLICT | The request conflicts with the object's current state. |
| 410 | GONE | The resource existed but can no longer be used. |
| 413 | PAYLOAD_TOO_LARGE | The request exceeds the body-size limit. |
| 415 | UNSUPPORTED_MEDIA_TYPE | The request content type is unsupported. |
| 422 | IDEMPOTENCY_KEY_REUSED | The key was previously used with different request parameters. |
| 422 | UNPROCESSABLE_ENTITY | The request is syntactically valid but cannot be processed. |
| 429 | RATE_LIMITED | The rate limit was reached; follow Retry-After. |
| 503 | PAYMENTS_UNAVAILABLE | Live payment configuration is temporarily unavailable. |
| 5xx | INTERNAL_ERROR | An unexpected server error occurred. |
| 409 | LIMIT_REACHED | The account reached a resource limit, such as API keys or webhooks. |
Validation errors produced from a schema use INVALID_REQUEST. The message
names the first invalid field, but integrations should branch on code, not
the English message.
Retrying
Retry network errors, 429, IDEMPOTENCY_KEY_IN_USE and 5xx with backoff.
For a POST, reuse the same Idempotency-Key and identical body. Do not retry
other 4xx responses without changing the request or account state.
The libraries map statuses to typed errors. See Node.js and PHP.