Skip to Content
Bill payments

Bill payments

Pay electricity, cable TV, and betting wallet funding using the same Transactions API as airtime and data. Authentication headers are unchanged.

Bill products use the unified transaction model:

productUse msisdn as
ELECTRICITYMeter number (prepaid or postpaid)
CABLESmartcard / IUC number
BETTINGCustomer ID on the betting platform

Sync (recommended) on the internal platform API (Bearer token, separate host) returns the final outcome in one response. External POST https://api.subthingy.io/v1/transactions (merchant key) is async — poll Check status with your request_ref.

Contact your account manager to enable bill products and betting on your merchant profile.

Plan catalog

Each bill product is identified by a numeric plan_code (Intelligent catalog id). Provider service codes are resolved server-side — you never send eBills service_id or variation_id.

List plans:

GET /v1/plans/bills/{product}

{product} is electricity, cable, or betting. Optional filter: ?network=IKEDC (electricity) or ?network=DSTV (cable).

curl "https://api.subthingy.io/v1/plans/bills/electricity?network=IKEDC" \ -H "X-Merchant-Key: mk_your_key_id" \ -H "X-Merchant-Secret: your_issued_secret"

HTTP 200:

{ "status": "2000", "description": "Operation Successful-BILLS-ELECTRICITY", "data": [ { "id": 1001, "name": "Ikeja Electric Prepaid", "network": "IKEDC", "product": "ELECTRICITY", "amount_type": "variable" }, { "id": 1002, "name": "Ikeja Electric Postpaid", "network": "IKEDC", "product": "ELECTRICITY", "amount_type": "variable" } ] }
FieldDescription
idPass as plan_code on verify and purchase
amount_typevariable (you set amount) or fixed (amount is set from catalog)
pricePresent on fixed cable bouquets

Electricity networks (network)

networkProvider
IKEDCIkeja Electric
EKEDCEko Electric
AEDCAbuja Electric
IBEDCIbadan Electric
EEDCEnugu Electric
KEDCOKano Electric
JEDJos Electric
PHEDPort Harcourt Electric
BEDCBenin Electric
ABEDCAba Electric
KAEDCOKaduna Electric
YEDCYola Electric
ABAAba Power

Cable networks (network)

networkService
DSTVDStv
GOTVGOtv
STARTIMESStarTimes

Betting networks (network)

networkOperator
BET9JABet9ja
SPORTYBETSportyBet
1XBET1xBet
BETKINGBetKing
BETWAYBetWay
NAIRABETNairaBet
MERRYBETMerryBet
BANGBETBangBet

Betting is opt-in per merchant. Contact support if your profile is not enabled.

Verify customer (optional)

Customer verification runs automatically before purchase. To validate a meter or smartcard without creating a transaction, use the platform API (Bearer token):

POST /v1/transactions/verify

External tenants may skip this step and proceed directly to purchase.

Body (platform API):

{ "product": "ELECTRICITY", "network": "IKEDC", "msisdn": "45012345678", "plan": "1001" }

No request_id on verify.

Pay electricity (async, external)

POST /v1/transactions
curl -X POST "https://api.subthingy.io/v1/transactions" \ -H "Content-Type: application/json" \ -H "X-Merchant-Key: mk_your_key_id" \ -H "X-Merchant-Secret: your_issued_secret" \ -d '{ "merchant": "YOUR_MERCHANT", "msisdn": "45012345678", "network": "IKEDC", "product": "ELECTRICITY", "plan_code": "1001", "amount": "5000", "request_ref": "subthingy-bill-ikeja-001" }'
FieldRequiredDescription
merchantYesYour merchant profile
msisdnYesMeter number
networkYesDisCo code (e.g. IKEDC)
productYesELECTRICITY
plan_codeYesCatalog id from plans
amountYesPayment amount in Naira (string)
request_refYesYour unique idempotency key

HTTP 200 — pending (poll status):

{ "status": "pending", "response_code": "02", "response_message": "Pending", "data": { "internal_reference": "019262ab-7c4d-7000-8000-000000000010", "msisdn": "45012345678", "product": "ELECTRICITY", "request_id": "subthingy-bill-ikeja-001", "network": "IKEDC", "amount": "5000", "plan": "1001", "merchant_id": 10 } }

When the payment completes, status polling may include token and units for prepaid electricity:

{ "state": "success", "code": "00", "message": "Successful", "payload": { "product": "ELECTRICITY", "request_id": "subthingy-bill-ikeja-001", "msisdn": "45012345678", "network": "IKEDC", "amount": "5000", "token": "1234-5678-9012-3456-7890", "units": "45.2 kWh" } }

Pay cable TV (async, external)

Same route as electricity. Example — DStv Compact (plan_code 3015):

curl -X POST "https://api.subthingy.io/v1/transactions" \ -H "Content-Type: application/json" \ -H "X-Merchant-Key: mk_your_key_id" \ -H "X-Merchant-Secret: your_issued_secret" \ -d '{ "merchant": "YOUR_MERCHANT", "msisdn": "1234567890", "network": "DSTV", "product": "CABLE", "plan_code": "3015", "amount": "10500", "request_ref": "subthingy-bill-dstv-001" }'

For fixed bouquets, amount must match the catalog price (or omit mismatch by using the price returned from the plans list).

Pay betting wallet (async, external)

curl -X POST "https://api.subthingy.io/v1/transactions" \ -H "Content-Type: application/json" \ -H "X-Merchant-Key: mk_your_key_id" \ -H "X-Merchant-Secret: your_issued_secret" \ -d '{ "merchant": "YOUR_MERCHANT", "msisdn": "08012345678", "network": "BET9JA", "product": "BETTING", "plan_code": "9001", "amount": "1000", "request_ref": "subthingy-bill-bet9ja-001" }'

Check status

Same endpoint as airtime and data:

GET /v1/transactions/status/{request_ref}

See Transactions — Check status.

List transactions

Bill payments appear in the standard transaction list:

GET /v1/transactions?page=1&limit=20

Filter by product in your integration layer using the product field on each row (ELECTRICITY, CABLE, BETTING).

Last updated on