Skip to main content

1. A bill-payment checkout

The whole service in one flow, with the confirmation step where it belongs.
The totalDebit in step 2 is what actually leaves the account. Showing amount instead is how a customer ends up surprised by the charge.

2. Airtime, in one fewer step

Airtime is the one product that does not need a package.
Two things differ from a utility bill:
  • The customer id is the phone number, normalised for you.
  • The recipient comes from the enquiry, not from the phoneNumber in the payment body. Getting the number right matters at enquiry time.
Data bundles do need a package, and their price is fixed by it — send an amount that disagrees and you get bill_amount_mismatch.

3. A vend that has not resolved

submitted and pending are normal. The money has left; the biller has not finished.
Never resubmit a pending payment. The account has already been debited, and a second payment under a new reference buys the value twice.
Better still, let the webhook drive it:

4. Reconcile a day of bills

Remember the page shape here: totalPages, and no hasNext. Loop while page < totalPages.

5. Tell the two telco billers apart

A telco appears as a separate biller under Airtime and under Data, with disjoint packages and different ids. Browse the group you mean, and keep the biller id you got from it:
Passing a biller id to a group it does not belong to 404s, so a mismatched pair fails loudly rather than quietly buying the wrong thing.

What you cannot do here

  • Cancel or refund a payment. A failure refunds itself; a success is final.
  • Pay in any currency but NGN.
  • Pay a biller outside the catalog.
  • Re-issue a token. Store it when it arrives.
  • Extend an enquiry. Make a new one.