USSD + Bank Payments +Airtime

This is a step-by-step tutorial on how you can use Africa’s Talking Ltd’s API to build a USSD application that can be used to sell airtime. It combines three products offered by AT i.e USSD, Airtime and Payments. For this specific tutorial, we will be using Bank Payments which is currently only available in Nigeria.

Okay, great, let’s get to it.


  1. An Africa’s Talking account.
  2. A USSD code
  3. A payments product
  4. Ngrok — a tunneling tool to make localhost run online
  5. Basic PHP knowledge.

User journey:

After this is done a checkout request will be initiated and then validated using the transaction-id and the OTP.

Once the payment has been confirmed the airtime will be sent to their phone number.

Code Walkthrough:

Step 1:

This is what the table looks like.

Create a file that we will use this file to connect to the database and store or retrieve data as required. I’ve called mine Driver.php.

In it add the below code.

These are the SQL queries we’ll be using to check the user’s level and graduate them accordingly.

Step 2:

//connect to the db in order to store the user responses
include 'Driver.php';
$driver = new Driver();
// Reads the variables sent via POST from Africas Talking
$sessionId = $_POST["sessionId"];
$serviceCode = $_POST["serviceCode"];
$phoneNumber = $_POST["phoneNumber"];
$text = $_POST["text"];
//get the last part of the text
$textArray=explode('*', $text);
//set the default level to help us navigate the user through different menus as we progress
//check the user's level from the db in order to decide which menu to serve next. $level = $driver->checkLevel($sessionId);if ( $level == 0) {//this is the very first level so we save the level to the db first then proceed to serve the first menu.
//This is the first request. Note how we start the response with CON
$response = "CON How much airtime would you like to buy?\n";
$response .= "Minimum: 100 \n";
$response .="Maximum: 10,000";
//now we graduate the user to the next level.

We then do the same for the other levels.

else if($level==1){
$response = "CON What is your account name?\n";

else if($level == 2){
$response = "CON What is your account number \n";
else if($level == 3){
$response = "CON Name of your bank, select from below\n";
$response .= "0. FCMB \n";
$response .= "1. Zenith \n";
$response .= "2. Access \n";\
$response .= "3. Providus \n";
$response .= "4. Sterling\n";


Step 3: Initiate a bank check out request.

The text parameter we get from Africa’s Talking at this point looks like this:


So we will break it up store it in an array that will later be used to initiate the bank checkout request. Since this is already done by this line from step 2:

$textArray=explode('*', $text);

We proceed to use this information to initiate a bank checkout request. First, we serve the last menu. Notice how we use the word END

\else if($level == 4){
$response = "END Thanks, we are processing your request.\n Please standby";

Now we need the user's bank code which we get from their response to the last menu. We use the last response to match the bank selected to the bank code.

$bankcode = [234001, 234002, 234003, 234007, 234010 ];
$bankCode = $bankcode[$userResponse];

Now that we have the bank code we proceed to the other bank information which needs to be in an array called `bank Account`. For the purpose of this tutorial, I hardcoded the birthdate but you should probably add another menu asking for the user’s birthdate

$bankAccount = ['accountName'=>$textArray[1],'accountNumber'=>$textArray[2],'bankCode'=>$bankCode,'dateOfBirth'=>"1989"];

Okay so now we take all this and include it in the $options array that we’ll later use to call the bank Checkout function. These are all the parameters required to initiate a bankCheckout request.

$options = [ 'productName' =>  "Airtime",
'bankAccount'=> $bankAccount,
'narration'=>"Airtime payment"];
$response = $payments->bankCheckout($options);

At this point, we will need to import Africa’s Talking Ltd SDK. So add these two lines in your code, just before the include ‘driver.php’ line.

//connect to the db in order to store the user responses
require_once "vendor/autoload.php";
include 'Driver.php';
$driver = new Driver();
use AfricasTalking\SDK\AfricasTalking;

The AT SDK needs your AT username and password and then we call the payments function.

use AfricasTalking\SDK\AfricasTalking;
$username = "username";
$apiKey = "apikey";
$AT = new AfricasTalking($username, $apiKey);
$payments = $AT->payments();

Step 4: Validate Checkout Request

The default OTP for the transaction on the Sandbox is 1234.

$tid = (array)$response['data'];
$tid = $tid['transactionId'];
$otp = "1234";
$payments-> validateBankCheckout(['transactionId'=>$tid,'otp'=>$otp]);

Step 5: Send Airtime

At the top of your code, right below $payments = $AT->payments();
add the line

$airtime = $AT->airtime();

Then at the bottom after validatebankCheckout add:

'recipients' => [["phoneNumber"=>$phoneNumber,"amount"=>"NGN ".$textArray[0] ],]]);

And that’s it. You can find the full source code on gist.

Enjoy selling airtime to your clients.

I write stuff sometimes :)