Integrate with the Onafriq (formerly MFS Africa) API to connect with 400M+ mobile wallets and 200M+ bank accounts across Africa. Use this skill whenever the user wants to send money to mobile money wallets, process collections, execute batch disbursements, or manage payouts across Africa. Trigger when the user mentions 'Onafriq', 'MFS Africa', 'mobile money hub', 'mobile wallet transfers', 'African payout', 'cross-border payments', or needs to reach customers on mobile money platforms across 40+ African countries.
Onafriq, formerly known as MFS Africa, is Africa's largest digital payments hub connecting over 400 million mobile wallets and 200 million bank accounts across more than 40 African countries. It provides a unified API for money transfers, collections, and disbursements across diverse mobile money providers, banks, and cash agents on the continent.
Build fintech applications, salary disbursement systems, utility payment platforms, or any service that needs to reach customers via mobile money across Africa. Onafriq abstracts the complexity of multiple mobile money providers, banks, and regional payment schemes into a single integration. Perfect for:
All Onafriq API requests require Token-based authentication using an API key:
Authorization: Token YOUR_API_KEY
Generate your API key in the Onafriq Dashboard under API Settings. Store the key securely in environment variables (ONAFRIQ_API_KEY) and never hardcode credentials.
Base URLs:
https://api.mfsafrica.com/apihttps://mfsafrica.beyonicpartners.com/apiContact your account manager to confirm which base URL applies to your account. Both URLs support versioning via path (/v1, /v2) or headers.
Create a payment to a mobile money wallet, bank account, or cash agent.
POST /api/v1/create_payment
Request Body:
{
"account_reference": "REF_USER_123456",
"transaction_reference": "TRX_2025_001",
"customer": {
"email": "[email protected]",
"msisdn": "+254701234567"
},
"details": {
"msisdn": "+254701234567",
"country_code": "KE",
"amount": 1000,
"currency": "KES"
},
"service_type": "mobile_money_payout",
"reason": "Vendor payment",
"metadata": {
"vendor_id": "VENDOR_123",
"transaction_type": "payout"
}
}
Response:
{
"success": true,
"data": {
"payment_id": "MFS_PAY_xxxxx",
"account_reference": "REF_USER_123456",
"transaction_reference": "TRX_2025_001",
"status": "pending",
"destination_country": "KE",
"destination_msisdn": "+254701234567",
"amount": 1000,
"currency": "KES",
"service_type": "mobile_money_payout",
"created_at": "2025-02-24T10:30:00Z"
}
}
Results come asynchronously via webhook. Monitor payment.status.changed events for completion.
Check the status of a previously initiated payment.
GET /api/v1/payments/{payment_id}
Response:
{
"success": true,
"data": {
"payment_id": "MFS_PAY_xxxxx",
"account_reference": "REF_USER_123456",
"transaction_reference": "TRX_2025_001",
"status": "completed",
"destination_country": "KE",
"destination_msisdn": "+254701234567",
"amount": 1000,
"currency": "KES",
"provider": "mpesa",
"provider_reference": "MP_REF_12345",
"created_at": "2025-02-24T10:30:00Z",
"completed_at": "2025-02-24T10:30:45Z",
"fees": 25,
"failure_reason": null
}
}
Status values: pending, completed, failed, cancelled.
Set up a payment collection request for customers to pay via mobile money.
POST /api/v1/collection_requests
Request Body:
{
"account_reference": "ACC_REF_001",
"customer": {
"email": "[email protected]",
"first_name": "John",
"last_name": "Doe",
"msisdn": "+254701234567"
},
"collection_details": {
"msisdn": "+254701234567",
"country_code": "KE",
"amount": 5000,
"currency": "KES",
"description": "Service subscription payment",
"requested_by": "APP_VENDOR"
},
"metadata": {
"invoice_id": "INV_2025_001",
"subscription_plan": "premium"
}
}
Response:
{
"success": true,
"data": {
"collection_request_id": "MFS_COL_xxxxx",
"account_reference": "ACC_REF_001",
"customer_msisdn": "+254701234567",
"amount": 5000,
"currency": "KES",
"status": "pending",
"created_at": "2025-02-24T10:30:00Z",
"expires_at": "2025-02-26T10:30:00Z",
"webhook_secret": "webhook_secret_xxxxx"
}
}
Customer receives an in-app or USSD notification to complete payment. Status updates arrive via webhook (collectionrequest.status.changed).
GET /api/v1/collection_requests/{collection_request_id}
Response:
{
"success": true,
"data": {
"collection_request_id": "MFS_COL_xxxxx",
"account_reference": "ACC_REF_001",
"customer_msisdn": "+254701234567",
"amount": 5000,
"currency": "KES",
"status": "received",
"created_at": "2025-02-24T10:30:00Z",
"received_at": "2025-02-24T10:35:00Z",
"received_amount": 5000,
"provider": "mpesa"
}
}
Get a list of collections received against a collection request.
GET /api/v1/collection_requests/{collection_request_id}/collections
Response:
{
"success": true,
"data": [
{
"collection_id": "MFS_COLL_xxxxx",
"amount": 5000,
"currency": "KES",
"provider": "mpesa",
"provider_reference": "MP_REF_54321",
"received_at": "2025-02-24T10:35:00Z"
}
]
}
GET /api/v1/payments?limit=50&offset=0&status=completed&created_after=2025-02-01&created_before=2025-02-28&country_code=KE
Query Parameters:
limit: Max results (default 50, max 100)offset: Pagination offsetstatus: Filter by status (pending/completed/failed)created_after: ISO 8601 start datecreated_before: ISO 8601 end datecountry_code: Filter by destination countrytransaction_reference: Filter by referenceResponse:
{
"success": true,
"data": [
{
"payment_id": "MFS_PAY_xxxxx",
"transaction_reference": "TRX_2025_001",
"amount": 1000,
"currency": "KES",
"status": "completed",
"created_at": "2025-02-24T10:30:00Z"
}
],
"pagination": {
"limit": 50,
"offset": 0,
"total": 150
}
}
Onafriq sends webhooks for payment and collection events. Configure your webhook endpoint in the Dashboard under API Settings.
Verify the HMAC signature to ensure webhooks are authentic:
const crypto = require('crypto');
const signature = req.headers['x-onafriq-signature'];
const body = req.rawBody; // Use raw request body string, not parsed JSON
const expectedSignature = crypto
.createHmac('sha256', YOUR_WEBHOOK_SECRET)
.update(body)
.digest('hex');
if (signature === expectedSignature) {
// Valid webhook — process the event
} else {
// Invalid signature — reject
return res.status(401).send('Unauthorized');
}
Payment Events:
payment.status.changed - Payment status changed (pending → completed/failed)payment.completed - Payment successfully deliveredpayment.failed - Payment failedCollection Events:
collection.received - Collection received from customercollectionrequest.status.changed - Collection request status changed (pending → received/expired/cancelled)collectionrequest.expired - Collection request expired without paymentExample Payment Webhook Payload:
{
"event": "payment.status.changed",
"timestamp": "2025-02-24T10:30:45Z",
"data": {
"payment_id": "MFS_PAY_xxxxx",
"transaction_reference": "TRX_2025_001",
"account_reference": "REF_USER_123456",
"status": "completed",
"amount": 1000,
"currency": "KES",
"destination_msisdn": "+254701234567",
"destination_country": "KE",
"provider": "mpesa",
"provider_reference": "MP_REF_12345",
"completed_at": "2025-02-24T10:30:45Z",
"fees": 25
}
}
Example Collection Webhook Payload:
{
"event": "collection.received",
"timestamp": "2025-02-24T10:35:00Z",
"data": {
"collection_id": "MFS_COLL_xxxxx",
"collection_request_id": "MFS_COL_xxxxx",
"account_reference": "ACC_REF_001",
"customer_msisdn": "+254701234567",
"amount": 5000,
"currency": "KES",
"provider": "mpesa",
"provider_reference": "MP_REF_54321",
"received_at": "2025-02-24T10:35:00Z"
}
}
POST /api/v1/create_payment with recipient detailspayment_id in your databasepayment.status.changed webhookPOST /api/v1/create_payment with salary detailspayment_id values and associate with batchpayment.status.changed webhooksPOST /api/v1/collection_requests with customer detailscollection.received webhookPOST /api/v1/create_payment for each seller payoutOnafriq returns consistent error responses:
{
"success": false,
"error": {
"code": "INSUFFICIENT_BALANCE",
"message": "Your wallet balance is insufficient for this transaction",
"type": "validation_error"
}
}
| Code | Error | Action |
|---|---|---|
| 400 | Bad Request | Validation error (invalid phone, unsupported country, invalid amount). Check request format. |
| 401 | Unauthorized | Invalid or missing API key. Verify token in Authorization header. |
| 403 | Forbidden | Permission denied or account not enabled for this operation. Contact support. |
| 404 | Not Found | Resource not found (payment ID, collection request ID). Check ID format. |
| 422 | Unprocessable Entity | Validation failed (e.g., phone number format invalid, amount outside limits). |
| 429 | Too Many Requests | Rate limited. Implement exponential backoff (1s, 2s, 4s, 8s...). |
| 500 | Server Error | Service unavailable. Retry with exponential backoff. |
| 502 | Bad Gateway | Provider unavailable. Retry with exponential backoff. |
| 503 | Service Unavailable | Temporary outage. Retry with exponential backoff. |
INSUFFICIENT_BALANCE - Wallet balance too low for transactionINVALID_MSISDN - Phone number format invalid or unsupportedUNSUPPORTED_COUNTRY - Country code not supportedUNSUPPORTED_PROVIDER - Mobile money provider not available in countryINVALID_AMOUNT - Amount outside provider limitsDUPLICATE_TRANSACTION - Duplicate reference already processedPAYMENT_FAILED - Provider rejected paymentINVALID_API_KEY - API key invalid or expiredRATE_LIMIT_EXCEEDED - Too many requests⚠️ UNVERIFIED ENDPOINTS — No Public Documentation Available
Onafriq (formerly MFS Africa) does not maintain a public API documentation portal. The endpoint paths, request/response shapes, and authentication mechanisms documented in this skill are based on reported integrations and community knowledge, not official documentation. Treat all endpoint paths as unverified. Always request official API documentation from your Onafriq account representative before production use.
⚠️ COMMERCIAL PARTNERSHIP REQUIRED
Onafriq API access requires a signed commercial partnership agreement. This is not a self-service integration — you must contact Onafriq via https://www.onafriq.com/ and complete their enterprise onboarding process. Expect a sales and compliance review before receiving credentials.
⚠️ TWO SEPARATE API SURFACES: Beyonic vs Onafriq Hub
The base URLs documented here reflect two different products:
https://api.mfsafrica.com/api— the Onafriq domestic payments APIhttps://mfsafrica.beyonicpartners.com/api— the Beyonic-based cross-border API (Onafriq acquired Beyonic in 2021)These are different systems with different capabilities, coverage, and response schemas. Confirm with your Onafriq contact which API surface applies to your use case. Do not assume these APIs are interchangeable.
MFS Africa rebranded to Onafriq in November 2023. The company name changed but the API endpoints, base URLs, and core functionality remain the same. Documentation and dashboards now reference "Onafriq" but some legacy references to "MFS Africa" may still exist. Both names refer to the same service.
Onafriq connects to 500M+ mobile money wallets across Africa. Major providers include:
Coverage continues to expand. Check your account dashboard for the latest provider availability in your target countries.
Onafriq operates in 40+ African countries including: Kenya, Uganda, Tanzania, Rwanda, Burundi, Ghana, Nigeria, Cameroon, Ivory Coast, Senegal, Togo, South Africa, Zambia, Zimbabwe, Malawi, Botswana, Namibia, Lesotho, Eswatini, Mauritius, Seychelles, Sudan, Egypt, and more. Check your dashboard for current coverage.
Always format phone numbers with country code and no leading zero:
+254701234567 (Kenya)+256701234567 (Uganda)+254 0701234567 (leading zero)0701234567 (missing country code)Limits vary by country, provider, and customer tier:
Onafriq charges fees per transaction. Fee structure depends on:
Fees are deducted from your wallet balance and returned in all API responses. Always display fees to end users and account for them in pricing calculations.
This skill was updated with verified information from: