Paiements
Le fonctionnement des paiements
Intentions de paiement, tentatives, les statuts que traverse un paiement, et le signal auquel se fier avant de livrer.
Sur cette page
Chaque paiement, par carte ou en espèces, est une intention de paiement (payment intent) : un
objet pour un montant à encaisser, de sa création jusqu’à l’argent reçu. Vous la créez vous-même, ou
une session de paiement ou un lien de paiement la crée pour vous. Son status dit où elle en est ;
votre code le lit au lieu de le deviner.
Intentions de paiement et tentatives
Une intention de paiement peut être tentée plusieurs fois. Chaque essai est une tentative,
aussi appelée charge (ch_…) : une page de paiement par carte ouverte, ou un code espèces émis.
Une carte refusée ou un code expiré termine la tentative, pas l’intention de paiement : votre client
peut réessayer, avec le même moyen ou un autre.
- Le
latest_chargede l’intention nomme sa tentative la plus récente. - Une intention de paiement réussit une seule fois. Même si une confirmation nous parvient
plusieurs fois, il y a un seul succès, un seul événement
payment_intent.succeededet une seule écriture dans votre solde. amount_receivedest fixé quand le paiement réussit ;amount_refundedaugmente à chaque remboursement.
Le cycle de vie
- requires_payment_method → requires_action: page carte ou code espèces
- requires_action → processing: client a payé
- processing → succeeded: confirmé, montant exact
- requires_action → requires_payment_method: refusé, échoué ou expiré
- processing → requires_payment_method
- requires_payment_method → canceled: annulé ou expiré
- requires_action → canceled: vous annulez
Un paiement par carte confirmé tout de suite peut aussi passer directement de requires_action à
succeeded.
Chaque statut, et que faire
| Statut | Ce qu’il signifie | Ce que vous faites |
|---|---|---|
requires_payment_method | Rien n’est en cours de paiement : le paiement vient d’être créé, ou la dernière tentative a échoué. | Envoyez votre client payer, ou laissez-le réessayer. last_payment_error dit pourquoi la dernière tentative a échoué. |
requires_action | Votre client doit agir : terminer sur la page de paiement par carte, ou payer le code espèces chez un agent. | Attendez. Avec votre propre page, affichez next_action (voir plus bas). |
processing | Votre client a payé ; la confirmation est en route. | Attendez le webhook. Ne livrez pas encore. |
succeeded | Le paiement est confirmé et le montant correspond. | Livrez la commande. C’est définitif. |
canceled | Vous avez annulé le paiement, ou sa session de paiement a expiré sans paiement. | Rien : aucun argent ne circule. Créez un nouveau paiement si votre client revient. |
Quand quelque chose ne colle pas
Si un paiement est confirmé pour un autre montant que celui demandé, ou si de l’argent arrive après
l’annulation du paiement ou l’expiration de son code, rien n’est crédité automatiquement.
L’intention de paiement reste en processing et reçoit un objet review, avec reason à
amount_mismatch ou paid_after_end, et vous recevez review.opened. Une personne de notre équipe
l’examine. Dans le bac à sable, les scénarios espèces permettent de
déclencher les deux.
Tentatives
Le status d’une tentative vaut pending, succeeded, failed, canceled ou expired. Une
tentative échouée porte failure_code et failure_message, et l’intention les recopie dans
last_payment_error :
| Code | Moyen | Ce qui s’est passé |
|---|---|---|
card_declined | Carte | La banque a refusé. decline_code peut préciser, par exemple insufficient_funds. |
expired_card | Carte | La carte a expiré. |
authentication_failed | Carte | Le 3-D Secure n’a pas abouti. |
processing_error | Carte, espèces | Le paiement n’a pas pu être traité. Votre client peut réessayer. |
voucher_expired | Espèces | Le code n’a pas été payé avant son échéance. |
voucher_refused | Espèces | Le réseau de paiement a refusé le code. |
Une tentative a une durée de vie limitée : environ 30 minutes pour une page de paiement par carte,
et l’échéance du code pour les espèces (environ trois jours). Une tentative arrivée à son terme
finit expired.
Actions suivantes
Tant qu’une intention de paiement est en requires_action, son next_action dit ce que votre client
doit faire. Avec la page hébergée ou un lien de paiement, vous ne le lisez jamais : nos pages s’en
chargent. Avec votre propre page :
form_post, pour une carte : une adresse et des champs que le navigateur de votre client envoie pour atteindre la page de paiement par carte.display_voucher, pour les espèces : lecode, l’amount_to_pay(votre montant plus un petit droit de timbre payé par votre client),expires_at, unslip_urlimprimable, ethosted_voucher_url, notre page du bon.
Montants et devise
- Chaque montant est un entier en centimes :
25000vaut 250,00 MAD. N’envoyez jamais de décimales. currencyvaut toujoursmad, en minuscules.- Un paiement en espèces vaut au moins 100,00 MAD (
10000) ; un paiement par carte au moins 1,00 MAD (100). Un montant inférieur est refusé avecamount_too_small, en mode test comme en production.
Redirections et webhooks : auquel se fier
Votre client revient sur votre success_url après avoir payé, mais ce retour ne prouve rien : il
peut fermer l’onglet avant, un paiement en espèces se fait des jours plus tard chez un agent, et
n’importe qui peut taper l’adresse.
Livrez sur l’un de ces deux signaux seulement :
- le webhook
payment_intent.succeeded, avec une signature vérifiée ; - l’intention de paiement lue dans l’API, avec votre clé secrète, qui montre
status: "succeeded".
Servez-vous du retour pour remercier votre client et afficher « Nous confirmons votre paiement » ; laissez ensuite le webhook faire le reste.
Remboursements
Un paiement par carte réussi peut être remboursé, en totalité ou en partie, tant que le total
remboursé ne dépasse pas le montant reçu. Un remboursement est pending, puis succeeded, failed
ou canceled. Un paiement en espèces ne peut pas être remboursé par AdProMaxPay : l’argent a été
remis en espèces, et il n’y a pas de carte sur laquelle le rendre. Réglez-le directement avec votre
client. Voir Remboursements.
Les événements que vous recevez
| Événement | Quand |
|---|---|
payment_intent.requires_action | Une page carte a été ouverte ou un code espèces émis. |
payment_intent.processing | Votre client a payé ; la confirmation est en route. |
payment_intent.succeeded | Le paiement est confirmé. Livrez. |
payment_intent.payment_failed | Une tentative a échoué : refusée, expirée ou rejetée. |
payment_intent.canceled | Le paiement a été annulé. |
charge.succeeded, charge.failed | Une tentative a réussi ou échoué. |
review.opened | Quelque chose ne colle pas ; rien n’a été crédité. |
La liste complète est dans Webhooks.