Skip to navigation

Bill payments

Pay utilities, government bills, and subscriptions
View as Markdown

Pay electricity, government control numbers, TV subscriptions, and other bills from your SenjaroPay merchant wallet.

Browse categories, confirm the customer account with a lookup, then settle the bill. All endpoints are POST to https://api.senjaropay.com and require x-api-key and x-api-secret.

How it works

1

List categories

Call categories to show the bill groups in your UI (utilities, government, TV, and more).

2

List billers

Pass a category_id to load the billers in that group. Each biller returns a utilityCode and the reference field your customer should enter.

3

Look up the account

When lookupAvailable is true, validate the meter, control number, or account before charging. Show the returned customer name for confirmation.

4

Pay

Send utility, utility_ref, and amount. Store data.transid from the response.

5

Check status

If the pay result is unclear, or you need to reconcile later, query status with transid.

Authentication

HeaderRequiredDescription
Content-TypeYesapplication/json
x-api-keyYesDashboard Public Key (Authentication)
x-api-secretYesSecret key. Server-side only.
POST /api/billPayments/categories HTTP/1.1
Host: api.senjaropay.com
Content-Type: application/json
x-api-key: <public_key>
x-api-secret: <secret>

1. List categories

POST https://api.senjaropay.com/api/billPayments/categories

No request body.

Response

{
"status": "success",
"code": 200,
"data": [
{
"id": 4,
"name": "Government Payments",
"icon": "Landmark"
},
{
"id": 1,
"name": "Utility Services",
"icon": "Lightbulb"
},
{
"id": 5,
"name": "Travel & Ticket Booking",
"icon": "Plane"
},
{
"id": 3,
"name": "Prepaid Internet",
"icon": "Globe"
},
{
"id": 2,
"name": "TV Subscriptions",
"icon": "Monitor"
},
{
"id": 6,
"name": "Investment & Pension Funds",
"icon": "LineChart"
}
]
}
FieldDescription
idPass as category_id when listing subcategories
nameDisplay name for the category
iconIcon key for your client UI
curl -sS -X POST "https://api.senjaropay.com/api/billPayments/categories" \
-H "Content-Type: application/json" \
-H "x-api-key: ${SENJARO_API_KEY}" \
-H "x-api-secret: ${SENJARO_API_SECRET}" \
-d '{}'

2. List subcategories

POST https://api.senjaropay.com/api/billPayments/subcategories

Request

{
"category_id": "4"
}
FieldTypeRequiredDescription
category_idstringYesid from the categories response

Response

data is keyed by category name. Each entry is a biller you can look up and pay.

{
"status": "success",
"code": 200,
"data": {
"Government Payments": [
{
"id": 11,
"utilityCode": "GEPG",
"refLabel": "Control No",
"refType": "Numeric(12)",
"refExample": "991234567891",
"lookupAvailable": true,
"description": "Government bill payment across supported agencies",
"logo": "https://cdn.example.com/bills/gepg.png"
}
]
}
}
FieldDescription
utilityCodePass as utility on lookup and pay
refLabelLabel for the customer reference input
refTypeExpected reference format
refExampleSample value for your UI
lookupAvailableWhen true, call lookup before pay
curl -sS -X POST "https://api.senjaropay.com/api/billPayments/subcategories" \
-H "Content-Type: application/json" \
-H "x-api-key: ${SENJARO_API_KEY}" \
-H "x-api-secret: ${SENJARO_API_SECRET}" \
-d '{"category_id":"4"}'

3. Look up an account

POST https://api.senjaropay.com/api/billPayments/lookup

Use this when the biller has lookupAvailable: true. Confirm the returned customer name with your payer before charging.

Request

{
"utility": "LUKU",
"utility_ref": "43036017606"
}
FieldTypeRequiredDescription
utilitystringYesutilityCode from the subcategory
utility_refstringYesMeter number, control number, or account ID

Response

{
"status": "success",
"code": 200,
"data": {
"lookup_transid": "LOOKUP_MOCK_7f3a91c2",
"transaction_id": "70effccb-2b9e-4b3f-8b47-c7fa873f1af3",
"utility": "LUKU",
"utility_ref": "43036017606",
"result": "SUCCESS",
"resultcode": "000",
"message": "LUKU Confirmation\nTest Customer\nMeter# 43036017606\n",
"lookup": [
{
"name": "Test Customer"
}
]
}
}
FieldDescription
result / resultcodeLookup outcome. SUCCESS / 000 means the account is valid
lookupCustomer details to show before payment
messageProvider confirmation text
curl -sS -X POST "https://api.senjaropay.com/api/billPayments/lookup" \
-H "Content-Type: application/json" \
-H "x-api-key: ${SENJARO_API_KEY}" \
-H "x-api-secret: ${SENJARO_API_SECRET}" \
-d '{"utility":"LUKU","utility_ref":"43036017606"}'

4. Pay a bill

POST https://api.senjaropay.com/api/billPayments/pay

Settles the bill from your merchant wallet. Store data.transid for status checks.

Request

{
"utility": "LUKU",
"utility_ref": "54205084277",
"amount": 2000,
"phone": "255700000001"
}
FieldTypeRequiredDescription
utilitystringYesutilityCode from the subcategory
utility_refstringYesSame reference used at lookup
amountintegerYesAmount in TZS
phonestringNoPayer MSISDN for the confirmation SMS. If omitted, SenjaroPay sends the SMS to the merchant phone on file

Response

{
"status": "success",
"code": 200,
"data": {
"transaction_id": "eef01eba-d42b-4ea3-9581-7778c75123aa",
"transid": "2dd9486c-bb19-4556-bade-482bf97a2b06",
"reference": "1949333867",
"utility": "LUKU",
"utility_ref": "54205084277",
"amount": 2000,
"currency": "TZS",
"result": "SUCCESS",
"resultcode": "000",
"message": "LUKU\nTest Customer\nMeter 54205084277\nUnits 5.6kWh\nToken 0105 6819 2412 0556 9485\nTOTAL TZS 2,000\nReference 1949333867"
}
}
FieldDescription
transidUse this on the status endpoint
referenceProvider payment reference
result / resultcodePayment outcome
messageReceipt text. Format varies by utility (tokens, units, fees)
curl -sS -X POST "https://api.senjaropay.com/api/billPayments/pay" \
-H "Content-Type: application/json" \
-H "x-api-key: ${SENJARO_API_KEY}" \
-H "x-api-secret: ${SENJARO_API_SECRET}" \
-d '{
"utility": "LUKU",
"utility_ref": "54205084277",
"amount": 2000,
"phone": "255700000001"
}'

5. Check status

POST https://api.senjaropay.com/api/billPayments/status

Use when the pay response is unclear, or to reconcile after a timeout.

Request

{
"transid": "2dd9486c-bb19-4556-bade-482bf97a2b06"
}
FieldTypeRequiredDescription
transidstringYesdata.transid from the pay response

Response

{
"status": "success",
"code": 200,
"data": {
"transaction_id": "eef01eba-d42b-4ea3-9581-7778c75123aa",
"transid": "2dd9486c-bb19-4556-bade-482bf97a2b06",
"reference": "1949333867",
"amount": "2000.00",
"currency": "TZS",
"payment_status": "SUCCESS",
"result": "SUCCESS",
"resultcode": "000",
"message": "LUKU\nTest Customer\nMeter 54205084277\nUnits 5.6kWh\nToken 0105 6819 2412 0556 9485\nTOTAL TZS 2,000\nReference 1949333867"
}
}
FieldDescription
payment_statusCurrent bill payment state
result / resultcodeProvider outcome codes
messageLatest receipt text from the provider
curl -sS -X POST "https://api.senjaropay.com/api/billPayments/status" \
-H "Content-Type: application/json" \
-H "x-api-key: ${SENJARO_API_KEY}" \
-H "x-api-secret: ${SENJARO_API_SECRET}" \
-d '{"transid":"2dd9486c-bb19-4556-bade-482bf97a2b06"}'

Errors

HTTP statusTypical error_codeWhen
400validation_errorMissing field, invalid amount, or unknown utility
401unauthorizedMissing or invalid x-api-key or x-api-secret
{
"status": "error",
"code": 400,
"error_code": "validation_error",
"message": "utility_ref is required"
}

Examples on this page are mock values. Keep API keys in server-side secrets.