Mobile Money Guide
This guide details how to process Mobile Money payments (MPESA, AIRTEL, MTN, TIGOPESA) directly via the Little Pay API.
1. Setup & Credentials
Before getting started, ensure you have an account:
- Create an account and a sandbox merchant at https://pay.little.africa.
- Navigate to Merchants -> Merchant Settings to obtain your credentials:
- App ID
- Client ID
- Client Secret
- Token ID
- Secret Key (Used as
X-API-KEY)
Note: The Secret Key can be found in the Security tab of the Merchant Settings.
2. Create Payment Intent
First, create a payment intent.
- URL:
https://pay.little.africa/api/payments/{tokenId}/pay - Method:
POST - Authentication: Basic Auth (use
ClientIdas username andClientSecretas password).
Request Body
The payload should be a JSON object with the following fields:
{
"amount": 0, //required - amount
"currency": "string", //required ISO 4217 currency code eg "KES"
"description": "string", // required
"callbackUrl": "string", // required
"key": "string", // required alphanumeric string
"expiresAt": 0, // optional - minutes after which the payment intent expires
"payload": {
"billingAddress": {
"firstName": "string", //optional
"lastName": "string", //optional
"email": "string", //optional if phone is provided
"phoneNumber": "string" //optional if email is provided
},
"customData": null // optional json with any additional data you want to pass
}
}
Code Examples
To create a payment intent, see the examples below:
- JavaScript
- PHP
- Python
- Java
const https = require('https');
const data = JSON.stringify({
amount: 100,
currency: "KES",
description: "Mobile Money Payment",
callbackUrl: "https://your-domain.com/callback",
key: "MM12345",
payload: {
billingAddress: {
phoneNumber: "+254712345678"
}
}
});
const options = {
hostname: 'pay.little.africa',
path: '/api/payments/{tokenId}/pay', // Replace {tokenId}
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic ' + Buffer.from('YOUR_CLIENT_ID:YOUR_CLIENT_SECRET').toString('base64'),
'Content-Length': data.length
}
};
const req = https.request(options, (res) => {
let body = '';
res.on('data', (chunk) => body += chunk);
res.on('end', () => {
console.log(JSON.parse(body));
});
});
req.write(data);
req.end();
<?php
$url = "https://pay.little.africa/api/payments/{tokenId}/pay"; // Replace {tokenId}
$clientId = "YOUR_CLIENT_ID";
$clientSecret = "YOUR_CLIENT_SECRET";
$data = [
"amount" => 100,
"currency" => "KES",
"description" => "Mobile Money Payment",
"callbackUrl" => "https://your-domain.com/callback",
"key" => "MM12345",
"payload" => [
"billingAddress" => [
"phoneNumber" => "+254712345678"
]
]
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Basic ' . base64_encode("$clientId:$clientSecret")
]);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>
import requests
from requests.auth import HTTPBasicAuth
url = "https://pay.little.africa/api/payments/{tokenId}/pay" # Replace {tokenId}
client_id = "YOUR_CLIENT_ID"
client_secret = "YOUR_CLIENT_SECRET"
payload = {
"amount": 100,
"currency": "KES",
"description": "Mobile Money Payment",
"callbackUrl": "https://your-domain.com/callback",
"key": "MM12345",
"payload": {
"billingAddress": {
"phoneNumber": "+254712345678"
}
}
}
response = requests.post(
url,
auth=HTTPBasicAuth(client_id, client_secret),
json=payload
)
print(response.json())
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Base64;
public class Main {
public static void main(String[] args) throws Exception {
String url = "https://pay.little.africa/api/payments/{tokenId}/pay"; // Replace {tokenId}
String clientId = "YOUR_CLIENT_ID";
String clientSecret = "YOUR_CLIENT_SECRET";
String auth = Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes());
String jsonPayload = """
{
"amount": 100,
"currency": "KES",
"description": "Mobile Money Payment",
"callbackUrl": "https://your-domain.com/callback",
"key": "MM12345",
"payload": {
"billingAddress": { "phoneNumber": "+254712345678" }
}
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/json")
.header("Authorization", "Basic " + auth)
.POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
Response
{
"date": "2024-03-07T13:03:05.141Z",
"data": {
"reference": "YOUR_REFERENCE_ID",
"checkoutUrl": "",
"message": "Request processed successfully"
}
}
3. Process Payment
Use the reference from Step 2 to process the mobile money payment.
- URL:
https://pay.little.africa/pay/{reference}/process - Method:
POST
Request Body
{
"type": "MPESA", // supports: MPESA, AIRTEL, MTN, TIGOPESA
"payment": {
"mobile": "+254712345678" // phone number in ISO format
}
}
Code Examples
- JavaScript
- PHP
- Python
- Java
const https = require('https');
const data = JSON.stringify({
type: "MPESA",
payment: {
mobile: "+254712345678"
}
});
const options = {
hostname: 'pay.little.africa',
path: '/pay/{reference}/process', // Replace {reference}
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length
}
};
const req = https.request(options, (res) => {
let body = '';
res.on('data', (chunk) => body += chunk);
res.on('end', () => {
console.log(JSON.parse(body));
});
});
req.write(data);
req.end();
<?php
$url = "https://pay.little.africa/pay/{reference}/process"; // Replace {reference}
$data = [
"type" => "MPESA",
"payment" => [
"mobile" => "+254712345678"
]
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>
import requests
url = "https://pay.little.africa/pay/{reference}/process" # Replace {reference}
payload = {
"type": "MPESA",
"payment": {
"mobile": "+254712345678"
}
}
response = requests.post(url, json=payload)
print(response.json())
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class ProcessPayment {
public static void main(String[] args) throws Exception {
String url = "https://pay.little.africa/pay/{reference}/process"; // Replace {reference}
String jsonPayload = """
{
"type": "MPESA",
"payment": {
"mobile": "+254712345678"
}
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
Response
{
"date": "2024-03-07T13:03:43.598Z",
"data": {
"status": "PENDING",
"message": "You will be promoted to enter your MPESA PIN",
"meta": {
"provider": "MPESA",
"providerReference": "",
"stepUpUrl": null,
"accessToken": null,
"amount": 1,
"currency": "KES",
"description": "",
"reference": ""
}
}
}
4. Handle Callback
Once the payment is completed (user enters PIN), a callback is sent to your callbackUrl.
{
"reference": "1cbfffbc-b365-45f6-9e5d-13e445c125cd",
"status": "COMPLETED", // COMPLETED or FAILED
"payload": {
"billingAddress": { /* ... */ },
"customData": null
},
"amount": 1,
"key": "MM12345",
"currency": "KES",
"provider": "MPESA",
"date": "2025-02-03T13:49:46.000Z"
}
5. Check Status (Optional)
You can check the transaction status at any time.
- URL:
https://pay.little.africa/api/payments-v2/{key} - Method:
GET - Headers:
X-API-KEY: {Secret Key}
Response
{
"date": "2024-05-13T08:26:18.719Z",
"data": {
"reference": "1cbfffbc-b365-45f6-9e5d-13e445c125cd",
"status": "COMPLETED",
"payload": { /* ... */ },
"amount": 1,
"payment": {
"provider": "MPESA",
"details": null
},
"key": "MM12345"
}
}