Hosted Checkout Guide (Mobile Money + Cards)
This guide details how to integrate the Little Pay Hosted Checkout Page into your application. This method allows you to redirect your customers to a secure payment page hosted by Little Pay. The Hosted Checkout Page supports both Mobile Money and Cards payments.
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
2. Create Payment Intent
To initiate a payment, you need to 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 (can include decimals, some payment providers may not support decimals eg MPESA and amount will be rounded to nearest whole number)
"currency": "string", //required ISO 4217 currency code eg "KES" for Kenyan Shillings
"description": "string", // required
"callbackUrl": "string", // required
"key": "string", // required (alphanumeric string, no special characters eg (-,/,*,+,\))
"returnUrl": "string", // optional - will redirect to this url after payment is completed
"expiresAt": 0, // optional - minutes after which the payment intent will expire
"payload": {
"billingAddress": {
"firstName": "string", //optional
"lastName": "string", //optional
"address1": "string", //optional - street address
"locality": "string", //optional - city/town
"administrativeArea": "string", //optional - state/province/county
"postalCode": "string", //optional - zip code
"country": "string", //optional - ISO 3166-1 alpha-2 country code eg "KE" for Kenya
"email": "string", //optional if phone is provided
"phoneNumber": "string" //optional if email is provided (ISO format eg +254712345678)
},
"customData": null // optional - a json with custom data that will be included in the callback
}
}
Code Examples
- JavaScript
- PHP
- Python
- Java
const https = require('https');
const data = JSON.stringify({
amount: 100,
currency: "KES",
description: "Payment for Order #123",
callbackUrl: "https://your-domain.com/callback",
key: "ORDER12345", // Unique alphanumeric key
returnUrl: "https://your-domain.com/success",
payload: {
billingAddress: {
firstName: "John",
lastName: "Doe",
email: "john.doe@example.com",
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" => "Payment for Order #123",
"callbackUrl" => "https://your-domain.com/callback",
"key" => "ORDER12345",
"returnUrl" => "https://your-domain.com/success",
"payload" => [
"billingAddress" => [
"firstName" => "John",
"lastName" => "Doe",
"email" => "john.doe@example.com",
"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
import json
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": "Payment for Order #123",
"callbackUrl": "https://your-domain.com/callback",
"key": "ORDER12345",
"returnUrl": "https://your-domain.com/success",
"payload": {
"billingAddress": {
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"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": "Payment for Order #123",
"callbackUrl": "https://your-domain.com/callback",
"key": "ORDER12345",
"returnUrl": "https://your-domain.com/success",
"payload": {
"billingAddress": {
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"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": "https://pay.little.africa/checkout/...",
"message": "Request processed successfully"
}
}
3. Display Checkout URL
On success, the response will contain a checkoutUrl. Redirect your customer to this URL to complete the payment.
If you provided a returnUrl in the payment intent, the user will be redirected to that URL after the payment is successfully processed.
4. Handle Callback
Once the payment is completed, a callback will be sent to the callbackUrl you provided.
Callback Payload
{
"reference": "1cbfffbc-b365-45f6-9e5d-13e445c125cd",
"status": "COMPLETED", // COMPLETED or FAILED
"payload": {
"billingAddress": { /* ... */ },
"customData": null
},
"amount": 1,
"key": "ORDER12345",
"currency": "KES",
"provider": "MPESA",
"date": "2025-02-03T13:49:46.000Z"
}
Handling Examples
- Node.js (Express)
- PHP
- Python (Flask)
- Java (Spring Boot)
app.post('/callback', (req, res) => {
const { status, reference, key } = req.body;
if (status === 'COMPLETED') {
console.log(`Payment for order ${key} (Ref: ${reference}) successful.`);
// Update order status in database
} else {
console.log(`Payment failed.`);
}
res.status(200).send('OK');
});
<?php
$json = file_get_contents('php://input');
$data = json_decode($json, true);
if ($data) {
$status = $data['status'];
$reference = $data['reference'];
$key = $data['key'];
if ($status === 'COMPLETED') {
// Payment successful, update database
error_log("Payment for order $key (Ref: $reference) successful.");
}
}
http_response_code(200);
?>
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/callback', methods=['POST'])
def callback():
data = request.json
status = data.get('status')
reference = data.get('reference')
key = data.get('key')
if status == 'COMPLETED':
print(f"Payment for order {key} (Ref: {reference}) successful.")
# Update database
return jsonify(success=True), 200
@PostMapping("/callback")
public ResponseEntity<String> handleCallback(@RequestBody Map<String, Object> payload) {
String status = (String) payload.get("status");
String reference = (String) payload.get("reference");
String key = (String) payload.get("key");
if ("COMPLETED".equals(status)) {
System.out.println("Payment for order " + key + " (Ref: " + reference + ") successful.");
// Update database
}
return ResponseEntity.ok("OK");
}