A refusal is always one envelope:
{ "error": { "type": "policy_rejection", "code": "method_suspended", "message": "This payment method is suspended for your account.", "param": null, "request_id": "req_4f1c0b2e9a7d" }}type is one of ten categories, each always sent on the same HTTP status, so you can branch on either. code is a stable name for the particular refusal. message is for the developer reading a log and may be reworded, so never branch on it. param names the field at fault, when there is one.
type | Status | Meaning |
|---|---|---|
validation_failure | 400 | A parameter is missing or not valid. param names it. |
authentication_failure | 401 | No Access Token, or one that is not valid or has expired. Get a new one at POST /oauth/token (see Authentication). |
authorization_failure | 403 | The key may not act on what the request names. |
not_found | 404 | No such object for this key, or no such route. Another merchant's objects read as none. |
conflict | 409 | The object is not in a state that allows this. |
timeout_or_in_progress | 409 | A duplicate of a request still running, or one whose outcome is not known yet, or a refund while another of the same payment is still being processed (refund_in_progress). Retry later. |
policy_rejection | 422 | Your account may not do this now, for the reason in code. |
invariant_violation | 422 | The request would break a rule that always holds, such as refunding more than was paid. |
rate_limited | 429 | Too many requests. Wait for Retry-After seconds. |
dependency_failure | 503 | Something on our side, or behind it, failed. On a read, nothing was changed; retry. On a write, whether it took effect is not known: retry with the same Idempotency-Key. See When a write answers 503. |
When a write answers 503
Section titled “When a write answers 503”A 503 is the one refusal that may follow work that was done: it is also what you get when something failed after a write had taken effect. So it does not say a write changed nothing.
- A read (
GET): nothing was changed. Retry after a short wait. - A write: whether it took effect is not known. Retry the same request with the same
Idempotency-Key, and never make a new key for the retry: if the first call took effect, you are answered with its result and nothing is done twice. The payment intent calls, simulating an outcome and refunds all take that header; the webhook endpoint calls take none, and Idempotency says what a retry of each does. A terminal that records cash retries with its ownidempotency_key; see Accepting cash.
Every response, an error or not, carries an X-Request-ID header, and an error carries it as request_id too. Quote it when you contact support.
Codes the API itself sends
Section titled “Codes the API itself sends”Beside the codes of each operation (they are listed with it in the reference):
code | type | When |
|---|---|---|
access_token_required | authentication_failure | No Access Token was sent. |
invalid_access_token | authentication_failure | The token is not valid or has expired. Get a new one. |
merchant_mismatch | authorization_failure | The key acts only for its own merchant. |
test_mode_only | authorization_failure | A test helper was called with a live key. See Testing your integration. |
resource_missing | not_found | No such object for this key. |
route_missing | not_found | No such route in this API version. |
invalid_parameter | validation_failure | A parameter is missing or not valid; param names it. |
invalid_json | validation_failure | The request body is not valid JSON. |
unsupported_media_type | validation_failure | Send the body as JSON. |
not_acceptable | validation_failure | This API answers in JSON only. |
method_not_allowed | validation_failure | The resource does not take that method; Allow lists the ones it does. |
rate_limited | rate_limited | Too many requests. |
service_unavailable | dependency_failure | Something went wrong on our side. On a read, nothing was changed; retry. On a write, whether it took effect is not known; see When a write answers 503. |