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.
| Status | Name | Description |
|---|---|---|
200 | OK | Request succeeded |
400 | Bad Request | Validation error in request parameters |
401 | Unauthorized | Invalid or missing API key |
403 | Forbidden | Access denied to this resource |
404 | Not Found | Resource not found |
409 | Conflict | Idempotency conflict (request still processing) |
410 | Gone | Session expired or no longer available |
422 | Unprocessable | Idempotency key used with different request body |
429 | Too Many Requests | Rate limit exceeded |
500 | Internal Server Error | Server error - contact support if persistent |
Error Response Format
All error responses follow the RFC 7807 Problem Details standard:
{
"type": "about:blank",
"title": "Validation Error",
"status": 400,
"detail": "amount must be greater than 0",
"instance": "/api/v1/checkout"
}| Field | Type | Description |
|---|---|---|
type | string | URI reference identifying the problem type |
title | string | Short, human-readable summary of the problem |
status | integer | HTTP status code |
detail | string | Human-readable explanation specific to this occurrence |
instance | string | URI reference to the specific occurrence |
Error Categories
Authentication Errors
401UNAUTHORIZEDMissing or invalid API key
403FORBIDDENAPI key lacks permission for this resource
404MERCHANT_NOT_FOUNDMerchant ID not found in the system
403MERCHANT_INACTIVEMerchant account is inactive or suspended
Validation Errors
400VALIDATION_ERRORInvalid request parameters
400INVALID_AMOUNTAmount must be a positive number
400INVALID_CURRENCYCurrency code is not supported
400INVALID_COUNTRYCountry code is not supported
400MISSING_REQUIRED_FIELDA required field is missing from the request
400INVALID_DOCUMENTDocument number format is invalid (CPF/CNPJ)
400INVALID_PIX_KEYPIX key format is invalid
Session Errors
404SESSION_NOT_FOUNDCheckout session ID does not exist
410SESSION_EXPIREDCheckout session has expired (default: 30 minutes)
400SESSION_ALREADY_COMPLETEDSession has already been paid or completed
400SESSION_CANCELLEDSession was cancelled by the user
Payment Errors
400PAYMENT_FAILEDGeneric payment failure
400CARD_DECLINEDCard was declined by the issuing bank
400INSUFFICIENT_FUNDSCustomer has insufficient funds
400CARD_EXPIREDCard has expired
400INVALID_CVVSecurity code (CVV) is invalid
502PROVIDER_ERRORPayment provider returned an error
504TIMEOUTRequest timed out waiting for provider
Payout Errors
400PAYOUT_FAILEDPayout operation failed
400INVALID_BENEFICIARYBeneficiary data is invalid or incomplete
400INSUFFICIENT_BALANCEMerchant balance is insufficient for payout
404BENEFICIARY_NOT_FOUNDBeneficiary account could not be found
Routing Errors
404METHOD_NOT_FOUNDPayment method code does not exist
503PROVIDER_UNAVAILABLEPayment provider is currently unavailable
400COUNTRY_NOT_SUPPORTEDCountry 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
1 async 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
1 import requests 2 import time 3 4 class 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 11 def 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
Use the error code (not message) for programmatic handling
Log full error details server-side for troubleshooting
Show generic messages to users, not technical details
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)
{
"type": "about:blank",
"title": "Validation Error",
"status": 400,
"detail": "amount must be greater than 0",
"instance": "/api/v1/checkout"
}Authentication Error (401)
{
"type": "about:blank",
"title": "Unauthorized",
"status": 401,
"detail": "Invalid or missing API key",
"instance": "/api/v1/checkout"
}Session Expired (410)
{
"type": "about:blank",
"title": "Gone",
"status": 410,
"detail": "Checkout session cs_abc123 has expired",
"instance": "/api/v1/checkout/cs_abc123"
}Rate Limited (429)
{
"type": "about:blank",
"title": "Too Many Requests",
"status": 429,
"detail": "Rate limit exceeded. Please retry after 60 seconds.",
"instance": "/api/v1/checkout"
}