Skip to main content
Version: v2

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

StatusMeaningWhat to Do
400Bad RequestCheck your request body for missing or invalid fields
401UnauthorizedVerify your API key is correct
403ForbiddenYou don't have access to this resource
404Not FoundCheck the resource ID exists
429Rate LimitedSlow down - max 100 requests per 60 seconds
500Server ErrorRetry later, contact support if persistent

Common Errors & Solutions

Invalid API Key (401)

{ "error": "Invalid or missing API key" }

Solutions:

  • Check the Authorization header 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_id or payout_id is 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:

  1. Check the API Reference for endpoint details
  2. Verify your request matches the examples
  3. 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