Skip to main content

Introduction

Bill Payment lets you pay Algerian utility and telecom bills on behalf of your own customers. You ask a biller what an account owes, you pay one of the bills that comes back, you follow it to a final state, and you keep the receipt. The whole product is five calls. This page is the map; each step below links to a guide with working code in cURL, Node.js, Python and PHP.
Bill Payment lives on https://billapi.oneclickdz.com — a different base URL from the rest of the platform. The authentication header is the same one you already use: X-Access-Token.

How it works

The five steps

1

Check the biller is available

Read the availability map and hide any biller that is UNAVAILABLE before your customer starts filling in a form.Step 1: Partners and accounts
2

Discover what is owed

Send the partner, the account identifier and your own ref. You get a transactionId back; the bills arrive on that transaction a moment later.Step 2: Discovering bills
3

Pay one bill

Pick a billId from bills[], show your customer amount + fee, and submit the payment with a new ref.Step 3: Paying bills
4

Poll until the status is final

SUCCESS, FAILED or REFUNDED. UNKNOWN means keep polling — never refund your customer and never retry the payment while it lasts.Step 4: Status polling
5

Store the receipt and reconcile

Download the receipt, store it with operationId, and reconcile daily against your own ledger.Step 5: Receipts and reconciliation

What you need to know

Everything is asynchronous

POST /v3/bills/discover and POST /v3/bills/pay both answer 200 immediately. That 200 means accepted, not done.
A 200 from pay does not mean the bill was paid. The real outcome only ever appears in the transaction’s status. Design your integration around polling from the first line of code — retrofitting it later is how customers get charged twice.

The billers and their identifiers

Five billers, each with one identifier field. Send the field that belongs to the partner; the API returns the same field back on every transaction. SEAAL and AADL are currently UNAVAILABLE in both sandbox and production. Read the availability map rather than hard-coding this. Identifier rules, formats and examples

The seven statuses

The full state machine and a production-grade poller

Fees and the 200 DZD floor

Every bill carries its own money fields:
  • amount — what the biller is owed, in DZD.
  • fee — the OneClickDz service fee, a percentage of the amount clamped between a minimum and a maximum, set per biller: In practice most bills pay the minimum: 0.5% only exceeds 30 DZD above a 6,000 DZD bill. These rates are configuration and can be adjusted, so read fee from the response rather than recomputing it.
  • totalamount + fee, the figure debited from your balance.
Bills below 200 DZD are filtered out during discovery and never appear in bills[]. A READY transaction with an empty bills[] therefore means either “nothing is due” or “everything due is below the floor” — the API does not distinguish. Tell your customer “no bills are payable right now”, not “you owe nothing”.

Your reference is your safety net

ref is required on both discover and pay, is at most 100 characters, and must be unique among your live transactions for that biller. Reusing one answers 403 DUPLICATED_REF. Derive it from something you already store, so that after a timeout you can always ask what that ref became instead of sending the request again.
Use a different ref for the discovery and for the payment. The transaction keeps its original discovery ref, and that is the one by-ref looks up.

Sandbox

Sandbox uses the same host, the same routes, the same envelope and the same lifecycle. The only difference is that a sandbox key never reaches a biller and never moves money. The outcome you get is chosen by the account identifier you send, so you can reproduce a decline, a refund and an unconfirmed payment on demand. Every key is bound to one environment. Call Validate API Key and read key.type to prove which one you are holding. Every sandbox scenario, and a go-live checklist

Key points

Both write endpoints accept the work and answer immediately. The result lives in the transaction’s status.Step 4: Status polling
UNKNOWN means the outcome is not confirmed yet. Keep polling — it resolves to SUCCESS or REFUNDED. Refunding your own customer or resending the payment while it lasts is how money is lost twice.Handling UNKNOWN
Every timeout, every DUPLICATED_REF, every unexplained failure is answered by looking the ref up. A second write is never the right recovery.Step 2: Discovering bills
Fees are configured per partner and can change. Charge your customer the total the API returned, never a figure you calculated.Step 3: Paying bills
A transaction that is not yours — or that belongs to the other environment — returns 404, never 403. The API never confirms that someone else’s transaction exists.Get Transaction by ID

API Reference

Validate API Key

GET /v3/validate

List Partners

GET /v3/partners

Discover Bills

POST /v3/bills/discover

Pay a Bill

POST /v3/bills/pay

Get Transaction by ID

GET /v3/bills/transactions/id

Get Transaction by Reference

GET /v3/bills/transactions/by-ref

List Transactions

GET /v3/bills/transactions

Download Receipt

GET /v3/bills/transactions/id/receipt

Start integrating

Begin with Step 1: Partners and accounts

Check availability and learn the identifier rules for each biller

Additional resources

Authentication

Keys, headers and environments

Response Format

The envelope every endpoint returns

Error Handling

Every error code and what to do about it

Polling Strategies

Intervals, backoff and ceilings

Security Best Practices

Protect your keys and your customers

Contact Support

Get help from our team