Errors
Tell a failed request from a failed payment, and what to do about each.
Check the HTTP status of every response: 2xx means it worked, 4xx means you have to change the request, and 5xx
means retry.
The error body
A 4xx comes with a JSON body:
{
"status": "NOT_FOUND",
"message": "Payment not found",
"requestId": "req_4f1c2a9e8b7d4c3a9f0e1d2c3b4a5f6e"
}Log message or show it to your team, but branch on the HTTP status code, since messages can be reworded. status
names the HTTP status, and requestId is the call's request ID.
A 401, a 429, and a 403 for a missing scope have no body. The token endpoints answer
with OAuth's error body instead, where error is a code such as invalid_client.
Request IDs
Log the Request-Id header of every response, such as req_4f1c2a9e8b7d4c3a9f0e1d2c3b4a5f6e. Errors without a body
have it too. Quote it when you contact support, so the call can be found.
Status codes
| Code | Meaning | What to do |
|---|---|---|
200, 201, 202, 204 | It worked. 202 means the outcome comes later. | |
400 | The request is invalid: a missing or malformed field, or a value the API does not accept. | Fix the request. Do not retry it unchanged. |
401 | The access token is missing, expired or revoked. | Get a new token and retry. |
403 | The token lacks the scope the call needs, or the call is not available to you. | Check the key's scopes. |
404 | You have no resource with this ID. | Check the ID. |
409 | The request conflicts with the resource's state, or an Idempotency-Key was reused with a different body. | Read the resource, then decide. |
422 | The request is valid but cannot be done, such as a provider that cannot pay out. | Change what you ask for. |
429 | Too many requests. | Wait the seconds in Retry-After, then retry. |
500, 502 | The request did not complete. | Retry with the same Idempotency-Key. |
Payment failures are not errors
A payment the customer declines is not an HTTP error: creating it worked, so you get 201. You learn the outcome later
from a payment.failed webhook, or from the payment's status and failureCode.
failureCode | Why the payment failed |
|---|---|
CUSTOMER_DECLINED | The customer declined on their phone. |
INSUFFICIENT_FUNDS | The customer's wallet did not have enough money. |
INSUFFICIENT_BALANCE | A payout your available FlexPay balance could not cover. |
EXPIRED | The payment was never sent, or the customer did not approve, within 4 hours. The status is EXPIRED. |
Providers can report other codes. Treat an unknown failureCode as a failure and show failureMessage to your team,
not to the customer.