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. Le client peut également choisir de recevoir son reçu de paiement et le suivi de commande par WhatsApp (receipt_opt_in: true). - 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.
Changement de moyen de paiement
Section intitulée « Changement de moyen de paiement »Si un client choisit Wave puis souhaite changer d’opérateur, la page hébergée lui permet de basculer vers Orange Money après expiration de la session Wave initiale. Pour éliminer tout risque de double prélèvement, le basculement depuis une session Orange Money active est strictement refusé par l’API (409 invalid_state).
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 |