Skip to main content
All articles
Guide13 min read

Getting invoices paid online: a payment link on every invoice, from QR code to reminder

Payment link on invoice: one single-use link per invoice, a printed QR code, email delivery, status tracking and reminders that never cause a double payment.

A payment link on invoice is how you get invoices paid online: every invoice you issue gets its own single-use link, for its amount. Your customer opens the link or scans its printed QR code and lands on that link's page, where they pay by card with 3-D Secure — or, on a link created without an expiry, choose cash at an agency; the link then turns "Paid" in your portal. This is not about paying your own bills, but about being paid for the invoices you send your customers, businesses or individuals. This guide covers creating the link, the QR code, sending, tracking, follow-ups without double payments and matching.

Getting invoices paid online, not paying your own

Let us clear up the ambiguity first: this article is about the invoices you issue, the ones your customers have to pay you. To pay your own bills — water, electricity, phone — from your balance, read about paying bills from your payment account instead.

A second clarification: ChariPay generates neither your invoices nor their PDFs. You keep producing them in your usual tool — invoicing software, ERP, spreadsheet — with your own numbering and wording. ChariPay adds what a paper or PDF invoice lacks: a way to pay it right away, online. ChariPay is a Moroccan payment platform, a PSP operated by Chari Money, a payment institution licensed by Bank Al-Maghrib. The payment link that goes with the invoice is described on the payment links page.

If you ask for part of the price before the work, the logic is different: one link goes out with the quote, another on delivery. That is the subject of our guide to collecting a deposit. Here, the work is delivered, the invoice is issued: what is left is getting paid.

The rule fits in one sentence: one invoice, one single-use link, for the amount due shown on the invoice. The link is consumed after one successful payment, which rules out the same invoice being paid twice through that link. Four settings make it a good invoice link:

  • The description repeats the invoice number: "Invoice FAC-2026-0457". The customer knows what they are paying; you find the invoice in the portal.
  • The expiry follows the due date: 24 hours, 7 days, 30 days or an exact date. An invoice payable at thirty days calls for a link that expires on the due date. This expiry applies to a link to be paid by card: for a customer who pays in cash, create the link with "Agency payment", without an expiry.
  • The customer is saved: their details serve for sending by email and for your next invoices.
  • Through the API, the `externalId` is the invoice number: a replayed creation with the same externalId returns the existing link with 200 instead of creating a second one. Your invoicing tool can therefore retry the call with no risk of a duplicate.
bash
curl -X POST 'https://api-psp.charipay.ma/v1/payment-links' \
  -H 'X-CHARI-PAY-API-KEY: chari_sk_test_...' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: invoice-fac-2026-0457' \
  -d '{
    "amount": 1800.00,
    "description": "Facture FAC-2026-0457",
    "singleUse": true,
    "expiresAt": "2026-11-01T23:59:59Z",
    "externalId": "FAC-2026-0457",
    "customerEmail": "amine.bennani@example.com",
    "metadata": { "invoiceNumber": "FAC-2026-0457" }
  }'

The response carries the link's reference (pl_…) and its payUrl: keep the first next to the invoice in your tool, and print the second, or its QR code, on the invoice. What the invoice must state otherwise — taxes, required wording, payment terms — is a matter for your tool and your advisor.

To see what your customer will receive, try it on a dummy invoice. Test mode opens as soon as your account is activated, with no approval to wait for: Start in test mode — three fields (name, work email, company), an activation link received by email to choose your password, then the portal, where you create your own test key after re-authenticating; the full key is shown only once. Create the invoice's link, open it and pay with the test card 4918 9141 0719 5005, CVV 123, any future expiry date, 3-D Secure code 555: only this card is accepted, and no real money moves. Your business verification (KYB) runs in parallel and only gates the move to production.

Printing the QR code on the invoice

An invoice is often read on paper, or as a PDF opened on a device other than a phone. The QR code bridges the gap: GET /v1/payment-links/{reference}/qr returns a PNG image that encodes the address of the link's payment page. Insert it into your invoicing tool's template, next to the amount and the invoice number, with a short line: "Scan to pay this invoice online."

The customer scans, lands on the page of this invoice's link — with your name, your logo, the amount and the description — and pays. For a PDF invoice read on screen, also add the payUrl as a clickable link: the customer then does not even need their phone.

On the automation side, the sequence takes three moves: create the link, fetch its QR code, insert it into the invoice PDF. The QR code belongs to a single-use link specific to this invoice: it is not reused from one invoice to the next. Other uses of QR codes — counter posters, stands — are covered in our guide to QR code payments.

There are two ways to get the link to the customer, and they can be combined.

Through your own channel: you send the invoice as usual — from your tool's email, on WhatsApp, by post — with the link or the QR code in it. That sharing is your move: ChariPay does not send your payment link by SMS or WhatsApp.

Through ChariPay's email: POST /v1/payment-links/{reference}/send sends the link by email and returns 202. With no body, the email goes to the customer address saved on the link; with an email field, to the address you provide — for example your business customer's accounts department.

bash
curl -X POST 'https://api-psp.charipay.ma/v1/payment-links/pl_3ND8xk/send' \
  -H 'X-CHARI-PAY-API-KEY: chari_sk_test_...' \
  -H 'Content-Type: application/json' \
  -d '{ "email": "amine.bennani@example.com" }'

This email carries the payment link, not your invoice: the invoice itself goes out through your tool. The same sending is available from the portal. The parameters of each call are in the Payment links module of the API docs.

Tracking the status of each invoice

The link's status tells you where the invoice stands. There are four: active, paid, canceled, expired.

Link statusWhat it says about the invoiceYour action
ActiveIssued, not yet paidWait for the due date, follow up if needed
PaidPaid onlineMark it paid in your tool
CanceledThe link was deactivated: invoice canceled or paid another wayNothing, other than checking why it was canceled
ExpiredThe link's due date passed with no paymentFollow up with a new link

When a payment comes in, you are notified in the portal. On the server side, GET /v1/payment-links/{reference} returns the link's state: in code, test status against "ACTIVE" to know whether the link can still be paid, and read useCount to know whether it has been paid. Your invoicing tool can thus update each invoice without manual entry.

Following up on an unpaid invoice with no risk of double payment

No reminder goes out from a link on its own: you follow up, at the pace your terms set. Three situations come up.

  1. 1The link is still active: send it again, with POST /v1/payment-links/{reference}/send or through your own channel, with a message that repeats the number, the amount and the due date. It is the same link: no risk of double payment.
  2. 2The link has expired: create a new link, with a new externalId — for example FAC-2026-0457-R1 — and the same invoice metadata. Replaying the old externalId would return the existing, expired link with 200.
  3. 3You want to replace a link that is still active (corrected amount, new due date): cancel the old one first — a canceled link can no longer be paid — then send the new one.

A reminder template that works, short and factual:

Hello, invoice FAC-2026-0457 is now due. You can pay it online, by card, with this link.

Keep in your tool the list of invoices whose link has expired: that is your follow-up list. Subscription installments, for their part, have their own reminder cycle: see unpaid subscriptions and reminders.

Customers who pay in cash or by bank transfer

Not all of your customers will pay by card, and that is fine: the same invoice link and your account cover the other two cases.

In cash. On the page of a single-use payment link, your customer chooses cash, receives a reference, pays it at an agency of the Chari network, and you are notified as soon as the network confirms the deposit. Cash payment at an agency always relies on a single-use link — one reference per deposit. In the portal, turning on "Agency payment" on a link disables its expiry: the link stays payable with no time limit. A link with an expiry date is therefore presented as a link to be paid by card; for a customer who pays in cash, create a link with "Agency payment", without an expiry. As soon as the network confirms the deposit, the link turns "Paid" and you are notified in the portal; on the server side, read the link's state with GET /v1/payment-links/{reference}. ChariPay is the only payment gateway in Morocco that also collects cash at agencies.

By bank transfer. Many business customers pay by transfer. Your ChariPay account is a real payment account, held by Chari Money, a payment institution licensed by Bank Al-Maghrib, opened in your company's name, with a RIB in that name and a PDF certificate to download from the portal or through the API. It receives your collections and incoming transfers. ChariPay is not a bank: your payment account is held by Chari Money. It complements your bank; it does not replace it. You can therefore show that RIB on your invoices; the account's framework is explained on the payment account in Morocco page, and the documents that come with it in our article on the payment account RIB certificate.

When a customer has paid by transfer, cancel the invoice's link: it can no longer be paid, and you avoid a second payment by card.

Matching every payment to its invoice

Matching is prepared when you create the link, by choosing what will come back to you.

  • Your `metadata` — here invoiceNumber — is returned verbatim in the card payment event and on every read of the link: it is the most reliable key for finding the invoice.
  • The link's `reference` (pl_…), kept in your tool next to the invoice, lets you read the link again at any time.
  • The `externalId` is read on the link, with GET /v1/payment-links/{reference}; do not count on it in the payment event, find the invoice through your metadata.

On the accounting side, every account movement carries the reference of the sale, refund or payout that explains it; the portal separates amount paid, fees and net, and the CSV export keeps those references — from the portal or with GET /v1/transactions/export.csv (up to 10,000 rows; beyond that, split by period with from/to). Timestamps are in UTC; Morocco is UTC+1: your reconciliation tool must convert. The day-to-day method, from the usual gaps to exports, is detailed in reconciling your collections.

Frequently asked questions

In the ChariPay portal, or through the API, create a single-use payment link for the invoice amount, with its number as the description and an expiry on the due date. Then add the link, or its QR code obtained with GET /v1/payment-links/{reference}/qr, to your invoicing tool's template, next to the amount. The customer pays online and the link turns "Paid".

Can ChariPay generate my invoices?

No. ChariPay generates neither invoices nor invoice PDFs: you produce them in your usual tool, with your own numbering and wording. ChariPay provides the payment method that goes with the invoice: a single-use link, its QR code, sending the link by email and tracking its status. Rules specific to the invoice itself are a matter for your tool and your advisor.

How do I follow up with a customer who has not paid their invoice?

If the link is still active, send it again, by email with POST /v1/payment-links/{reference}/send or through your own channel, with a message repeating the number, the amount and the due date. No reminder goes out automatically: you set the pace. If the link has expired, create a new one with a new externalId and the same invoice metadata.

Create a new single-use link for the same amount, with a new externalId, for example the invoice number followed by a reminder suffix, and the same metadata. Replaying the old externalId would return the expired link, with 200, instead of creating a fresh one. Then send the new link to the customer and choose a new, realistic expiry.

How do I keep an invoice from being paid twice?

Use one single-use link per invoice: it is consumed after one successful payment. Through the API, use the invoice number as the externalId, so that a replayed creation returns the existing link. Before sending a replacement link, cancel the old one, and also cancel the link if the customer paid by transfer: a canceled link can no longer be paid.

Can a customer pay an invoice in cash?

Yes, on a single-use link created with "Agency payment", without an expiry. On its page, the customer chooses cash, receives a reference and pays it at an agency of the Chari network. As soon as the network confirms the deposit, the link turns "Paid" and you are notified in the portal. The amount is then available in your payment account, and the invoice is settled.

Can my customer pay the invoice by bank transfer?

Yes. Your payment account, held by Chari Money and opened in your company's name, has a RIB in that name and receives incoming transfers: you can show it on your invoices. It complements your bank; it does not replace it. When the transfer arrives, match it to the invoice and cancel the corresponding link, so it can no longer be paid by card.

How do I know which invoice a payment settled?

Through your metadata, for example invoiceNumber, returned verbatim in the card payment event and on every read of the link. Also keep the link's reference next to the invoice in your tool. The externalId is read on the link, not in the event. The CSV export then lists every payment with its reference, amount, fees and net.

Next step

In test mode, add the link or its QR code to your tool's invoice template, pay a dummy invoice with the test card, then check the matching in the export: Start in test mode. For the stage before the invoice, see how to go about collecting a deposit, and keep the payment links page for the full offer.

Written by ChariPay team.

Read next

Ready to try it yourself?

Create your account and take test-mode payments today: it is free, with no approval to wait for. A question? Our team supports merchants and developers alike.

  • Free, no commitment
  • Test mode from sign-up
  • No approval to wait for