Paiements
Un paiement est une demande d’argent adressée à un client. Vous le créez sur votre serveur, le client paie sur la page de paiement hébergée avec Wave ou Orange Money, et Xaalis vous communique le résultat par webhook.
stateDiagram-v2
[*] --> requires_payment_method: POST /v1/payments
requires_payment_method --> processing: le client choisit Wave / Orange Money
requires_payment_method --> expired: 30 min sans paiement
processing --> succeeded: le prestataire confirme
processing --> failed: refusé / annulé / montant différent
succeeded --> [*]
failed --> [*]
expired --> [*]
succeeded, failed et expired sont des statuts finaux. Un paiement réussi peut ensuite passer en refunded par
un remboursement : rien d’autre ne modifie un paiement final. Un paiement
échoué ne peut pas être relancé : créez-en un nouveau (avec une nouvelle Idempotency-Key).
POST /v1/payments avec une clé secrète. Envoyez une Idempotency-Key pour qu’une nouvelle tentative
ne puisse pas créer deux paiements.
| Champ | Obligatoire | Remarques |
|---|---|---|
amount |
oui | entier en XOF, de 100 à 100 000 000. Les nombres à virgule, les chaînes et 0 sont refusés (400). |
currency |
non | uniquement "XOF" (la valeur par défaut) |
description |
non | 200 caractères au plus, affichée au client sur la page de paiement |
client_reference |
non | votre numéro de commande (100 caractères au plus), renvoyé sur le paiement et dans les webhooks |
success_url, cancel_url |
non | où la page de paiement renvoie le client une fois le paiement dans un état final — utilisez https:// |
customer |
non | { phone: "+2217XXXXXXXX", name } |
metadata |
non | chaîne → chaîne, clés de 40 caractères au plus, valeurs de 500 au plus. Jamais montrées au client. |
provider |
non | "wave" ou "orange_money" : saute le choix du moyen de paiement ; next_action est prêt dans la réponse |
La réponse est l’objet paiement avec status: "requires_payment_method" et une checkout_url.
Redirigez le client vers cette URL.
La page de paiement hébergée
Section intitulée « La page de paiement hébergée »checkout_url contient un secret client (cs=…) qui permet au navigateur de voir uniquement ce dont le client a
besoin : montant, description, nom de votre entreprise, statut. Elle n’expose jamais vos frais, metadata,
client_reference ni les identifiants. Traitez cette URL comme un mot de passe : ne la journalisez pas et ne
l’envoyez pas à vos outils d’analyse d’audience.
Quand le client choisit un moyen de paiement :
- Wave →
next_action: { type: "redirect", url }: la page de paiement l’envoie vers Wave. - Orange Money →
next_action: { type: "qr_code", qrCodeBase64, deeplinks }: un QR code pour Max It / Orange Money et des liens directs vers l’application sur mobile.
Si vous avez fixé provider à la création, vous pouvez utiliser next_action vous-même au lieu de la page de paiement
hébergée.
La redirection ne prouve rien
Section intitulée « La redirection ne prouve rien »Après avoir payé, le client revient sur votre success_url. Cela ne prouve rien : n’importe qui peut ouvrir cette
URL. Ne livrez la commande que sur la base :
- du webhook
payment.succeededsigné, ou - d’un
GET /v1/payments/{id}qui renvoiestatus: "succeeded"(appelé depuis votre serveur).
fee = ceil(amount × fee_bps / 10 000) + fee_fixed, plafonné à amount. Par défaut 150 points de base (1,5 %), sans
partie fixe ; votre contrat peut prévoir autre chose. net = amount − fee est ce qui arrive dans available.
| montant | frais à 1,5 % | net |
|---|---|---|
| 100 | 2 | 98 |
| 1 001 | 16 | 985 |
| 15 000 | 225 | 14 775 |
Consulter et lister
Section intitulée « Consulter et lister »GET /v1/payments/{id}GET /v1/payments?limit=20&status=succeeded&starting_after=pay_…— du plus récent au plus ancien,limitde 1 à 100 (20 par défaut) ;has_moreindique s’il faut récupérer la page suivante en passant le dernier identifiant dansstarting_after.
L’objet paiement
Section intitulée « L’objet paiement »| Champ | Signification |
|---|---|
id |
pay_… |
livemode |
false pour les clés de test |
amount, fee, net, currency |
entiers en XOF |
status |
voir le diagramme ci-dessus |
provider |
wave, orange_money, mock (test) ou null tant que le client n’a pas choisi |
checkout_url, next_action |
où le client paie |
client_reference, description, customer, metadata |
ce que vous avez envoyé |
failure_reason |
par exemple declined_or_cancelled, amount_mismatch, expired |
provider_transaction_id |
l’identifiant de la transaction Wave / Orange Money, une fois le paiement effectué |
expires_at, succeeded_at, created_at |
ISO 8601 |