NEW APP AVAILABLE FOR DOWNLOAD NOW

Get it on Google PlayDownload on the App Store

Airtime

Purchase mobile airtime for all major networks

Purchase airtime for MTN, Airtel, Glo, and 9mobile networks.

Supported Networks

NetworkCode
MTN NigeriaMTN
Airtel NigeriaAIRTEL
GlobacomGLO
9mobile9MOBILE

Purchase Flow

Airtime purchases are straightforward - no verification required.

  1. List products - Get available airtime products
  2. Make purchase - Send the purchase request

Step 1: List Products

bash
curl -X GET \
  -H "Authorization: Bearer sk_live_your_secret_key" \
  "https://my.rizpay.app/api/partners/v1/products/airtimes?network=MTN"

Response:

json
{
  "status": { "code": 200, "message": "Success" },
  "data": [
    {
      "id": "prd_mtn_airtime",
      "type": "airtime",
      "attributes": {
        "display_name": "MTN Airtime",
        "network": "MTN",
        "min_amount": "50.00",
        "max_amount": "50000.00",
        "price": {
          "currency": "NGN",
          "basis": "face_value",
          "min_amount": "50.00",
          "max_amount": "50000.00"
        }
      }
    }
  ]
}

The price block

Airtime is a variable-priced product - the partner picks the amount. RizPay returns the supported range as a face_value tuple. The partner will be billed exactly the amount they submit on the purchase request (no markup today). To quote your end-user, take their request amount, add your margin, and bill them; RizPay will bill you the underlying amount.

FieldTypeNotes
currencystringAlways NGN
basisstringface_value (partner chooses the amount)
min_amountstringSmallest amount accepted by the network
max_amountstringLargest amount accepted by the network

Step 2: Make Purchase

bash
curl -X POST \
  -H "Authorization: Bearer sk_live_your_secret_key" \
  -H "Content-Type: application/json" \
  -d '{
    "product_id": "prd_mtn_airtime",
    "phone_number": "08012345678",
    "amount": "500.00",
    "external_reference": "1736234400B2C3D4"
  }' \
  https://my.rizpay.app/api/partners/v1/purchases

Response:

json
{
  "status": { "code": 201, "message": "Purchase created" },
  "data": {
    "id": "txn_abc123",
    "type": "transaction",
    "attributes": {
      "amount": "500.00",
      "currency": "NGN",
      "status": "pending",
      "category": "purchase",
      "description": "Purchase of MTN Airtime",
      "reference": "airtime-order-001",
      "external_reference": "1736234400B2C3D4",
      "product_type": "airtime",
      "phone_number": "08012345678",
      "price": {
        "product_amount": "500.00",
        "fee_amount": "0.00",
        "total_debit": "500.00",
        "currency": "NGN",
        "basis": "face_value"
      },
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    }
  }
}

The price breakdown

Every purchase response carries a price object so you can reconcile the debit against your customer charge:

FieldTypeNotes
product_amountstringWhat the underlying product cost. For airtime equals your requested amount.
fee_amountstringAny partner-tier markup RizPay applied. Zero today.
total_debitstringWhat was actually taken from your wallet (product_amount + fee_amount).
currencystringAlways NGN.
basisstringface_value for airtime/electricity, fixed for data/cable TV.

Check Transaction Status

Poll the transaction or use webhooks to get the final status:

bash
curl -X GET \
  -H "Authorization: Bearer sk_live_your_secret_key" \
  "https://my.rizpay.app/api/partners/v1/purchases/txn_abc123"

Successful response:

json
{
  "status": { "code": 200, "message": "Success" },
  "data": {
    "id": "txn_abc123",
    "reference": "airtime-order-001",
    "status": "successful",
    "amount": "500.00",
    "phone_number": "08012345678",
    "completed_at": "2024-01-15T10:30:02Z"
  }
}

Complete Example

javascript
// Generate external reference: 10-digit timestamp + 6 alphanumeric
function generateReference() {
  const timestamp = Math.floor(Date.now() / 1000);
  const chars =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  let suffix = "";
  for (let i = 0; i < 6; i++) {
    suffix += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return `${timestamp}${suffix}`;
}

async function purchaseAirtime(network, phoneNumber, amount) {
  const API_KEY = "sk_live_your_secret_key";
  const BASE_URL = "https://my.rizpay.app/api/partners/v1";

  // Step 1: Find the product
  const productsRes = await fetch(
    `${BASE_URL}/products/airtimes?network=${network}`,
    { headers: { Authorization: `Bearer ${API_KEY}` } }
  );
  const products = await productsRes.json();
  const product = products.data[0];

  // Validate amount
  if (parseFloat(amount) < parseFloat(product.min_amount)) {
    throw new Error(`Minimum amount is ${product.min_amount}`);
  }
  if (parseFloat(amount) > parseFloat(product.max_amount)) {
    throw new Error(`Maximum amount is ${product.max_amount}`);
  }

  // Step 2: Make purchase
  const purchaseRes = await fetch(`${BASE_URL}/purchases`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      product_id: product.id,
      phone_number: phoneNumber,
      amount: amount,
      external_reference: generateReference(),
    }),
  });

  return await purchaseRes.json();
}

// Usage
purchaseAirtime("MTN", "08012345678", "1000.00")
  .then((result) => console.log(result))
  .catch((error) => console.error(error));

Phone Number Validation

Nigerian phone numbers should:

  • Start with 080, 081, 070, 090, or 091
  • Be 11 digits total
  • Match the network of the product (or be cross-network if supported)
PrefixNetwork
0803, 0806, 0813, 0816, 0810, 0814, 0903, 0906, 0913, 0916MTN
0802, 0808, 0812, 0701, 0708, 0902, 0907, 0912Airtel
0805, 0807, 0811, 0815, 0705, 0905, 0915Glo
0809, 0817, 0818, 0908, 09099mobile

Amount Limits

NetworkMinMax
MTN5050,000
Airtel5050,000
Glo5050,000
9mobile5050,000

Limits may vary. Check the product min_amount and max_amount fields.

Transaction States

StatusDescription
pendingProcessing with provider
successfulAirtime delivered
failedPurchase failed (balance refunded)

Required Scope

Requires the purchase_airtime scope on your API key.

Next Steps