Errors & Troubleshooting
How to handle errors and fix common issues.
Error Response Format
All errors return JSON with an error field:
{
"error": "Human-readable error message"
}
HTTP Status Codes
| Status | Meaning | What to Do |
|---|---|---|
400 | Bad Request | Check your request body for missing or invalid fields |
401 | Unauthorized | Verify your API key is correct |
403 | Forbidden | You don't have access to this resource |
404 | Not Found | Check the resource ID exists |
429 | Rate Limited | Slow down - max 100 requests per 60 seconds |
500 | Server Error | Retry later, contact support if persistent |
Common Errors & Solutions
Invalid API Key (401)
{ "error": "Invalid or missing API key" }
Solutions:
- Check the
Authorizationheader format:Bearer YOUR_API_KEY - Verify the API key in your dashboard
Missing Required Fields (400)
{ "error": "products is required" }
Solutions:
- Check the API reference for required fields
- Ensure JSON is properly formatted
- Verify field names match exactly (case-sensitive)
Invalid Amount (400)
{ "error": "Amount must be greater than 10 XOF" }
Limits:
- Transactions: minimum > 10 XOF
- Payouts: 11 - 1,500,000 XOF
Rate Limit Exceeded (429)
{ "error": "Rate limit exceeded. Try again later." }
Solutions:
- Max 100 requests per 60 seconds (sliding window)
- Implement exponential backoff
- Cache responses when possible
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url, options);
if (response.status === 429) {
const waitTime = Math.pow(2, i) * 1000; // 1s, 2s, 4s
await new Promise(r => setTimeout(r, waitTime));
continue;
}
return response;
}
throw new Error('Max retries exceeded');
}
Resource Not Found (404)
{ "error": "Transaction not found" }
Solutions:
- Verify the
order_idorpayout_idis correct - Resources are scoped to your organization - you can't access others' data
Insufficient Balance (400)
{ "error": "Insufficient balance for payout" }
Solutions:
- Check your balance:
GET /api/v2/accounts - Add funds to your account
- Reduce the payout amount
Invalid Phone Number (400)
{ "error": "Invalid phone number format" }
Solutions:
- Use international format:
+221XXXXXXXXX - Include country code
- Remove spaces and special characters
Handling Errors in Code
JavaScript
async function createPayment(data) {
const response = await fetch('https://api.naboopay.com/api/v2/transactions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
const result = await response.json();
if (!response.ok) {
switch (response.status) {
case 400:
throw new Error(`Invalid request: ${result.error}`);
case 401:
throw new Error('Invalid API key - check your credentials');
case 429:
throw new Error('Rate limited - please retry later');
default:
throw new Error(result.error || 'Unknown error');
}
}
return result;
}
Python
import requests
def create_payment(data):
response = requests.post(
'https://api.naboopay.com/api/v2/transactions',
headers={
'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json'
},
json=data
)
result = response.json()
if not response.ok:
error_msg = result.get('error', 'Unknown error')
if response.status_code == 400:
raise ValueError(f'Invalid request: {error_msg}')
elif response.status_code == 401:
raise PermissionError('Invalid API key')
elif response.status_code == 429:
raise Exception('Rate limited - retry later')
else:
raise Exception(error_msg)
return result
Debugging Tips
1. Log Request and Response
async function apiCall(endpoint, options) {
console.log('Request:', endpoint, options);
const response = await fetch(`https://api.naboopay.com/api/v2${endpoint}`, options);
const data = await response.json();
console.log('Response:', response.status, data);
return { response, data };
}
2. Validate Before Sending
function validateTransaction(data) {
const errors = [];
if (!data.products || data.products.length === 0) {
errors.push('products is required');
}
if (!data.method_of_payment || data.method_of_payment.length === 0) {
errors.push('method_of_payment is required');
}
if (!data.success_url) {
errors.push('success_url is required');
}
data.products?.forEach((p, i) => {
if (p.amount <= 10) {
errors.push(`products[${i}].amount must be > 10 XOF`);
}
});
if (errors.length > 0) {
throw new Error(errors.join(', '));
}
}
Getting Help
If you're stuck:
- Check the API Reference for endpoint details
- Verify your request matches the examples
- Contact support with:
- The endpoint you're calling
- Your request body (without the API key)
- The error response you received
- The timestamp of the request