Skip to content
iSmartPay Developers
Esc
↑↓navigate↵open⌘Jpreview
On this page

Utility purchases

Buy airtime and data for a mobile number.

You can buy airtime and data for any mobile number in Ghana, paid from your wallet or by the customer over mobile money.

What you can buy

List the products on sale now:

GET /v1/utility-products
{
  "items": [
    {
      "id": "mtn-airtime",
      "category": "airtime",
      "network": "mtn",
      "name": "MTN airtime",
      "kind": "flexi",
      "min": "1.00",
      "max": "500.00",
      "currency": "GHS",
      "delivery": "verified"
    },
    {
      "id": "telecel-data-1gb",
      "category": "data",
      "network": "telecel",
      "name": "1GB",
      "kind": "fixed",
      "price": "10.00",
      "currency": "GHS",
      "validity": "30 days",
      "delivery": "unverified"
    }
  ]
}

The values above only show the shape. Read the list rather than hard-coding product IDs.

  • The list has airtime and data only.
  • MTN data is sold as flexi data. MTN’s named bundles are not offered.
  • Ismart Global products are not offered.
  • ECG and other meter products are not on sale yet.
  • Telecel and AirtelTigo products show delivery: unverified. None has been confirmed delivered yet, so check the first ones you sell.

Amounts and fees

  • A fixed product is sold at its price. Send that as the amount.
  • A flexi product is sold at any amount from min to max.
  • Airtime starts at GHS 1.00.
  • The fee is added on top of the amount. You pay the amount plus the fee.

Ask for the fee before you buy:

GET /v1/fee-quotes/utilities?productId=mtn-airtime&amount=10.00&currency=GHS
{
  "productId": "mtn-airtime",
  "amount": "10.00",
  "currency": "GHS",
  "fee": "0.20",
  "gross": "10.20"
}

gross is what you pay. A quote holds nothing. The purchase prices again when it runs.

Buy

POST /v1/utility-purchases
Idempotency-Key: 6c1f0e2a-airtime-1
{
  "reference": "airtime-1001",
  "productId": "mtn-airtime",
  "amount": "10.00",
  "currency": "GHS",
  "beneficiary": { "msisdn": "233244123456" },
  "funding": { "type": "wallet" }
}
  • reference is yours, and unique for each purchase. See Idempotency and references.
  • beneficiary.msisdn is the number that receives the airtime or data, in 233 form.
  • currency is GHS. No other currency is sold.

A 202 means the purchase was accepted. It has not been delivered yet:

{
  "reference": "airtime-1001",
  "status": "accepted",
  "product": { "id": "mtn-airtime", "category": "airtime", "network": "mtn", "name": "MTN airtime" },
  "beneficiary": { "msisdn": "233244123456" },
  "amount": "10.00",
  "currency": "GHS",
  "fee": "0.20",
  "gross": "10.20",
  "funding": { "type": "wallet" },
  "createdAt": "2026-10-04T10:00:00Z"
}

Funding

funding.type says who pays.

  • wallet. The total is taken from your wallet. If the sale fails, it goes back to your wallet. Do not send a payer.
  • collection. The customer pays. They get a mobile money prompt for the total and approve it on their phone. Nothing is sold until they have paid. If the sale then fails, they are refunded in full.
{
  "type": "collection",
  "payer": { "provider": "mtn", "msisdn": "233244000111" }
}

payer.provider is mtn or telecel.

Statuses

Status Meaning Final?
accepted We have the purchase. No
awaiting_payment Waiting for the customer to approve the mobile money prompt. No
vending Being sold. No
delivered The airtime or data was sent. Yes
failed The sale did not go through. failureReason says why. Ends the sale; a refund can follow
refunding The customer’s payment is being returned. No
refunded The customer’s payment was returned in full. Yes
refund_failed The refund did not reach the customer. iSmartPay retries it. No
outcome_unknown The result was not clear. See below. No

outcome_unknown means we could not tell whether the airtime or data was sent. The money stays held and nothing is sold again. iSmartPay finds out and moves the purchase on.

Follow a purchase with webhooks, or poll GET /v1/utility-purchases/{reference}. Treat any status you do not know as still in progress.

Permissions

To The key needs
Quote a fee or buy disbursements.write
List products or read a purchase disbursements.read

Webhooks

Subscribe an endpoint to these events in the console:

Type Sent when
utility_purchase.accepted A purchase is accepted.
utility_purchase.status_changed A purchase moves to a new status, such as delivered or refunded.

data is the purchase as it stood when the event was sent. It does not carry the beneficiary’s number or the payer. Fetch the purchase by reference when you need them. See Webhooks.

If your webhook endpoints were set up before utility purchases arrived, edit or add an endpoint in the console once. Until then, these events are not sent to your business, and they do not appear in GET /v1/events.

Errors

As well as the common errors, a purchase or quote can be refused with:

Status Code What to do
404 product_not_found No product has that productId. Read the product list again.
422 product_not_sellable The product is not on sale now. Pick another.
422 amount_out_of_range The amount is not the product’s price, or is outside min and max.
422 currency_not_supported Send GHS.
422 beneficiary_invalid The product cannot be sold to this number. Check the network.
422 fee_unpriceable The fee cannot be worked out right now. Try again later.
503 utilities_unavailable Purchases are not available right now. Try again later.

Was this page helpful?