Purchase data
Purchase a data plan. Request fields, response examples and integration guidance.
/purchases/data
Example request
curl --request POST \
--url "https://api.strongmb.ng/v1/purchases/data" \
--header "Authorization: Bearer $STRONGMB_API_KEY" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data '{
"phone": "0123456789",
"product_code": "smb_mtn_sme_1gb_30days",
"reference": "SMB202609160001"
}'
// Server-side Node.js 22+; never expose your key in a browser.
async function main() {
const response = await fetch("https://api.strongmb.ng/v1/purchases/data", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.STRONGMB_API_KEY}`,
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify({
"phone": "0123456789",
"product_code": "smb_mtn_sme_1gb_30days",
"reference": "SMB202609160001"
}),
signal: AbortSignal.timeout(30000)
});
const result = await response.json();
console.log(response.status, result);
// For purchases, inspect data.status before showing a receipt.
}
main().catch(console.error);
<?php
// Requires the PHP cURL extension.
$client = curl_init('https://api.strongmb.ng/v1/purchases/data');
curl_setopt_array($client, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('STRONGMB_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => '{
"phone": "0123456789",
"product_code": "smb_mtn_sme_1gb_30days",
"reference": "SMB202609160001"
}',
]);
$raw = curl_exec($client);
if ($raw === false) {
throw new RuntimeException(curl_error($client));
}
$status = curl_getinfo($client, CURLINFO_HTTP_CODE);
curl_close($client);
$result = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
print_r(['http_status' => $status, 'response' => $result]);
// For purchases, inspect data.status before showing a receipt.
require 'net/http'
require 'json'
uri = URI('https://api.strongmb.ng/v1/purchases/data')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == 'https'
http.open_timeout = 10
http.read_timeout = 30
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer ' + ENV.fetch('STRONGMB_API_KEY')
request['Accept'] = 'application/json'
request['Content-Type'] = 'application/json'
request.body = '{
"phone": "0123456789",
"product_code": "smb_mtn_sme_1gb_30days",
"reference": "SMB202609160001"
}'
begin
response = http.request(request)
result = JSON.parse(response.body)
puts({ http_status: response.code, response: result }.to_json)
rescue StandardError => error
warn error.message
end
# Reconcile an uncertain purchase before retrying.
import json
import os
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
headers = {
"Authorization": "Bearer " + os.environ["STRONGMB_API_KEY"],
"Accept": "application/json",
"Content-Type": "application/json",
}
payload = {'phone': '0123456789',
'product_code': 'smb_mtn_sme_1gb_30days',
'reference': 'SMB202609160001'}
body = json.dumps(payload).encode("utf-8")
request = Request(
"https://api.strongmb.ng/v1/purchases/data",
data=body, headers=headers, method="POST"
)
try:
with urlopen(request, timeout=30) as response:
result = json.load(response)
print(response.status, result)
except HTTPError as error:
print(error.code, error.read().decode("utf-8"))
except URLError as error:
print("Network error:", error.reason)
# Reconcile an uncertain purchase before retrying.
Purchase a data plan using a product_code obtained from /products/internet.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| phone | string | Required | Recipient phone number |
| product_code | string | Required | From /products/internet (e.g. smb_mtn_sme_1gb_30days) |
| reference | string | Required | Unique reference. a-zA-Z0-9 only. |
Request Example
{
"phone": "0123456789",
"product_code": "smb_mtn_sme_1gb_30days",
"reference": "SMsadkjhdfkgfjaaa1fhaa"
}
{
"status": true,
"message": "Data purchase is being processed.",
"data": {
"status": "processing",
"type": "data",
"provider": "mtn",
"title": "1gb mtn sme data",
"recipient": "0123456789",
"data_type": "sme",
"plan": "1gb",
"validity": "30days",
"bundle_size_mb": 1024,
"reference": "SMsadkjhdfkgfjaaa1fhaa",
"currency": "NGN",
"balance_before": "44584.00",
"balance_after": "44114.00",
"amount": 470
},
"metadata": { "code": "ERR_TRANSACTION_PROCESSING", "timestamp": 1773797068, "trace_id": "96640DE2C7" }
}
{
"status": true,
"message": "Transaction completed successfully.",
"data": {
"status": "successful",
"type": "data",
"provider": "airtel",
"title": "5gb airtel gifting data",
"recipient": "0123456789",
"data_type": "gifting",
"plan": "5gb",
"validity": "2days",
"bundle_size_mb": 5000,
"description": null,
"reference": "1SMsaadkj3hd5fdaaaa1fahaa",
"date": "2026-09-21 00:51:37",
"currency": "NGN",
"balance_before": "886959.56",
"balance_after": "885459.56",
"amount": "1500.00"
},
"metadata": {
"code": "TRANSACTION_SUCCESSFUL",
"timestamp": 1789948297,
"trace_id": "9055DC6574"
}
}
{
"status": false,
"message": "Your transaction has failed, amount has been refunded to your wallet.",
"data": {
"transaction_status": "failed",
"type": "data",
"provider": "airtel",
"title": "5gb airtel gifting data",
"recipient": "0123456789",
"data_type": "gifting",
"plan": "5gb",
"status": "failed",
"validity": "2days",
"bundle_size_mb": 5000,
"description": null,
"reference": "1SMsaadk3k33",
"date": "2026-09-24 01:47:47",
"currency": "NGN"
},
"metadata": {
"code": "ERR_TRANSACTION_FAILED",
"timestamp": 1790210867,
"trace_id": "1ECAE30874"
}
}
{
"status": false,
"message": "Insufficient wallet balance.",
"data": null,
"metadata": { "code": "ERR_INSUFFICIENT_BALANCE", "timestamp": 1773797069, "trace_id": "97641EF3D8" }
}
{
"status": false,
"message": "Product code is invalid or currently inactive.",
"data": null,
"metadata": { "code": "ERR_INVALID_PRODUCT_CODE_OR_INACTIVE", "timestamp": 1773797072, "trace_id": "AA644H26GB" }
}
{
"status": false,
"message": "Invalid mobile number.",
"data": null,
"metadata": { "code": "ERR_INVALID_MOBILE_NUMBER", "timestamp": 1773797071, "trace_id": "99643G15FA" }
}
{
"status": false,
"message": "Daily limit exceeded. Contact support to increase.",
"data": null,
"metadata": { "code": "ERR_DAILY_LIMIT_EXCEEDED", "timestamp": 1773797073, "trace_id": "BB645I37HC" }
}
{
"status": false,
"message": "Service provider temporarily unavailable.",
"data": null,
"metadata": { "code": "ERR_PRODUCT_GATEWAY_UNAVAILABLE", "timestamp": 1773797070, "trace_id": "98642F04E9" }
}
Understand the request fields
| Field | Integration guidance |
|---|---|
phone
|
Recipient phone number. Preserve the leading zero. Confirm the network: prefixes do not account for ported numbers. |
product_code
|
An exact identifier from the matching product list, not a provider name or an identifier from a different API. |
reference
|
Your saved identifier for this intended purchase. Use 10–255 letters or digits. Duplicate references are rejected. |
Handle the purchase result
Show a receipt only for a successful outcome. Keep processing transactions pending. Reconcile failed or timed-out purchases before another attempt.
Response fields and types
Expand an object to explore its fields. [] indicates an array item. Error responses may return
data: null.
| Field path | JSON type | Meaning and handling |
|---|---|---|
status |
boolean | Request-level success flag. Check the HTTP status and metadata code as well; a successful API request is not by itself proof of purchase fulfillment. |
message |
string | Human-readable description of the result. Use metadata.code for programmatic error handling instead of parsing this text. |
data |
null | object | Response payload. A failed purchase can return transaction details even when the top-level status is false. Check that data is an object before reading data.status; other errors may return null or validation information. |
data.status |
string | Purchase outcome: successful, processing or failed. Use this field rather than the top-level status flag to decide whether a purchase completed. |
data.type |
string | Service or transaction type, for example data, airtime, electricity or cable TV. |
data.provider |
string | Provider identifier associated with the purchased service. |
data.title |
string | Short display title for the transaction receipt. |
data.recipient |
string | Phone number, meter or customer identifier for the purchase. Compare it with the intended recipient. |
data.data_type |
string | Data product classification for the purchased bundle. |
data.plan |
string | Display label of the purchased plan. |
data.validity |
string | Human-readable validity or duration label for the selected plan. |
data.bundle_size_mb |
integer | Data volume in megabytes as an integer. |
data.reference |
string | Reference supplied when creating the purchase. Save it and use the same value for transaction verification. |
data.currency |
string | Currency code, such as NGN for Nigerian naira. |
data.balance_before |
string | Wallet balance before this transaction, as reported by the API. |
data.balance_after |
string | Wallet balance after this transaction, as reported by the API. |
data.amount |
string | Amount charged, returned as a decimal string in the indicated currency. |
metadata |
object | Diagnostic information about the response. |
metadata.code |
string | Machine-readable result code. Use it to distinguish validation, authentication and service errors. |
metadata.timestamp |
integer | Unix timestamp in seconds associated with the response. |
metadata.trace_id |
string | Correlation identifier for troubleshooting. Retain it with a redacted request when contacting support. |
data.description |
string | null | Optional description; the successful response can return null. |
data.date |
string | Transaction date and time as returned by the API. |
data.transaction_status |
string | Deprecated legacy outcome field included in this failed example. Use data.status in new integrations. |
Always check metadata.code; do not rely on HTTP status alone. See response codes and recommended
handling.
Test your integration Use the sandbox test values and examples.
Questions? Let’s work through them.
Having an issue or need help with your integration? Join the Strongmb Slack community to ask questions and get assistance from our team and other developers.
Keep API keys and customer details private when sharing examples.
Experiencing a service issue? Check Strongmb’s service status for incident updates.
Did this page help you?
Up to 100 characters. Please leave out personal details, account information and API keys.