Pay a Bill
Bill Payment
Pay a Bill
Pay one of the bills found by a discovery
POST
Pay a Bill
Overview
Pays a single bill from aREADY discovery. You choose one billId out of that transaction’s bills[]; the same transaction then carries the payment through to a final state.
This is the call that moves money. Everything you need on your own side — the order record, the amount, your customer’s authorisation — should already be persisted before you send it.
Request Body
string
required
The discovery to pay against. Must be a 24-character lowercase hexadecimal string, and the transaction must currently be
READY.string
required
The
billId of one entry in that transaction’s bills[]. Maximum 100 characters.Copy it from the response — do not construct it.string
required
A new reference for this payment. Maximum 100 characters, and unique among your live transactions for that partner.It must be different from the
ref you used for the discovery; reusing that value answers 403 DUPLICATED_REF.The transaction keeps the
ref it was created with. That original discovery ref is what this endpoint echoes back, what Get Transaction by Reference looks up, and what appears on the transaction from now on.Response
boolean
required
true when the payment was accepted.object
required
object
required
string
required
Correlation identifier, also sent as the
X-Request-Id response header.Examples
Success Response
SUCCESS, Get Transaction by ID returns operationId and receiptUrl alongside selectedBill and total.
Error Responses
400 — Validation error
400 — Validation error
The body did not match the schema.Common causes: a
transactionId that is not 24 hexadecimal characters, a missing billId, a missing ref, or a ref longer than 100 characters.What to do: fix the request. Never retry it unchanged.401 — Missing or invalid access token
401 — Missing or invalid access token
The key was absent or rejected.What to do: verify the key with Validate API Key. Nothing was charged.
403 — Duplicate reference
403 — Duplicate reference
The The most common cause is reusing the discovery
ref is already in use for this partner.ref on the payment. Send a distinct value, for example pay- in front of your order identifier.What to do: before retrying, check the transaction’s current state with Get Transaction by ID. If it is already PROCESSING, your payment went through and there is nothing to resend.404 — Not found or not payable
404 — Not found or not payable
The transaction does not exist for your account, or it is not in a payable state, or that All three cases answer
billId is not one of its bills.404 — including a transaction that belongs to another partner, so the API never confirms that someone else’s transaction exists.What to do: re-read the transaction. If its status is no longer READY, the payment has already been started; poll it instead of sending another one.409 — Bill already paid
409 — Bill already paid
This exact bill was already paid.What to do: treat it as a successful outcome that you already have. Find the paid transaction in List Transactions and use its receipt. Do not charge your customer twice.
409 — Payment in progress
409 — Payment in progress
Another payment for the same bill has not finished.What to do: poll the transaction that is already running. Sending this again will not make it finish sooner.
500 — Internal error
500 — Internal error
Something failed on our side.What to do: do not resend the payment. Read the transaction first — if it is
PROCESSING, the payment is running. Contact support with the requestId if the state is unclear.What you pay
Every bill in a discovery carries its own money fields.
The fee is a percentage of the amount, clamped between a minimum and a maximum, set per biller:
Because 0.5% of a typical bill is well under the minimum, most payments are charged exactly the minimum. These rates are configuration and can be adjusted, so read
fee from the response rather than recomputing it. total appears on the transaction once a bill has been selected.
For the 443.39 DZD ADE bill above: 0.5% is 2.22, which is below the 30 DZD minimum, so fee is 30.00 and total is 473.39.
Before you call
1
Persist your own record first
Write your order — customer,
transactionId, billId, amount, fee, total and the ref you are about to use — before the request leaves your process. If the response is lost, that record is how you find the payment again.2
Confirm the amount with your customer
amount and fee come from the discovery. Show the total you are about to charge, not an estimate.3
Send the payment
One call, with a
ref that is new for this partner.4
Poll until final
SUCCESS, FAILED or REFUNDED. Treat UNKNOWN as “keep polling”, never as a failure.→ Status pollingThe guards that protect you
Three rules stop the same money moving twice. All three answer before anything is charged.Best Practices
Write before you send
Persist your order record, including the
ref, before the request. A lost response is then recoverable.One ref per call
Use a distinct
ref for the discovery and for the payment. disc- and pay- in front of your order identifier is enough.Never resend on a timeout
Read the transaction first. A network timeout does not mean the payment did not happen.
Charge from total
Debit your customer the
total the API returned, never a figure you calculated yourself.Related Endpoints
Discover Bills
Find what is payable
Get Transaction by ID
Poll the outcome
Download Receipt
Proof of payment
Get Transaction by Reference
Recover a lost response
Paying Bills
The full walkthrough
Status Polling
A production-grade poller

