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:
product | Use msisdn as |
|---|---|
ELECTRICITY | Meter number (prepaid or postpaid) |
CABLE | Smartcard / IUC number |
BETTING | Customer 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"
}
]
}| Field | Description |
|---|---|
id | Pass as plan_code on verify and purchase |
amount_type | variable (you set amount) or fixed (amount is set from catalog) |
price | Present on fixed cable bouquets |
Electricity networks (network)
network | Provider |
|---|---|
IKEDC | Ikeja Electric |
EKEDC | Eko Electric |
AEDC | Abuja Electric |
IBEDC | Ibadan Electric |
EEDC | Enugu Electric |
KEDCO | Kano Electric |
JED | Jos Electric |
PHED | Port Harcourt Electric |
BEDC | Benin Electric |
ABEDC | Aba Electric |
KAEDCO | Kaduna Electric |
YEDC | Yola Electric |
ABA | Aba Power |
Cable networks (network)
network | Service |
|---|---|
DSTV | DStv |
GOTV | GOtv |
STARTIMES | StarTimes |
Betting networks (network)
network | Operator |
|---|---|
BET9JA | Bet9ja |
SPORTYBET | SportyBet |
1XBET | 1xBet |
BETKING | BetKing |
BETWAY | BetWay |
NAIRABET | NairaBet |
MERRYBET | MerryBet |
BANGBET | BangBet |
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/verifyExternal 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/transactionscurl -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"
}'| Field | Required | Description |
|---|---|---|
merchant | Yes | Your merchant profile |
msisdn | Yes | Meter number |
network | Yes | DisCo code (e.g. IKEDC) |
product | Yes | ELECTRICITY |
plan_code | Yes | Catalog id from plans |
amount | Yes | Payment amount in Naira (string) |
request_ref | Yes | Your 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=20Filter by product in your integration layer using the product field on each row (ELECTRICITY, CABLE, BETTING).