Errors
Understanding and handling errors from the Paychtec API.
Error Response Format
When an error occurs, the API returns a JSON response with an error object containing the error type, code, and a human-readable message.
{
"error": {
"type": "invalid_request",
"code": "IR_04",
"message": "Invalid value for field: amount"
}
}HTTP Status Codes
| Status | Description |
|---|---|
200 | Request succeeded |
201 | Resource created successfully |
400 | Bad request — invalid parameters or missing required fields |
401 | Unauthorized — invalid or missing API key |
403 | Forbidden — insufficient permissions |
404 | Not found — resource doesn't exist |
409 | Conflict — resource already exists or action conflicts |
422 | Unprocessable entity — request understood but cannot be processed |
429 | Too many requests — rate limit exceeded |
500 | Internal server error — something went wrong on our end |
502 | Bad gateway — upstream service error |
503 | Service unavailable — temporary outage |
Error Types
authentication_error
Issues with API authentication. Check that your API key is correct and has the required permissions.
invalid_request
The request was malformed or contained invalid parameters. Check the request body and parameters.
processing_error
An error occurred while processing the payment. This may include card declines or issues with the payment method.
rate_limit_error
Too many requests were made in a short period. Wait and retry with exponential backoff.
api_error
An unexpected error occurred on our servers. These are rare and usually temporary. Retry with exponential backoff.
Common Error Codes
| Code | Type | Description |
|---|---|---|
AU_01 | authentication_error | Invalid API key provided |
AU_02 | authentication_error | API key has been revoked |
IR_01 | invalid_request | Missing required field |
IR_04 | invalid_request | Invalid field value |
IR_05 | invalid_request | Resource not found |
PE_01 | processing_error | Card declined |
PE_02 | processing_error | Insufficient funds |
PE_03 | processing_error | Expired card |
CE_01 | connector_error | Processor unavailable |
RL_01 | rate_limit_error | Rate limit exceeded |
Handling Errors
Here's an example of how to handle errors in your code:
try {const response = await fetch('https://api.v2.paychtec.com/payments', { method: 'POST', headers: { 'Content-Type': 'application/json', 'api-key': 'snd_YOUR_API_KEY' }, body: JSON.stringify({ amount: 1000, currency: 'USD', profile_id: 'YOUR_PROFILE_ID' })});const data = await response.json();if (!response.ok) { const { error } = data; switch (error.type) { case 'authentication_error': console.error('Authentication failed:', error.message); break; case 'invalid_request': console.error('Invalid request:', error.message); break; case 'processing_error': console.error('Payment failed:', error.message); break; case 'rate_limit_error': console.error('Rate limited, retrying...'); break; default: console.error('An error occurred:', error.message); } return;}console.log('Payment succeeded:', data.payment_id);} catch (networkError) {console.error('Network error:', networkError);}Retry Strategy
For transient errors (5xx status codes and rate limits), implement exponential backoff with jitter:
async function retryWithBackoff(fn, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (i === maxRetries - 1) throw error;
// Only retry on 5xx errors and rate limits
if (error.status < 500 && error.status !== 429) throw error;
// Exponential backoff with jitter
const delay = Math.min(1000 * Math.pow(2, i) + Math.random() * 1000, 30000);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}Idempotency Keys: Always use idempotency keys when retrying POST requests to prevent duplicate operations.