Developer Guides
Airtime and Data API Integration in Nigeria: Build a Reliable Top-Up Flow
Build an airtime and data purchase flow that handles uncertain delivery, duplicate requests, and refunds. This developer guide covers product discovery, ledger design, status handling, and launch checks for Nigerian digital businesses.
Airtime and data API integration in Nigeria requires more than a successful HTTP request. Your application must collect the right recipient details, present valid products, reserve customer funds, and distinguish confirmed delivery from an unresolved transaction. For fintechs, marketplaces, and digital businesses, those details determine whether a convenient feature becomes a support burden.
Paddle offers bills and value-added services (VAS) alongside payment and ledger capabilities. This guide explains how to design a reliable top-up flow around those building blocks, while keeping provider-specific endpoints and transaction rules grounded in the current API documentation.
Plan your airtime and data API integration in Nigeria
Start with a narrow purchase journey: a customer buys airtime or a data bundle for a Nigerian mobile number using an available balance in your application. Add scheduled purchases, promotional bundles, and other bill categories only after the basic transaction lifecycle is dependable.
Your initial architecture needs five responsibilities:
- Product discovery: retrieve and display currently supported services and bundles.
- Purchase orchestration: validate requests and submit purchases safely.
- Balance control: reserve funds and prevent concurrent overspending.
- Status resolution: reconcile pending purchases with provider outcomes.
- Customer communication: explain whether a purchase is processing, delivered, or unsuccessful.
Keep these responsibilities separate even if they initially live in one backend service. Your frontend should never decide that a purchase succeeded solely because the submit request returned without an error.
Before implementation, confirm Paddle’s supported billers, product fields, authentication requirements, status mechanisms, and transaction limits in the documentation or with the integration team. Do not assume every VAS category follows the same workflow.
Build product discovery before checkout
Airtime purchases and data bundles have different input requirements. Airtime may use an entered amount, while data purchases typically depend on a specific product identifier. Your integration must follow the requirements of the selected service.
Keep catalogue data fresh
Where a catalogue API is available, use it rather than hard-coding bundle names and prices. Store the provider’s product identifier alongside the display name, network, amount, and any supplied validity information.
Cache catalogue responses for browsing, but revalidate the selected product before charging the customer. If a price or availability changes, ask the customer to confirm the updated purchase instead of silently substituting another bundle.
Treat missing catalogue fields as unknown. Do not invent bundle allowances, expiry periods, or promotional conditions for a cleaner interface.
Validate recipients without guessing
Normalize phone numbers into the format required by the API. Accept familiar customer input formats, then validate and convert them server-side.
Do not rely on a phone-number prefix alone to determine the current network: mobile number portability can make that assumption unreliable. Let customers confirm the network, or use a supported lookup mechanism where available.
Before submission, show a confirmation screen containing the recipient number, selected network, product, and total charge. Explain any limits on correcting or reversing a completed purchase using verified service terms.
Separate the purchase from the funding ledger
A top-up order describes the service being purchased. A ledger records what happened to the customer’s money. These records should reference each other without being treated as the same object.
For an internal purchase record, store:
- A unique purchase reference and customer identifier.
- Recipient number, network, and product identifier.
- Service value, total customer charge, and currency.
- Current status and a version for concurrency control.
- Provider reference, when returned.
- Creation time, last status check, and resolution time.
Keep sensitive fields out of general application logs. Use masked recipient numbers for routine troubleshooting and restrict access to full transaction details.
Reserve funds atomically
Before submitting a purchase, check the available balance and create a reservation in one atomic operation. Otherwise, two simultaneous purchases can both pass the same balance check.
A reservation reduces spendable funds without claiming that the service has already been delivered. On confirmed success, finalize the debit. On a definitive failure, release the reservation.
For unresolved purchases, keep the reservation subject to a documented investigation policy. Do not automatically release funds merely because your HTTP request timed out: the provider may still have processed the purchase.
If Paddle ledgers are part of your implementation, map these requirements to their documented behavior. An application-level reservation is a design requirement, not a claim about a particular API primitive.
Model uncertain delivery explicitly
A useful internal state machine distinguishes transaction uncertainty from failure. The following names are illustrative application states, not Paddle API status values:
created: the purchase exists but funds are not reserved.reserved: funds are held and submission can proceed.submitted: a submission attempt has started or been acknowledged.pending: the final delivery outcome is not yet known.succeeded: authoritative confirmation supports finalizing the debit.failed: a definitive unsuccessful outcome supports releasing funds.review_required: conflicting evidence or prolonged uncertainty needs investigation.
Persist the submission attempt before making the external request. This helps recovery workers recognize that a crashed process might already have contacted the provider.
A timeout is not a failed top-up
If the connection drops after submission, avoid immediately creating another purchase. First query the original transaction using the documented reference or status lookup mechanism.
Use provider-side idempotency only if the endpoint documents it. Local duplicate protection remains essential: bind a customer’s purchase intent to one internal reference and reject conflicting reuse of that reference.
If safe resubmission semantics are unclear, escalate or continue status resolution rather than guessing. A second request can deliver a second top-up even when your first response never arrived.
Process status updates and reconciliation safely
If the integration supports webhooks, verify their authenticity using the documented method before processing them. Do not assume a signature header, algorithm, or event schema.
Persist accepted events before acknowledging them, then process them asynchronously. Make processing idempotent so repeated notifications cannot finalize a debit twice.
Handle out-of-order events through explicit transition rules. An old pending notification should not overwrite confirmed success. Conflicting final outcomes should trigger investigation rather than silent balance changes.
Where status polling is supported, use bounded retries with backoff and respect documented rate limits. Run a reconciliation worker to find purchases that remain unresolved or whose ledger state disagrees with their confirmed service outcome.
Design refunds and support around evidence
A failed purchase with reserved funds usually needs a reservation release, not a new credit. A purchase already debited may require a compensating ledger entry after a confirmed reversal. Confusing these paths can credit the customer twice.
Do not promise automatic reversals for completed airtime or data delivery. Establish the applicable provider process and distinguish a delivery complaint from a confirmed failed transaction.
Give support teams one transaction timeline showing submission attempts, provider references, status checks, and ledger movements. Require an auditable reason and appropriate approval for manual financial adjustments.
Customer messaging should be equally precise. “Processing—please do not retry yet” is more useful than displaying “Failed” when the actual outcome is unknown.
Practical launch checklist
Test the complete purchase lifecycle before enabling production traffic:
- Confirm the contract: document supported products, required fields, status meanings, lookup options, and reversal procedures.
- Protect credentials: keep API keys server-side and separate test credentials from production credentials.
- Test duplicate intent: double-click checkout, replay requests, and submit from two devices.
- Test uncertain outcomes: simulate connection loss and a process crash during submission.
- Test balance integrity: run simultaneous purchases against a balance that can fund only one.
- Test status processing: replay notifications and deliver them out of order where applicable.
- Test catalogue changes: remove a product or change its price between selection and confirmation.
- Verify recovery: ensure reconciliation identifies unresolved purchases without issuing duplicate top-ups.
Monitor pending transaction age, duplicate attempts, lookup failures, and mismatches between purchase outcomes and ledger entries. Choose escalation thresholds based on documented service expectations rather than an arbitrary timer.
Build it with Paddle
Paddle brings bills and VAS together with virtual accounts, payouts, ledgers, and other infrastructure for African digital businesses. Start by confirming the supported airtime and data products, then implement one reliable purchase journey before expanding your catalogue.
Paddle is a banking-as-a-service platform by Pickpadi Global Ltd, not a bank. Banking services are provided by CBN-licensed partner banks.
Ready to build? create a free account and read the API docs to validate the available services and map your transaction lifecycle to the documented integration.
Keep reading
Virtual Account Provisioning API for Nigerian Fintechs: Build a Safe Account Lifecycle
Build a reliable virtual account provisioning flow for Nigerian customers, from eligibility checks and duplicate prevention to account restrictions and closure.
Payment Webhook Security for Nigerian Fintechs: A Developer Guide
Build a secure webhook pipeline for Nigerian payment products, from authenticity checks to replay protection and recovery. Learn how to connect Paddle events to controlled business workflows without trusting every incoming request.
Double-entry ledger integration for Nigerian fintechs: Build Auditable Wallet Balances
Build wallet balances that remain explainable through pending transfers, reversals and reconciliation. This guide covers ledger design, posting rules and a practical Paddle integration checklist.
Paddle Build Studio
Want us to build it with you?
Build for Africa and the world. Our team can deliver your fintech, web or mobile product in 2–3 weeks — or integrate Paddle APIs and build it yourself.