Bills
Fetch and pay real-time bills (utilities, telecom, tuition, and more) with an OTP-verified fetch flow.
REST over HTTPS with JSON requests and responses. Intended for authorized distributors.
Two-step flow: Fetch Bill returns the amount to pay (some billers require a provider OTP first), then Pay Bill settles it using the exact billId and baseAmount returned by fetch.
Authentication & headers
Every request must include the HTTP headers below, plus Content-Type: application/json on requests that send a body.
| Header | Description |
|---|---|
sessionId | Value provided by Whish. |
token | Value provided by Whish. |
language | Always set to en. |
User-Agent | Identifies your app. Use your own details, not Whish's. Format: AppName/version (website; contact-email). Example: AcmeStore/2.1 (https://acme.example; dev@acme.example). |
Environments
| Environment | Base URL | Purpose |
|---|---|---|
| Sandbox | https://api.sandbox.whish.money/itel-service/api | Testing, QA, integration verification. |
| Production | https://api.whish.money/itel-service/api | Live environment for real transactions. |
Response format
All endpoints return HTTP 200 with Content-Type: application/json and a shared envelope. Always branch on the status field in the body, not the HTTP status code.
| Field | Type | Description |
|---|---|---|
status | Boolean | true = success · false = failure. |
code | String | Operation-specific failure code; null on success. |
dialog | Object | Optional title / message to display to the user. |
data | Object | Response payload for the operation; shape varies per endpoint. |
actions / extra | Object | Reserved; typically null. |
Account balance
Returns the real and void balances of the account. The void balance represents voided items (sold but unused, held for later).
No parameters. Each session (sessionId) is tied to a single currency, so the balance is always returned in that session's currency. To work in both LBP and USD, use a separate session for each.
{
"status": true,
"code": null,
"dialog": null,
"extra": null,
"data": {
"balanceDetails": {
"balance": -217.718,
"voidBalance": 0.0
}
}
}Response fields
| Field | Type | Description |
|---|---|---|
balance | Double | The real balance of the account. |
voidBalance | Double | The void balance of the account. |
Fetch bill
Fetches a bill. For most denominations this is a two-step, OTP-verified flow; selected denominations skip OTP.
Request body
| Field | Type | Description |
|---|---|---|
denominationId | int | Identifier of the product/biller. |
target | String | Bill target (e.g. subscriber phone number). |
verificationId | int | OTP session ID from Step 1; include only in Step 2 with otp. |
otp | int | One-time password sent by the carrier; required in Step 2. |
Standard flow: OTP first
Treat code = bill.requires_provider_otp as an expected challenge, not an error. Persist verificationId = data and prompt the user for the OTP. Sandbox fixed values: verificationId = 6789, otp = 1234.
{
"denominationId": 53001,
"target": "971555555555"
}{
"status": false,
"code": "bill.requires_provider_otp",
"dialog": {
"title": "Verification required",
"message": "Please enter the OTP sent by the provider."
},
"actions": null,
"extra": null,
"data": 6789
}{
"denominationId": 53001,
"target": "971555555555",
"verificationId": 6789,
"otp": 1234
}{
"status": true,
"code": null,
"dialog": null,
"actions": null,
"extra": null,
"data": {
"billId": 1220,
"target": "0555555555",
"baseAmount": 19.0,
"additionalAmount": -0.0,
"totalAmount": 19.0,
"allowPayAll": true,
"minAmount": 19.0,
"maxAmount": 19.0,
"amountIncrement": 0.0
}
}Alternative flow: no OTP (selected denominations)
{
"denominationId": 54001,
"target": "971555555555"
}{
"status": true,
"code": null,
"dialog": null,
"extra": null,
"data": {
"billId": 1234,
"target": "971555555555",
"baseAmount": 30.40,
"additionalAmount": 1.60,
"totalAmount": 32.00,
"allowPayAll": true,
"minAmount": null,
"maxAmount": null,
"amountIncrement": null
}
}Pay bill
Pays the bill retrieved by Fetch Bill. Always pass the exact billId and baseAmount (as amount) returned by fetch.
Request body
| Field | Type | Description |
|---|---|---|
externalId | Long | Client-generated unique ID per payment attempt (idempotency). |
billId | Long | The billId returned by /bill/fetch. |
amount | Double | Must equal baseAmount from /bill/fetch. |
{
"externalId": 9876543210,
"billId": 1220,
"amount": 19.0
}{
"status": true,
"code": null,
"dialog": null,
"extra": null
}{
"status": false,
"code": "payment.failed",
"dialog": {
"title": "Error",
"message": "Payment failed"
},
"extra": null
}Error codes
| Code | Description |
|---|---|
bill.requires_provider_otp | OTP challenge (expected on fetch, not a failure). |
bill.fetch_failed | Bill fetch failed. |
payment.failed | Payment failed. |
Sandbox scenarios
| Denomination ID | Behavior |
|---|---|
53001 | Standard fetch & payment (requires provider OTP). |
54001 | Fetch & payment (no OTP). |
| Test target | Expected outcome |
|---|---|
971555555555 | Success path (fetch and pay). |
971555555554 | Fetch fails (bill.fetch_failed). |
971555555553 | Fetch succeeds; payment fails (payment.failed). |
Fixed sandbox OTP values: verificationId = 6789, otp = 1234.
Best practices
- Always include
sessionId,token,languageheaders. - Treat
bill.requires_provider_otpas a two-step flow, not an error; persistverificationId. - Use the exact
billIdandbaseAmountfrom fetch when paying. - Make
externalIdunique per payment attempt (client-side idempotency). - Normalize amounts to two decimals for display; preserve full precision internally.
- Handle transient failures with safe retries; on payment retry use a new
externalIdunless told otherwise.
Postman & tools
Import the ready-made Postman collection for this API, set your credentials as collection variables (or attach a sandbox / production environment), and call every endpoint without writing code.
⤓ Download collectionAll downloads & environments
In Postman: Import → select the file → choose the Sandbox or Production environment → fill in your credentials. Requests use {{baseUrl}} and the credential variables provided.