API Details
Overview
The API is organized around REST. The API accepts json-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes and verbs.
API servers
Environment | Server URL [SERVER_URL] |
---|---|
Sandbox | https://sandbox-api.fonbnk.com |
Production | https://aten.fonbnk-services.com |
Sandbox Testing
When you interact with Sandbox version of the API, you have the same experience as you would in production, but you won’t get charged real tokens and won’t receive real top-ups just yet.
Request Authentication
All requests should be signed using a HMAC256 algorithm and provided clientId
and clientSecret
.
How to get the signature of the request?
- Generate a timestamp (Epoch Unix Timestamp)
- Concatenate the timestamp and the endpoint that is called
{timestamp}:{endpoint}
- Decode the base64 encoded clientSecret
- Compute the SHA256 hash of the concatenated string. Use decoded clientSecret as a key. Convert the result to base64
- Add the clientId, signature, and timestamp to HTTP headers
The following pseudocode example demonstrates and explains how to sign a request
timestamp = CurrentTimestamp();
stringToSign = timestamp + ":" + endpoint;
signature = Base64 ( HMAC-SHA256 ( Base64-Decode ( clientSecret ), UTF8 ( concatenatedString ) ) );
Typescript example
import crypto from "crypto";
const generateSignature = ({
clientSecret,
timestamp,
endpoint,
}: {
clientSecret: string;
timestamp: string;
endpoint: string;
}) => {
let hmac = crypto.createHmac("sha256", Buffer.from(clientSecret, "base64"));
let stringToSign = `${timestamp}:${endpoint}`;
hmac.update(stringToSign);
return hmac.digest("base64");
};
Each request should include the following headers
Header | Description | Example |
---|---|---|
x-client-id | clientId which can be found at the merchant dashboard settings page | 645a20cbaf1d31dbd52c0fda |
x-timestamp | A UNIX timestamp you generate before sending a request to us. Please generate this timestamp right before sending a request to us and re-generate it for every request. | 1663240633 |
x-signature | Computed signature using clientSecret provided to you. | Y90dweZduRFNEF8MsmEUExBg8b8ha= |
API Methods
Create top-up request
Create a request to top-up a specified phone number.
This endpoint reduces your account's balance and initiates a top-up.
Additionally, you can pass the carrier name to top-up a specific carrier.
If you don't pass the carrier name, we will automatically detect the carrier and top-up the phone number, which may
take a few seconds to complete.
Strategies
Furthermore, you can pass the strategy parameter to specify the strategy for fulfilling the top-up request. The default strategy is best_price
.
Available strategies are:
Strategy | Description |
---|---|
best_price | At first, we try to fulfill the request using the market price (p2p). If we can't, we will fulfill the request using the wholesale price. |
wholesale | We fulfill the request only using the wholesale price. |
market | We fulfill the request only using the market price (p2p). |
Request
Request URL
[POST] [SERVER_URL]/api/v1/top-up/create-request
Request body
{
airtimeAmount: 100,
recipientPhoneNumber: "254XXXXXXXXX",
carrierName: "Safaricom Kenya", //optional
strategy: "best_price", //optional
}
Endpoint for signature
/api/v1/top-up/create-request
Request Headers
x-client-id: vXVMhQlr5+sq4cPdCD5b4W0T6wM53nDGraxtadiavbg=
x-timestamp: 1663240633
x-signature: Y90dweZduRFNEF8MsmEUExBg8b8ha5SLYHz5uoYO8wA=
Response
A successful request will return the following JSON encoded response
{
"requestId": "Y90dweZduRFNEF8Msm",
"status": "pending",
"airtimeAmount": 100,
"carrier": "Safaricom Kenya",
"recipientPhoneNumber": "XXXXXXXXXXXX",
"date": "2022-09-16T07:05:46.126Z"
}
List of available carriers
Returns a list of available carriers
Request
Request URL
[GET] [SERVER_URL]/api/v1/top-up/carriers
Endpoint for signature
/api/v1/top-up/carriers
Request Headers
x-client-id: vXVMhQlr5+sq4cPdCD5b4W0T6wM53nDGraxtadiavbg=
x-timestamp: 1663240633
x-signature: Y90dweZduRFNEF8MsmEUExBg8b8ha5SLYHz5uoYO8wA=
Response
A successful request will return the following JSON encoded response
[
"MTN Nigeria",
"Airtel Nigeria",
"9mobile Nigeria",
"Glo Nigeria",
"Safaricom Kenya",
"Airtel Kenya",
"Telkom Kenya",
]
Get top-up request by id
Get the details of a top-up request
Request
Request URL
[GET] [SERVER_URL]/api/v1/top-up/request/<REQUEST_ID>
Endpoint for signature
/api/v1/top-up/request/<REQUEST_ID>
Request Headers
x-client-id: vXVMhQlr5+sq4cPdCD5b4W0T6wM53nDGraxtadiavbg=
x-timestamp: 1663240633
x-signature: Y90dweZduRFNEF8MsmEUExBg8b8ha5SLYHz5uoYO8wA=
Response
A successful request will return the following JSON encoded response
{
"requestId": "Y90dweZduRFNEF8Msm",
"usdAmount": 0.83,
"exchangeRate": 120,
"status": "completed",
"airtimeAmount": 100,
"recipientPhoneNumber": "XXXXXXXXXXXX",
"date": "2022-09-16T07:05:46.126Z"
}
Get top-up requests list
Get the list of a top-up requests. You can pass the limit
and page
parameters to paginate the results. The result is sorted by the date
field in descending order.
Request
Request URL
[GET] [SERVER_URL]/api/v1/top-up/requests?limit=10&page=1
Endpoint for signature
/api/v1/top-up/request/requests?limit=10&page=1
Request Headers
x-client-id: vXVMhQlr5+sq4cPdCD5b4W0T6wM53nDGraxtadiavbg=
x-timestamp: 1663240633
x-signature: Y90dweZduRFNEF8MsmEUExBg8b8ha5SLYHz5uoYO8wA=
Response
A successful request will return the following JSON encoded response
[
{
requestId: "Y90dweZduRFNEF8Msm",
usdAmount: 0.83,
exchangeRate: 120,
status: "completed",
airtimeAmount: 100,
recipientPhoneNumber: "XXXXXXXXXXXX",
date: "2022-09-16T07:05:46.126Z"
}
]
Top up request statuses
Status | Description |
---|---|
pending | The top-up request was succesfully created |
completed | The recipient got the airtime |
failed | The top-up request failed, your account will be refunded |
Balance
Get account balance
Request
Request URL
[GET] [SERVER_URL]/api/v1/top-up/balance
Endpoint for signature
/api/v1/top-up/balance
Request Headers
x-client-id: vXVMhQlr5+sq4cPdCD5b4W0T6wM53nDGraxtadiavbg=
x-timestamp: 1663240633
x-signature: Y90dweZduRFNEF8MsmEUExBg8b8ha5SLYHz5uoYO8wA=
Response
A successful request will return the following JSON encoded response
{
balance: 1000.00
}
Verify top-up request
This endpoint estimates the top-up cost and validates the data you need to provide to create a top-up request.
This endpoint doesn't reduce your account's balance.
Additionally, you can pass the strategy parameter to specify the price estimation strategy. The default strategy is best_price
.
Available strategies are: best_price
, wholesale
, market
.
Request
Request URL
[POST] [SERVER_URL]/api/v1/top-up/verify-request
Request body
{
airtimeAmount: 100,
recipientPhoneNumber: "254XXXXXXXXX",
strategy: "best_price" //optional
}
Endpoint for signature
/api/v1/top-up/verify-request
Request Headers
x-client-id: vXVMhQlr5+sq4cPdCD5b4W0T6wM53nDGraxtadiavbg=
x-timestamp: 1663240633
x-signature: Y90dweZduRFNEF8MsmEUExBg8b8ha5SLYHz5uoYO8wA=
Response
A successful request will return the following JSON encoded response
{
"carrier": "Safaricom Kenya",
"usdAmount": 0.83,
"exchangeRate": 120,
"airtimeAmount": 100,
"recipientPhoneNumber": "254XXXXXXXXX"
}
Error codes
Code | Description |
---|---|
1000 | Too low airtime amount |
1001 | Too big airtime amount |
1002 | Unsupported country |
1003 | Unsupported carrier |
1004 | Unable to fulfill the request |
1005 | Invalid airtime amount format |
1006 | Invalid recipient phone number |
1007 | Invalid strategy |
1008 | Invalid top-up request ID |
1009 | Insufficient funds |
1010 | Unsupported strategy for the carrier |
1011 | Invalid airtime amount |
All validation or processing error responses will have the following format and HTTP status code 400 (Bad request)
{
"message": "Validation error",
"errorCode": "1000",
"description": "Too low airtime amount"
}