Reference

Error Codes

Understand and handle API errors effectively with our comprehensive error reference.

HTTP Status Codes

The API uses standard HTTP status codes to indicate the success or failure of requests.

StatusNameDescription
200OKRequest succeeded
400Bad RequestValidation error in request parameters
401UnauthorizedInvalid or missing API key
403ForbiddenAccess denied to this resource
404Not FoundResource not found
409ConflictIdempotency conflict (request still processing)
410GoneSession expired or no longer available
422UnprocessableIdempotency key used with different request body
429Too Many RequestsRate limit exceeded
500Internal Server ErrorServer error - contact support if persistent

Error Response Format

All error responses follow the RFC 7807 Problem Details standard:

error-response.json
{
  "type": "about:blank",
  "title": "Validation Error",
  "status": 400,
  "detail": "amount must be greater than 0",
  "instance": "/api/v1/checkout"
}
FieldTypeDescription
typestringURI reference identifying the problem type
titlestringShort, human-readable summary of the problem
statusintegerHTTP status code
detailstringHuman-readable explanation specific to this occurrence
instancestringURI reference to the specific occurrence

Error Categories

Authentication Errors

401
UNAUTHORIZED

Missing or invalid API key

403
FORBIDDEN

API key lacks permission for this resource

404
MERCHANT_NOT_FOUND

Merchant ID not found in the system

403
MERCHANT_INACTIVE

Merchant account is inactive or suspended

Validation Errors

400
VALIDATION_ERROR

Invalid request parameters

400
INVALID_AMOUNT

Amount must be a positive number

400
INVALID_CURRENCY

Currency code is not supported

400
INVALID_COUNTRY

Country code is not supported

400
MISSING_REQUIRED_FIELD

A required field is missing from the request

400
INVALID_DOCUMENT

Document number format is invalid (CPF/CNPJ)

400
INVALID_PIX_KEY

PIX key format is invalid

Session Errors

404
SESSION_NOT_FOUND

Checkout session ID does not exist

410
SESSION_EXPIRED

Checkout session has expired (default: 30 minutes)

400
SESSION_ALREADY_COMPLETED

Session has already been paid or completed

400
SESSION_CANCELLED

Session was cancelled by the user

Payment Errors

400
PAYMENT_FAILED

Generic payment failure

400
CARD_DECLINED

Card was declined by the issuing bank

400
INSUFFICIENT_FUNDS

Customer has insufficient funds

400
CARD_EXPIRED

Card has expired

400
INVALID_CVV

Security code (CVV) is invalid

502
PROVIDER_ERROR

Payment provider returned an error

504
TIMEOUT

Request timed out waiting for provider

Payout Errors

400
PAYOUT_FAILED

Payout operation failed

400
INVALID_BENEFICIARY

Beneficiary data is invalid or incomplete

400
INSUFFICIENT_BALANCE

Merchant balance is insufficient for payout

404
BENEFICIARY_NOT_FOUND

Beneficiary account could not be found

Routing Errors

404
METHOD_NOT_FOUND

Payment method code does not exist

503
PROVIDER_UNAVAILABLE

Payment provider is currently unavailable

400
COUNTRY_NOT_SUPPORTED

Country is not available for this payment method

Handling Errors

Here are examples of how to properly handle API errors in your application:

Node.js Example

handle-errors.js
1async function createCheckout(data) {
2 try {
3 const response = await fetch('https://cashier.flowpayment.net/api/v1/checkout', {
4 method: 'POST',
5 headers: {
6 'X-API-Key': process.env.CASHIER_API_KEY,
7 'Content-Type': 'application/json',
8 },
9 body: JSON.stringify(data),
10 });
11
12 if (!response.ok) {
13 const error = await response.json();
14
15 switch (error.status) {
16 case 400:
17 // Validation error - show user-friendly message
18 console.error('Validation error:', error.detail);
19 throw new Error('Please check your input and try again');
20 case 401:
21 // Auth error - check API key
22 console.error('Authentication failed');
23 throw new Error('Service temporarily unavailable');
24 case 429:
25 // Rate limited - implement backoff
26 const retryAfter = response.headers.get('Retry-After') || 60;
27 console.log(`Rate limited. Retry after ${retryAfter}s`);
28 throw new Error('Too many requests. Please wait.');
29 default:
30 console.error('API error:', error);
31 throw new Error('An error occurred. Please try again.');
32 }
33 }
34
35 return await response.json();
36 } catch (err) {
37 // Network or parsing errors
38 console.error('Request failed:', err);
39 throw err;
40 }
41}

Python Example

handle_errors.py
1import requests
2import time
3
4class CashierError(Exception):
5 def __init__(self, status, code, detail):
6 self.status = status
7 self.code = code
8 self.detail = detail
9 super().__init__(f"{code}: {detail}")
10
11def create_checkout(data: dict, max_retries: int = 3):
12 """Create a checkout session with retry logic."""
13
14 for attempt in range(max_retries):
15 try:
16 response = requests.post(
17 'https://cashier.flowpayment.net/api/v1/checkout',
18 headers={
19 'X-API-Key': os.environ['CASHIER_API_KEY'],
20 'Content-Type': 'application/json',
21 },
22 json=data,
23 timeout=30
24 )
25
26 if response.ok:
27 return response.json()
28
29 error = response.json()
30 status = error.get('status', response.status_code)
31
32 # Handle specific errors
33 if status == 429:
34 # Rate limited - exponential backoff
35 retry_after = int(response.headers.get('Retry-After', 60))
36 time.sleep(retry_after)
37 continue
38
39 if status >= 500:
40 # Server error - retry with backoff
41 time.sleep(2 ** attempt)
42 continue
43
44 # Client error - don't retry
45 raise CashierError(
46 status=status,
47 code=error.get('title', 'Unknown Error'),
48 detail=error.get('detail', 'An error occurred')
49 )
50
51 except requests.exceptions.Timeout:
52 if attempt < max_retries - 1:
53 time.sleep(2 ** attempt)
54 continue
55 raise CashierError(504, 'TIMEOUT', 'Request timed out')
56
57 except requests.exceptions.RequestException as e:
58 raise CashierError(0, 'NETWORK_ERROR', str(e))
59
60 raise CashierError(500, 'MAX_RETRIES', 'Max retries exceeded')

Important

Never expose detailed error messages to end users. Log them for debugging, but show generic user-friendly messages instead.

Best Practices

Check Error Codes First

Use the error code (not message) for programmatic handling

Log for Debugging

Log full error details server-side for troubleshooting

User-Friendly Messages

Show generic messages to users, not technical details

Implement Retry Logic

Retry transient errors (429, 5xx) with exponential backoff

Retry Strategy

For 429 (Rate Limited) errors, always check the Retry-After header. For 5xx errors, use exponential backoff: wait 1s, 2s, 4s, 8s between retries.

Error Response Examples

Validation Error (400)

validation-error.json
{
  "type": "about:blank",
  "title": "Validation Error",
  "status": 400,
  "detail": "amount must be greater than 0",
  "instance": "/api/v1/checkout"
}

Authentication Error (401)

auth-error.json
{
  "type": "about:blank",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Invalid or missing API key",
  "instance": "/api/v1/checkout"
}

Session Expired (410)

session-expired.json
{
  "type": "about:blank",
  "title": "Gone",
  "status": 410,
  "detail": "Checkout session cs_abc123 has expired",
  "instance": "/api/v1/checkout/cs_abc123"
}

Rate Limited (429)

rate-limited.json
{
  "type": "about:blank",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Rate limit exceeded. Please retry after 60 seconds.",
  "instance": "/api/v1/checkout"
}