Error Reference
All API errors return a JSON body with an error field (string code) and optionally a details field with field-level validation messages.
Error response format
{
"error": "bad_request",
"details": {
"amount": ["can't be blank"],
"currency": ["is invalid"]
}
}
HTTP status codes
| Code | Meaning | Common cause |
|---|---|---|
400 | Bad Request | Malformed JSON or missing required fields |
401 | Unauthorized | Missing or invalid x-api-key / Bearer token |
403 | Forbidden | Valid credentials but no permission for this resource |
404 | Not Found | Transaction or resource with given ID does not exist |
409 | Conflict | Duplicate txid — a transaction with this ID already exists |
422 | Unprocessable Entity | Validation failed — check details |
429 | Too Many Requests | Rate limit exceeded |
500 | Internal Server Error | Platform error — contact support with transaction ID |
Transaction error codes
These appear in error_description within webhook payloads and transaction status responses:
| Code | Meaning | Recommended action |
|---|---|---|
insufficient_funds | Card declined: insufficient funds | Ask payer to use another card |
card_declined | Card declined by issuer | Ask payer to contact their bank |
expired_card | Card expiry date has passed | Ask payer to update card details |
invalid_card_number | Card number is invalid | Check card number format |
invalid_cvv | CVV is incorrect | Ask payer to re-enter CVV |
do_not_honour | Generic bank decline | Ask payer to contact their bank |
lost_card | Card reported lost | Do not retry |
stolen_card | Card reported stolen | Do not retry |
restricted_card | Card cannot be used for this transaction | Ask payer to use another card |
transaction_limit_exceeded | Amount exceeds card/account limits | Ask payer to use another payment method |
3ds_failed | 3D Secure authentication failed | Ask payer to retry or use another card |
3ds_timeout | 3D Secure timed out | Retry the transaction |
provider_unavailable | Payment provider is temporarily unavailable | Retry after a delay |
routing_failed | No provider found for this transaction | Contact your platform operator |
duplicate_txid | txid already exists for this terminal | Use a unique txid per transaction |
currency_not_supported | Currency not supported by this terminal | Check terminal configuration |
amount_too_low | Amount below minimum for this provider | Increase transaction amount |
amount_too_high | Amount above maximum for this provider | Split into smaller transactions |
antifraud_reject | Blocked by anti-fraud rules | Contact your platform operator |
Validation errors (422)
Validation errors include a details map with field-level messages:
{
"error": "unprocessable_entity",
"details": {
"params.amount": ["can't be blank", "must be greater than 0"],
"params.currency": ["is invalid — use ISO 4217 code"],
"params.txid": ["has already been taken"]
}
}
Handling errors in your code
Retry strategy
| Error type | Retry? | Notes |
|---|---|---|
provider_unavailable | ✅ Yes | Wait 30–60 seconds, max 3 retries |
3ds_timeout | ✅ Yes | Retry once immediately |
insufficient_funds | ❌ No | Show alternative payment method |
card_declined | ❌ No | Show alternative payment method |
lost_card, stolen_card | ❌ Never | Do not retry or re-present |
duplicate_txid | ❌ No | Generate a new unique txid |
routing_failed | ❌ No | Contact your platform operator |
Example error handling (Python)
import requests
response = requests.post(
'https://4pay.online/api/v1/transactions',
headers={'x-api-key': 'YOUR_API_KEY', 'Content-Type': 'application/json'},
json={'params': {'type': 'payment', 'amount': 1000, 'currency': 'USD', 'txid': 'order-1'}}
)
if response.status_code == 422:
errors = response.json().get('details', {})
for field, messages in errors.items():
print(f"{field}: {', '.join(messages)}")
elif response.status_code == 409:
print("Duplicate txid — use a unique order ID")
elif response.status_code >= 500:
print("Platform error — retry later or contact support")
else:
tx = response.json()
print(f"Transaction created: {tx['id']}")
Contact support
For persistent errors or unexpected 500 responses, contact:
- Email: support@4pay.online
- Include the transaction
id(UUID) for faster diagnosis