Skip to main content
A user paying with her smartphone: bill payment built into an app
Bill Payment

Integrating bill payment into your app: the integrator's guide

7 min read

In short

  • Bill payment is one of the most frequent services in a financial app: electricity, water, telecom, public services and other receivables.
  • Chari Money's API covers the journey end to end: billers, receivables, dynamic form, unpaid bills, preview, confirmation, status, receipt and webhooks.
  • Three golden rules: build the form from the API's response, never show a failure before the final notification, and always display the settlement reference on the receipt.
  • For a merchant who simply wants to pay its own bills, the journey is already available in a payment platform's portal: no integration needed.

Why integrate bill payment

Paying a bill comes back every month. For an app, it is a reason to be opened regularly, far more than a one-off payment. It is also an expected service in a wallet: a balance you cannot use for your bills is only half useful.

Our article on online bill payment in Morocco presents the service from the user's side. Here, we take the side of the technical team integrating it into an app, a super app or an agent network, under its own brand, with Chari Money's value-added services module.

One clarification before starting: if you are a merchant who only wants to pay its own bills from the money of its sales, you have nothing to integrate. ChariPay, the payment platform operated by Chari Money, lets you pay bills from your payment account directly in its portal.

Prerequisites

Before the first call, three things must be in place:

  1. A valid sandbox API key, sent in the Chari-Api-Key header, with a unique request identifier in C-Request-Id for tracing.
  2. The bill payment module enabled for your partner account by the Chari Money team. Without activation, the calls fail.
  3. An existing end user, identified by their phone number in international format, and test float for debit operations.

The step-by-step guide, with sample requests and responses, is in the API documentation. This article explains its logic and its pitfalls.

The journey in six steps

StepWhat your app doesWhat the API returns
1. BillersShow the list of available billersThe active billers for your account, with their code
2. ReceivablesShow the chosen biller's servicesThe biller's receivables (bill, fees, tax...)
3. FormBuild the input screenThe schema of the fields to display
4. Unpaid billsSend the entered identificationThe unpaid items, the total amount and a transaction reference
5. Preview and confirmationLet the user pick items, then confirmThe payment result and the settlement reference
6. TrackingShow the status and the receiptThe status, the operation identifier, the receipt file

1. List the billers

The API returns the active billers your account has access to, filtered according to your contract. Each biller carries a four-digit code you will reuse. Since the list is relatively stable, caching it for a few hours on the partner side is acceptable.

2. List the receivables

A biller may expose several receivables, each corresponding to a type of service: bill, connection fees, tax... The receivable code is always two positions long.

3. Build the identification form

This is the step most often done wrong. For each biller and receivable pair, the API returns the list of fields to display: label, type, format, minimum and maximum sizes, required or optional. Your screen must be built from this response, never hard-coded, or it will break when a new biller arrives. "Label" fields are static help text: display them, but never send them back in the next request.

4. Retrieve the unpaid bills

You send the values entered by the user. Watch the name of the property expected in the request, which differs from the one in the responses: the API guide flags it explicitly. This call opens the transaction and returns a 12-digit reference to keep for the confirmation; the link remains valid for seven calendar days.

The response lists the unpaid items: receivable, fees, mandatory items, stamp duty. Some technical parameters with an empty label must never be shown to the customer.

5. Preview, then confirm

The user chooses to settle everything or to select certain items: partial payment is supported. You can first validate the request body with the preview call, which accepts exactly the same body as the confirmation without executing the payment. Then you confirm.

Two responses need particular attention. A code indicating an already processed transaction must be treated as a success: show the receipt. And some codes returned by the digital channel are not final failures: the transaction stays authorized and its final outcome arrives by webhook.

6. Track the transaction and deliver the receipt

A transaction's status is read from its reference; it also returns the Chari Money operation identifier, which lets you download the receipt file. The receipt must show the settlement reference returned at confirmation. The user's paginated payment history is also available.

Listening to webhooks

Bill payment is partly asynchronous. The module emits four events: payment confirmed, canceled, refunded or failed. Notifications arrive as a POST with the X-Api-Key header, the secret key you provide to Chari Money.

Answer 200 OK within five seconds. Any non-2xx code triggers a retry: after 1 minute, 5 minutes, 30 minutes, 60 minutes, then every six hours up to 72 hours in total. Your processing must therefore be idempotent: the same notification may arrive more than once.

Errors to plan for

  • 401: the API key is not authorized; check the header and the environment, keys being specific to each.
  • Missing parameter: a required field is missing, phone number, biller, receivable or the array of entered values.
  • No bill to pay: the lookup finds no unpaid item, which is not a technical error; plan a clear message.
  • Required field missing: a mandatory field of the dynamic form was not sent.

Building the user experience

A good integration is judged on screen. Show the customer name returned with the unpaid bills so the user confirms it is their contract. Show the item detail and the total before confirmation. After payment, display the receipt immediately with the settlement reference, and keep it accessible in the history.

Bill payment combines naturally with telecom top-ups and vouchers, which follow the same preview-then-confirm model. For a project that is just starting, our guide to launching a fintech in Morocco helps choose the order of services.

On the merchant side: collecting rather than paying

An app that lets its users pay their bills must not be confused with a merchant that wants to get paid for its own. A school, a practice or a shop that invoices its customers needs the opposite: sending a payment request. For that, ChariPay offers payment links, shared as a link, QR code, email or WhatsApp, with no integration.

Next step

To enable the bill payment module in the sandbox, see the partner API documentation and request your access from the documentation page. For a production launch, adding bill payment is prepared as a use case in its own right, with the Chari Money team.

Frequently Asked Questions

How do you integrate bill payment into an app?
With Chari Money's API, in six stages: list the billers, list their receivables, build the identification form from the API's response, retrieve the customer's unpaid bills, preview then confirm the payment, and finally track the transaction and deliver the receipt. The module is enabled for your partner account by the Chari Money team.
Why not hard-code the input form?
Because each biller and receivable pair has its own fields: label, type, format, size and whether it is required. The API returns that schema and your screen must be built from it, to stay compatible with new billers. Label-type fields are static text and must never be sent back.
Can the customer pay only part of the unpaid bills?
Yes, partial payment is supported: the user selects the items they want to settle among the unpaid bills returned by the API, then you confirm with that selection. You can also settle all unpaid bills at once.
What if the confirmation does not return an immediate success?
Some return codes on confirmation are not final failures: the transaction stays authorized and its final outcome is notified by webhook. So do not show the customer a failure before the notification, and treat the already-processed code as a success, showing the receipt.
How long does the link to the unpaid bills remain valid?
Retrieving the unpaid bills opens a transaction and returns a 12-digit reference to keep for the confirmation. That link remains valid for seven calendar days. Beyond that, the lookup must be run again.
Is an authorization needed to offer bill payment?
Offering payment services is a regulated activity. With Chari Money, the partner is subject to Bank Al-Maghrib's approval, through principal agent status, and adding bill payment as a new use case requires the prior approval of the Banking Supervision Directorate.