Core concepts
Errors
The error envelope and what each status means.
When a request fails, ShiftxPay returns a non-2xx HTTP status and a JSON body in a
single, consistent envelope. Branch on the HTTP status for the broad category and
on the code for the specific reason.
The error envelope
Every error has exactly this shape:
{
"error": {
"code": "validation_error",
"message": "amount must be greater than zero"
}
}code— a stable, machine-readable string. Switch on this.message— a human-readable explanation for logs and debugging. Do not parse it; it may change.
Statuses and codes
| HTTP | code | Meaning |
|---|---|---|
| 400 | invalid_body | Malformed JSON, or an unknown field in the body. |
| 400 | validation_error | A field is present but invalid (range, type, format). |
| 401 | unauthorized | Missing or invalid API key. |
| 403 | forbidden | The key lacks the required scope. |
| 403 | payment_blocked | The payment is not permitted (e.g. risk or status rules). |
| 403 | feature_disabled | The requested feature is not enabled for this merchant. |
| 404 | not_found | No such object, or not visible to this caller. |
| 409 | no_connector | No PSP connector is configured for this merchant/currency. |
| 409 | not_refundable | The payment is not in a refundable state. |
| 409 | already_refunded | The payment has already been fully refunded. |
| 409 | idempotency_conflict | A request with the same idempotency key is in flight. |
| 422 | idempotency_key_reuse | The idempotency key was reused with a different body. |
| 422 | amount_too_large | The amount exceeds the allowed maximum. |
| 422 | raw_card_rejected | The body carried card-shaped fields (PAN/CVC) and was blocked. |
| 429 | rate_limited | Too many requests; back off and retry. |
| 502 | connector_error | The upstream PSP returned an error. |
| 500 | internal | An unexpected server-side error. |
Unknown fields are rejected
ShiftxPay validates request bodies strictly. Sending a JSON field the endpoint
does not recognize returns 400 invalid_body — it is not silently ignored. This
catches typos (ammount) and stale integrations early, but it means you must send
only documented fields.
Notes on specific codes
422 raw_card_rejectedcomes from theRawCardGuardmiddleware. The gateway never accepts raw card data; the card belongs in the PSP surface only. See How card data stays off your servers.409 idempotency_conflictand422 idempotency_key_reuseare covered in detail under Idempotency.502 connector_erroris an upstream PSP failure, not a problem with your request. It is generally safe to retry with the same idempotency key.