Payments API
Accept mobile money, cards, and bank transfers across 54+ African countries with instant settlements, fraud detection, and PCI compliance.
π Quick Startβ
curl -X POST https://api.afriroute.ai/api/v1/payments \
-H "Authorization: Bearer $AFRIROUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 1000,
"currency": "ETB",
"method": "mobile_money",
"provider": "telebirr",
"phone": "+251911234567",
"description": "Order #12345"
}'
π³ Payment Methodsβ
Mobile Moneyβ
Ethiopia (Telebirr), Kenya (M-Pesa), Uganda (MTN Mobile Money), Ghana (MTN Momo, Vodafone Cash), Rwanda (MTN Momo), etc.
const response = await fetch('https://api.afriroute.ai/api/v1/payments', {
method: 'POST',
headers: {
'Authorization': 'Bearer $AFRIROUTE_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 1000,
currency: 'ETB',
method: 'mobile_money',
provider: 'telebirr',
phone: '+251911234567',
customer: {
name: 'John Doe',
email: '[email protected]'
},
metadata: {
order_id: '12345',
customer_id: 'cust_abc123'
},
callback_url: 'https://yourapp.com/webhooks/payment'
})
});
const data = await response.json();
console.log(data.payment_id); // pay_abc123
console.log(data.status); // pending
console.log(data.ussd_code); // *127#
Cards (Visa, Mastercard)β
{
amount: 5000,
currency: 'KES',
method: 'card',
card: {
number: '4242424242424242',
exp_month: 12,
exp_year: 2025,
cvv: '123'
},
customer: {
name: 'Jane Smith',
email: '[email protected]'
}
}
Bank Transferβ
{
amount: 10000,
currency: 'NGN',
method: 'bank_transfer',
bank: {
account_number: '1234567890',
bank_code: '058',
account_name: 'John Doe'
}
}
π Payment Flowβ
1. Create Paymentβ
const payment = await createPayment({
amount: 1000,
currency: 'ETB',
method: 'mobile_money',
provider: 'telebirr',
phone: '+251911234567'
});
// Response
{
payment_id: 'pay_abc123',
status: 'pending',
ussd_code: '*127#', // For USSD-based providers
expires_at: '2024-03-15T10:40:00Z'
}
2. Customer Completes Paymentβ
Customer dials USSD code or enters PIN in mobile money app.
3. Receive Webhookβ
app.post('/webhooks/payment', (req, res) => {
const { payment_id, status, amount, currency } = req.body;
if (status === 'completed') {
console.log(`Payment ${payment_id} successful: ${amount} ${currency}`);
// Fulfill order
await fulfillOrder(req.body.metadata.order_id);
// Send confirmation
await sendEmail({
to: req.body.customer.email,
subject: 'Payment Received',
template: 'payment_confirmation'
});
} else if (status === 'failed') {
console.log(`Payment ${payment_id} failed: ${req.body.failure_reason}`);
}
res.sendStatus(200);
});
π Check Statusβ
const status = await fetch(
`https://api.afriroute.ai/api/v1/payments/${payment_id}`,
{ headers: { 'Authorization': 'Bearer $AFRIROUTE_API_KEY' } }
);
const data = await status.json();
console.log(data);
// {
// payment_id: 'pay_abc123',
// status: 'completed',
// amount: 1000,
// currency: 'ETB',
// provider: 'telebirr',
// completed_at: '2024-03-15T10:35:42Z',
// receipt_url: 'https://afriroute.ai/receipts/pay_abc123'
// }
πΈ Payoutsβ
Send money to customers (refunds, seller payments, etc.).
await fetch('https://api.afriroute.ai/api/v1/payouts', {
method: 'POST',
headers: {
'Authorization': 'Bearer $AFRIROUTE_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 500,
currency: 'KES',
method: 'mobile_money',
provider: 'mpesa',
phone: '+254712345678',
description: 'Refund for order #12345'
})
});
π 3D Secureβ
For card payments, 3DS is automatically triggered when required.
const payment = await createPayment({
amount: 10000,
currency: 'NGN',
method: 'card',
card: cardData,
return_url: 'https://yourapp.com/payment/complete'
});
if (payment.status === 'requires_action') {
// Redirect customer to 3DS authentication
window.location.href = payment.redirect_url;
}
π Supported Providersβ
East Africaβ
- πͺπΉ Ethiopia: Telebirr, CBE Birr, M-Birr
- π°πͺ Kenya: M-Pesa, Airtel Money
- πΉπΏ Tanzania: M-Pesa, Tigo Pesa, Airtel Money
- πΊπ¬ Uganda: MTN Mobile Money, Airtel Money
- π·πΌ Rwanda: MTN Mobile Money
West Africaβ
- π³π¬ Nigeria: Paystack, Flutterwave, Bank Transfer
- π¬π Ghana: MTN Momo, Vodafone Cash, AirtelTigo
Southern Africaβ
- πΏπ¦ South Africa: Cards, EFT, SnapScan
π° Currency Supportβ
42 currencies supported:
- ETB (Ethiopian Birr)
- KES (Kenyan Shilling)
- NGN (Nigerian Naira)
- ZAR (South African Rand)
- USD, EUR, GBP
- View all currencies β
π Webhooksβ
Payment Eventsβ
app.post('/webhooks/payment', (req, res) => {
const signature = req.headers['x-afriroute-signature'];
// Verify webhook signature
if (!verifySignature(req.body, signature)) {
return res.status(401).send('Invalid signature');
}
const { event, payment } = req.body;
switch (event) {
case 'payment.created':
console.log('Payment initiated');
break;
case 'payment.completed':
console.log('Payment successful');
await fulfillOrder(payment.metadata.order_id);
break;
case 'payment.failed':
console.log('Payment failed:', payment.failure_reason);
break;
case 'payment.refunded':
console.log('Payment refunded');
break;
}
res.sendStatus(200);
});
Signature Verificationβ
const crypto = require('crypto');
function verifySignature(payload, signature) {
const expectedSignature = crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(JSON.stringify(payload))
.digest('hex');
return signature === expectedSignature;
}
π‘ Best Practicesβ
Securityβ
- Verify webhook signatures - prevent fraudulent webhooks
- Use HTTPS - always use secure connections
- Store API keys securely - use environment variables
- Implement idempotency - use unique transaction IDs
- Log all transactions - for auditing and dispute resolution
User Experienceβ
- Show clear pricing - display amount and currency upfront
- Handle timeouts gracefully - payments can take 30-120 seconds
- Provide payment status - show real-time updates
- Support multiple methods - let users choose preferred provider
- Send receipts - email confirmation after successful payment
Performanceβ
- Use webhooks - don't poll for payment status
- Implement retry logic - handle transient failures
- Set reasonable timeouts - 120 seconds for mobile money
- Cache provider availability - check before showing options
Complianceβ
- KYC requirements - collect customer information for large amounts
- Transaction limits - respect provider limits (e.g., M-Pesa: 150K KES/transaction)
- Anti-money laundering - flag suspicious patterns
- Data retention - keep transaction records for 7 years
π‘οΈ Fraud Detectionβ
Automatic fraud checks on all transactions:
- β Velocity checks (multiple failed attempts)
- β Geolocation verification
- β Device fingerprinting
- β Unusual amount patterns
- β Blacklist checking
Configure in dashboard: Settings β Fraud Prevention
β οΈ Error Handlingβ
try {
const payment = await createPayment(paymentData);
} catch (error) {
if (error.code === 'INSUFFICIENT_FUNDS') {
showError('Insufficient balance. Please top up and try again.');
} else if (error.code === 'INVALID_PHONE') {
showError('Invalid phone number. Please check and retry.');
} else if (error.code === 'PROVIDER_UNAVAILABLE') {
showError('Payment provider temporarily unavailable. Try another method.');
} else if (error.code === 'AMOUNT_TOO_LOW') {
showError(`Minimum amount is ${error.min_amount} ${error.currency}`);
}
}
Common Error Codesβ
| Code | Description | Action |
|---|---|---|
INSUFFICIENT_FUNDS | Customer has low balance | Ask customer to top up |
INVALID_PHONE | Wrong phone number | Validate input |
PROVIDER_UNAVAILABLE | Service down | Show alternative method |
AMOUNT_TOO_LOW | Below minimum | Show minimum amount |
AMOUNT_TOO_HIGH | Above maximum | Split transaction |
TRANSACTION_TIMEOUT | No response from provider | Retry or use webhook |
π° Pricingβ
| Transaction Type | Fee |
|---|---|
| Mobile Money | 2.5% + $0.20 |
| Cards | 3.5% + $0.30 |
| Bank Transfer | 1.5% + $0.50 |
| Payouts | 1.0% + $0.10 |
Volume discounts available for >$10K monthly volume.
π Dashboard Featuresβ
- π³ Real-time transaction monitoring
- π Revenue analytics
- πΈ Automatic settlements (daily/weekly)
- π Refund management
- π Payment success rates
- π Geographic breakdown
- π§ Customer receipts
π§ͺ Testingβ
Use test credentials in sandbox mode:
// Test mobile money
{
phone: '+254700000000', // Always succeeds
phone: '+254711111111', // Always fails (insufficient funds)
phone: '+254722222222', // Timeout (use for timeout testing)
}
// Test cards
{
number: '4242424242424242', // Visa success
number: '4000000000000002', // Card declined
number: '4000000000000341', // 3DS required
}
π οΈ SDKsβ
// JavaScript/Node.js
const afriroute = require('@afriroute/sdk');
const payments = new afriroute.Payments('$AFRIROUTE_API_KEY');
const payment = await payments.create({
amount: 1000,
currency: 'ETB',
method: 'mobile_money',
provider: 'telebirr',
phone: '+251911234567'
});
# Python
from afriroute import Payments
payments = Payments(api_key='$AFRIROUTE_API_KEY')
payment = payments.create(
amount=1000,
currency='ETB',
method='mobile_money',
provider='telebirr',
phone='+251911234567'
)
π Related Resourcesβ
Need help? Contact Support β | View Code Examples β