Error Handling
AWDPay uses standard HTTP codes combined with internal error codes to help you quickly diagnose and resolve issues.
Error response formatβ
{
"error": {
"code": 40010,
"message": "Invalid amount",
"details": "Amount must be greater than 0"
}
}
| Field | Type | Description |
|---|---|---|
code | Integer | AWDPay error code (see table below) |
message | String | Human-readable message describing the error |
details | String | Additional details (optional) |
Error codes by categoryβ
π Authentication & Authorizationβ
| Code | Name | HTTP | Description | Recommended Action |
|---|---|---|---|---|
401 | InvalidRole | 401 | Invalid or insufficient role | Check your account permissions |
30001 | KEYCLOAK_ERROR | 500 | Authentication server error | Retry, contact support if persistent |
40001 | INVALID_ACCESS | 403 | Unauthorized access to this resource | Check your access rights |
40002 | UNAUTHORIZE_REQUEST | 401 | Unauthorized request | Check your Bearer token |
π Resources not foundβ
| Code | Name | HTTP | Description | Recommended Action |
|---|---|---|---|---|
40004 | RESSOURCE_NOT_FOUND | 404 | Resource not found | Check the resource identifier |
40005 | PHONE_NUMBER_NOT_FOUND | 404 | Phone number not found | Verify the format and existence of the number |
40006 | TRX_NOT_FOUND | 404 | Transaction not found | Check the transaction reference |
40007 | OTP_NOT_FOUND | 404 | OTP not found or expired | Request a new OTP |
40008 | CUSTOMER_NOT_FOUND | 404 | Customer not found | Check customer information |
40017 | WALLET_NOT_FOUND | 404 | Wallet not found | Verify that the account exists |
β οΈ Validation errorsβ
| Code | Name | HTTP | Description | Recommended Action |
|---|---|---|---|---|
40010 | INVALID_AMOUNT | 400 | Invalid amount | Amount must be > 0 |
40011 | INVALID_COUNTRY | 400 | Invalid country code | Use a valid ISO 3166-1 alpha-2 code |
40012 | INVALID_GATEWAY | 400 | Invalid gateway | Check the gateway name |
40014 | INVALID_NUMBER | 400 | Invalid number | Use international format (+XXX...) |
40015 | INVALID_CURRENCY | 400 | Invalid currency | Use an ISO 4217 code (XOF, EUR...) |
40016 | INVALID_JSON_BODY | 400 | Invalid JSON body | Check JSON syntax |
40017 | INVALID_METHOD | 400 | Invalid method | Use a supported HTTP method |
40018 | INVALID_CLIENT | 400 | Invalid client | Check your API credentials |
40019 | INVALID_OTP | 400 | Invalid OTP code | Check the entered code |
40020 | INVALID_OPERATION | 400 | Invalid operation | This operation is not allowed |
40021 | INVALID_CALLBACK_URL | 400 | Invalid callback URL | Use a valid HTTPS URL |
40022 | INVALID_SECRET_CODE | 400 | Invalid secret code | Check your secret code |
40023 | INVALID_REQUEST | 400 | Invalid request | Check request parameters |
π° Balance errorsβ
| Code | Name | HTTP | Description | Recommended Action |
|---|---|---|---|---|
40013 | INSUFFICIENT_BALANCE | 422 | Insufficient balance | Top up your merchant account |
Standard HTTP codesβ
| HTTP Code | Meaning | Description |
|---|---|---|
200 | OK | Request successful |
201 | Created | Resource created successfully |
400 | Bad Request | Invalid parameters |
401 | Unauthorized | Missing or invalid token |
403 | Forbidden | Access denied |
404 | Not Found | Resource not found |
422 | Unprocessable Entity | Business validation failed |
429 | Too Many Requests | Rate limit reached |
500 | Internal Server Error | Server error |
502 | Bad Gateway | External gateway error |
503 | Service Unavailable | Service temporarily unavailable |
Error handling by typeβ
4xx errors (Client)β
These errors are caused by invalid data. Do not retry without correcting the request.
async function handleClientError(response) {
const error = await response.json();
switch (error.code) {
case 40010: // INVALID_AMOUNT
throw new Error('Invalid amount: must be greater than 0');
case 40013: // INSUFFICIENT_BALANCE
throw new Error('Insufficient balance for this operation');
case 40014: // INVALID_NUMBER
throw new Error('Invalid number format');
default:
throw new Error(error.message);
}
}
5xx errors (Server)β
These errors are temporary. Retry with exponential backoff.
async function retryWithBackoff(fn, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
if (error.status >= 500 && attempt < maxRetries - 1) {
const delay = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
}
Idempotence and retryβ
Using the Idempotency-Key headerβ
To avoid duplicates during retries, use an idempotency key:
curl -X POST "https://app.awdpay.com/api/deposits/initiate" \
-H "Authorization: Bearer $AWDPAY_TOKEN" \
-H "Idempotency-Key: order-1234-attempt-1" \
-H "Content-Type: application/json" \
-d '{...}'
Recommended retry strategyβ
| Attempt | Delay | Action |
|---|---|---|
| 1 | Immediate | First attempt |
| 2 | 1 second | If 5xx error or timeout |
| 3 | 2 seconds | If 5xx error or timeout |
| 4 | 4 seconds | If 5xx error or timeout |
| 5+ | Abandon | Alert technical team |
Never retry
4xxerrors (except429Too Many Requests)INSUFFICIENT_BALANCEerrorsINVALID_*errors
Best practicesβ
β Doβ
- Log all errors with code, message and timestamp
- Use idempotency keys for creation operations
- Implement a circuit breaker for recurring errors
- Display clear user messages (not technical codes)
β Don'tβ
- Expose internal codes to end users
- Retry blindly without analyzing the error
- Ignore errors β log them even if non-blocking
Supportβ
If you encounter persistent errors:
- Note the error code, message and timestamp
- Retrieve the transaction reference if available
- Contact support via the AWDPay dashboard
- Provide request/response logs (without sensitive data)
Next stepsβ
- Authentication β Configure your token
- Collections β Accept payments
- Disbursements β Send funds