9mobile airtime API: product codes and purchases
Use the 9MOBILE identifier in RizPay's airtime catalogue and purchase flow. Keep the API code separate from customer-facing network labels.
Already registered? Open API settings and follow the business-access steps. Sandbox purchases do not deliver real services.
Reviewed
RizPay's documented API identifier for this network is 9MOBILE. Keep this machine identifier in your integration mapping rather than deriving request values from whatever label your interface displays.
Design the checkout
Filter the airtime catalogue with 9MOBILE and use the matching returned product. If your customer-facing labels change, review that mapping explicitly. Editing display text must not silently change the API request or choose a different network.
Discover current products
Use a sandbox key with the view_products scope. Keep the key in a server environment variable. The request below reads the catalogue; it does not buy a service.
curl --fail-with-body --silent --show-error --max-time 20 \
-H "Authorization: Bearer ${RIZPAY_API_KEY:?Set a sandbox API key}" \
"https://my.rizpay.app/api/partners/sandbox/v1/products/airtimes?network=9MOBILE"
Read products from data and their details from attributes. Follow pagination.total_pages when you need the complete list. Select an actual returned ID, not a guessed or documentation-example ID. Catalogue availability can change: refresh an unavailable selection and let the customer choose again.
Airtime uses a customer-selected face value. Read the product's minimum and maximum amounts, validate the requested value on your server, and show any fee your application charges separately. The purchase response's price breakdown records the total debit; a product label is not a fee quotation.
Confirm the payment target
Airtime does not use the meter or decoder verification step. Confirm the phone number, network and requested amount in your own checkout. Normalise input to the phone format documented by the API, while keeping identifiers as strings.
Prepare one purchase per order
The purchase request uses product_id, network, phone_number, amount, external_reference. Enable the relevant purchase permission (purchase_airtime) and read_transactions for status checks. Confirm your key's permissions against the authentication reference when moving from sandbox to production.
This is the JSON body shape for a sandbox purchase. Replace every dollar-prefixed placeholder before sending it, using the product you selected and your stored order reference. The recipient values below are sandbox fixtures, not real recipients. For variable-amount products, choose an amount within the selected product's limits.
{
"product_id": "$RIZPAY_PRODUCT_ID",
"phone_number": "08011111111",
"amount": "1000.00",
"network": "9MOBILE",
"external_reference": "$RIZPAY_ORDER_REFERENCE"
}
Send the body to POST /api/partners/sandbox/v1/purchases. Generate and persist the reference once for the order, following the documented format. Do not make a new reference simply because a request timed out. Keep product selection, pricing and authorization on your server; a browser or mobile app must never contain the partner secret.
Follow the result
Persist data.id from an accepted purchase and inspect data.attributes.status. An accepted request can still be pending. Read the existing purchase with GET /purchases/:id and reconcile signed webhook events with your stored order. If the response was lost, look up the existing external reference before considering another purchase.
A DUPLICATE_REFERENCE response establishes that a reference has already been used; it does not prove fulfillment. Retrieve the existing transaction and check its status. Only successful is a completed purchase. Handle failed and reversed outcomes according to the returned transaction and your own ledger; do not issue a second refund because the same event arrives again.
Should I send the display name as the network?
Use the network code returned by the selected product. Display labels are for the customer; API identifiers control routing. Treat a changed or missing code as a reason to refresh the catalogue and review the selection.
Before accepting real orders
Test a successful purchase, an unresolved pending result and a failure. Confirm that a repeated submit cannot make a second local order and that the receipt reflects the final state. Use the sandbox's configured test recipients rather than arbitrary phone or meter numbers. Sandbox delivery is simulated and is not a measurement of live biller reliability.
Read the product reference, sandbox guide and pricing explanation before enabling production access.