Aller au contenu

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.

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.

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 :

  1. du webhook payment.succeeded signé, ou
  2. d’un GET /v1/payments/{id} qui renvoie status: "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
  • GET /v1/payments/{id}
  • GET /v1/payments?limit=20&status=succeeded&starting_after=pay_… — du plus récent au plus ancien, limit de 1 à 100 (20 par défaut) ; has_more indique s’il faut récupérer la page suivante en passant le dernier identifiant dans starting_after.
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