Skip to main content

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

EnvironmentServer URL [SERVER_URL]
Sandboxhttps://sandbox-api.fonbnk.com
Productionhttps://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?

  1. Generate a timestamp (Epoch Unix Timestamp)
  2. Concatenate the timestamp and the endpoint that is called {timestamp}:{endpoint}
  3. Decode the base64 encoded clientSecret
  4. Compute the SHA256 hash of the concatenated string. Use decoded clientSecret as a key. Convert the result to base64
  5. 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

HeaderDescriptionExample
x-client-idclientId which can be found at the merchant dashboard settings page645a20cbaf1d31dbd52c0fda
x-timestampA 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-signatureComputed 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:

StrategyDescription
best_priceAt 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.
wholesaleWe fulfill the request only using the wholesale price.
marketWe 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

StatusDescription
pendingThe top-up request was succesfully created
completedThe recipient got the airtime
failedThe 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

CodeDescription
1000Too low airtime amount
1001Too big airtime amount
1002Unsupported country
1003Unsupported carrier
1004Unable to fulfill the request
1005Invalid airtime amount format
1006Invalid recipient phone number
1007Invalid strategy
1008Invalid top-up request ID
1009Insufficient funds
1010Unsupported strategy for the carrier
1011Invalid 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"
}