Data bundle API for Nigerian apps

Offer data bundles through RizPay with catalogue-based selection, current partner costs and a purchase flow that tracks delivery separately from payment acceptance.

Already registered? Open API settings and follow the business-access steps. Sandbox purchases do not deliver real services.

Reviewed

Data customers choose a specific bundle, not simply an amount of airtime. Present the network, bundle size, validity and plan-family label together. Two bundles with the same size can have different restrictions or validity periods, so size alone is not a safe product key.

Design the checkout

Use the product ID from the catalogue as the value in your selector. Read every page of results before presenting a complete list, and preserve a null bundle-family label rather than inventing one. Recheck the chosen product before a customer confirms an old saved basket.

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.

bash
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/dataplans"

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.

A data plan has a fixed catalogue cost in price.amount. Your application decides the retail price and collects its own markup. Use decimal arithmetic or integer minor units for money. Do not parse the product name to recover a price, and do not promise the illustrative rates in old documentation as current offers.

Confirm the payment target

Data purchases do not use meter or decoder verification. Your confirmation screen should include the number, selected network, bundle size, validity and total retail charge. Submit the exact selected product rather than searching by size at purchase time.

Prepare one purchase per order

The purchase request uses product_id, network, phone_number, external_reference. Enable the relevant purchase permission (purchase_data) 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 network value must be the one on the product you selected: a purchase whose network does not match its product is rejected in production even though the sandbox accepts it. The recipient values below are sandbox fixtures, not real recipients. For variable-amount products, choose an amount within the selected product's limits.

json
{
  "product_id": "$RIZPAY_PRODUCT_ID",
  "phone_number": "08011111111",
  "network": "$RIZPAY_SELECTED_PRODUCT_VALUE",
  "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.

Can I buy airtime and call it a data purchase?

No. Submit the selected data product to the data purchase flow. An airtime credit is a different service and should never be shown as successful delivery of the data bundle your customer selected.

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.