How to create a payment link: every setting, from the portal to the API
How to create a payment link step by step: amount, expiry, sharing, statuses, then the same link through the API — single-use or reusable — no duplicates.
How to create a payment link? It comes down to a handful of settings: an amount in dirhams, a description, an expiry, then, if you want, a saved customer and the "Agency payment" option; the reusable link, for its part, is created through the API. The ChariPay portal gives you back a single-use link to share — by message, email, QR code or poster — and tells you when it has been paid. This guide reviews every setting, from the portal to the API: what it does, when to pick it, the mistakes that cost you a double payment or a lost customer, and the single call that creates the same link from your code without ever creating it twice.
Creating a payment link: what you need before you start
A payment link is an amount and a description; the customer pays on a page hosted by ChariPay. ChariPay is a Moroccan payment platform, a PSP operated by Chari Money, a payment institution licensed by Bank Al-Maghrib. To create a link, you need neither a website nor a developer: only access to the portal.
To follow this guide hands-on, a test-mode account is enough. 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. Pay your test links 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. Test mode is free, with no time limit and no commitment.
Two other reads complement this one without repeating it: the payment links page presents the offer, and the article on payment link or checkout helps you choose between a link and a checkout session built into your website. Here, the link is the choice: what remains is to set it up well.
Creating a payment link in the portal, step by step
In the portal, everything starts from the "Payment links" screen, which lists the links you have already created along with their status.
- 1Open the portal's payment links and start creating a new link.
- 2Enter the amount in dirhams (MAD) and the description the customer will read on the page: what is being sold and your internal reference.
- 3Keep it single-use for a specific sale: the link is consumed after one successful payment. The reusable link, for one amount paid by several customers, is covered further down.
- 4Choose the expiry: 24 hours, 7 days, 30 days, never, or an exact date.
- 5Attach a saved customer if you wish: you then find their details again for your next links.
- 6Turn on "Agency payment" if you know the customer will pay in cash: this option disables the link's expiry, and 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.
- 7Create the link and copy it, or display its QR code, to share it.
The new link appears in the list with an active status. Everything is in Moroccan dirhams (MAD): collections, balances, transfers and payouts, with no conversion. If you get the amount wrong before the payment, do not improvise: cancel that link and create a new one.
A link's settings, field by field
| Field | What it does | Tip |
|---|---|---|
| Amount | Sets the sum to pay, in dirhams (MAD) | The exact total, delivery included: an amount corrected after payment forces you to claim or refund a difference |
| Description | The text the customer reads on the page; 255 characters at most through the API | What is sold plus your reference (order, quote, invoice): it is what you will search for in the portal |
| Single-use or reusable | One payment, or several payments of the same amount; from the portal, the link is single-use, and the reusable link is created through the API | Single-use as soon as the customer or the amount changes |
| Expiry | 24 hours, 7 days, 30 days, never, or an exact date | Align it with how long your offer is valid |
| Saved customer | Attaches the link to a customer and their contact details | Reusable for the same customer's next links |
| Agency payment / preselected method | In the portal, "Agency payment" removes the expiry; through the API, paymentMethod preselects card (default) or cash | Cash only on a single-use link, without an expiry |
The description deserves more attention than it usually gets. The customer reads it at the moment of paying: "Order #1042 — 2 gift boxes" reassures more than a vague label. And it is how you will find the link in the portal, then the movement in your exports. A simple rule lasts: what is sold, then your order, quote or invoice number.
Single-use or reusable: what the choice changes
A single-use link carries a sale: one order, one customer, one amount. It is consumed after one successful payment, which rules out a customer paying twice for the same order. It is also the only link that opens up cash: on its page, the customer chooses between card and cash at an agency. Cash payment at an agency always relies on a single-use link — one reference per deposit. The full mechanics, from reference to deposit, are explained in our guide to collecting cash at an agency.
A reusable link carries a price: the same amount, paid by as many customers as needed until it expires or is canceled — a membership fee, a ticket, a best-selling product. It takes card payments only. It is the link that goes on a poster, in a social media bio or on a page of your website. From the portal, every payment link you create is single-use. The reusable link — one amount paid by several customers — is created through the API, with singleUse: false; once created, it shows up in the portal like the others. Without a developer, to sell several times at the same price, publish a product on your hosted storefront and share its link.
When in doubt, choose single-use: a reusable link sent to a single customer works, but it stays payable after being paid, and it shuts the door on cash.
Sharing the link where your customer reads you
A link is shared as a link, a QR code, a printable PDF poster, by email or WhatsApp. Pick the channel where the sale already closes:
- Link to copy: in a WhatsApp conversation, a direct message, a text message or an email you write yourself. The text message is your move: ChariPay does not send your payment link by SMS or WhatsApp.
- Email: from the portal, or through the API with
POST /v1/payment-links/{reference}/send, which returns202and sends the link to the saved customer or to the address you provide. - QR code and PDF poster: for a counter, a stand or a printed document. How to use them — where to put them, which link to print — is detailed in our guide to QR code payments.
Always send the link with a sentence that repeats the amount and what is being sold: the customer then finds on the page exactly what they just read.
Tracking, canceling and customizing a link
Every link has a clear status: active, paid, canceled, expired. When a payment comes in, you are notified in the portal, and the list shows where each link came from — dashboard or API — so you do not mix up your team's links with your website's.
| Status | What it means | What you do |
|---|---|---|
| Active | The link can be paid | Share it, follow up with the customer if needed |
| Paid | The single-use link has been paid | Deliver, ship or confirm the service |
| Canceled | You deactivated it: it can no longer be paid | Create a new one if the sale resumes |
| Expired | Its expiry date has passed | Create a new one if the customer still wants to pay |
To cancel a link, use the portal, or the API with POST /v1/payment-links/{reference}/cancel. A canceled link can no longer be paid: always cancel the old link before sending another one for the same sale.
On the customer's side, a link's page shows your name and your logo; you set it up from your account settings.
Creating the same link through the API
One call is enough: POST /v1/payment-links returns the payUrl to share. There is a single base URL, https://api-psp.charipay.ma, in test as in production: the key selects the environment. Amounts are in major units (149.90 = MAD 149.90).
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: order-1042-link' \
-d '{
"amount": 149.90,
"description": "Commande #1042",
"singleUse": true,
"externalId": "order-1042",
"customerEmail": "amine.bennani@example.com",
"customerPhone": "+212600000000",
"metadata": { "cartId": "c_987" }
}'The 201 response — or 200 if a link already existed with that externalId — carries the link's reference (pl_…) and its payUrl, the address to send to the customer. For a reusable link, set singleUse to false: it then takes card payments only. The metadata, a flat object, comes back to you verbatim when you read the link and in the payment event: it is how your system finds the order again.
For a link to be paid in cash, add paymentMethod: "CASH" and keep singleUse set to true:
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: order-1043-link' \
-d '{
"amount": 320.00,
"description": "Commande #1043",
"singleUse": true,
"paymentMethod": "CASH",
"externalId": "order-1043",
"customerPhone": "+212600000000",
"metadata": { "orderNumber": "1043" }
}'The code to present at the agency (cashinCode) and the deposit entity (cashinEntity) are not in the creation response: they are generated when the payment page is first opened and can then be read with GET /v1/payment-links/{reference}. On that read, test status against "ACTIVE" to know whether the link is still open, and read useCount and totalCollected to know what it has collected. The other calls — list, cancel, send, QR, poster — are described in the Payment links module of the API docs.
Never creating the same link twice
The classic scenario: your server sends the creation request, the connection drops before the response, your code retries. Without precautions, your customer receives two links for one order. Two tools prevent this.
- The `externalId` field: your identifier, unique per account and per environment. A creation with an existing
externalIdreturns the existing resource with200 OKinstead of201 Created. Both are successes: check the status, and do not treat the200as an error. - The `Idempotency-Key` header: replaying the same value returns the first result; the same key with a different body returns
409 IDEMPOTENCY_CONFLICT. It is scoped to the account: keep separate keys for sandbox and production.
The practical consequence: an externalId you have already used will always return the same link, even if it has expired or been canceled. For a new link on the same order, give it a new externalId (order-1042-2, for example). The principle, and its limits, are developed in our article on payment idempotency.
Frequently asked questions
How do I create a payment link to be paid in cash?
Create a single-use link with "Agency payment" in the portal — without an expiry — or through the API with paymentMethod: "CASH" and singleUse set to true. The customer receives a reference on the page, pays it at an agency of the Chari network, and the link turns "Paid" as soon as the network confirms the deposit. A reusable link, by contrast, accepts card payments only.
Which expiry should I choose for a payment link?
The one that matches your offer. 24 hours for a sale closed in a conversation, 7 or 30 days for a quote or an invoice, an exact date for a seasonal offer, never for a permanent poster. Once it passes, the page tells the customer the offer is no longer available, and no payment can go through: if they still want to buy, create a new link.
How do I know a payment link has been paid?
When the payment comes in, you are notified in the portal and the single-use link turns "Paid". Through the API, GET /v1/payment-links/{reference} returns, among other fields, useCount and totalCollected, and the card payment event sends your metadata back to you. Never rely on a screenshot sent by the customer: only the link's status, in your portal or read through the API, counts.
How do I cancel a payment link I have already sent?
From the portal, or through the API with POST /v1/payment-links/{reference}/cancel. A canceled link can no longer be paid, even if the customer still has it in their conversation: if they open it, they will not be able to pay. Let them know, and send them the new link if the sale goes on. Always cancel the old link before sending another one for the same sale.
Can I save a customer to send them more links?
Yes. Save your customers and their contact details in the portal: you then attach them to your next links without retyping anything. Through the API, a link also carries customerName, customerEmail and customerPhone. The saved email is used, among other things, when the link is sent with POST /v1/payment-links/{reference}/send and you provide no other address.
Can I show my logo on the payment page?
Yes. A link's page shows your name and your logo, and you set this up from your account settings. Your customer therefore sees, on a page hosted by ChariPay, the business they are paying, the amount and the description, before entering their card and confirming with 3-D Secure.
Can I create a payment link through the API?
Yes: one call is enough, POST /v1/payment-links returns the payUrl to share. The required fields are amount and description; singleUse, paymentMethod, expiresAt, the customer's details, externalId and metadata are optional. A chari_sk_test_… test key creates test links, payable with the test card, on the same https://api-psp.charipay.ma base.
What happens if the same link creation is sent twice?
With the same externalId, the second creation returns the existing link with 200 OK instead of 201 Created: no duplicate is created. With the same Idempotency-Key, the first result is replayed; the same key with a different body returns 409 IDEMPOTENCY_CONFLICT. With neither, two separate links are created, and your customer may receive both of them.
Next step
Open your test account — Start in test mode — then create your first link in the portal, pay it with the test card, and create the same link through the API with your test key and an externalId. To go further, print its QR code with our guide to QR code payments, or sell in conversations with our method for selling on Instagram and WhatsApp.
Written by ChariPay team.