Le paiement
Étape 4 — Le paiement de l'acheteur
Entre « l'acheteur a viré l'argent » et « la facture est marquée payée », il y a une étape invisible mais essentielle : le rapprochement bancaire.
Le mouvement bancaire (BankMovement) : la brique universelle
Tout flux d'argent — entrant ou sortant, Ponto ou MangoPay — est représenté par un mouvement bancaire (enregistrement d'un flux d'argent : un virement reçu, un paiement carte, un remboursement, un reversement vendeur… C'est l'objet pivot entre la banque et les factures) avec :
- un type :
IN(argent qui entre),OUT(argent qui sort),INTERNAL(mouvement interne plateforme),TRANSFER; - un montant, une devise, une date ;
- la communication (
remittanceInformation) : le texte du virement, idéalement la référence structuréeXXX/XXXX/XXXXX; - un statut qui suit son traitement.
Le cycle d'un paiement entrant :
flowchart LR
a["NEW"] --> b["LINKED"]
b --> c["MATCHED"]
c --> d["SETTLED"]
| Statut | Signification |
|---|---|
| NEW | Le mouvement vient d'être créé (synchronisé depuis Ponto, ou créé par un webhook MangoPay). Personne ne sait encore à quelle facture il correspond. |
| LINKED | Un lien provisoire vers une ou plusieurs factures a été posé (objet BankMovementInvoice avec le montant affecté à chaque facture). |
| AUTO_MATCHED / MANUAL_MATCHED | Le rapprochement est confirmé : automatiquement (montant + référence + IBAN concordants) ou à la main par un comptable dans l'admin. C'est ce qui déclenche le passage de la facture à PAID. |
| SETTLED | Le mouvement est définitivement réconcilié avec la transaction bancaire réelle. |
Pour les mouvements sortants (reversements, remboursements), le cycle est : SUBMITTED (préparé) → EXECUTED (envoyé à la banque / à MangoPay) → SETTLED (confirmé) — ou REJECTED en cas d'échec. Autres statuts : DRAFT, IGNORED (mouvement volontairement écarté, ex. frais bancaires), SIGNED (legacy Ponto), PENDING, CANCELLED.
Le lettrage / rapprochement : comment on marie paiement et facture
L'algorithme de suggestion (« guess ») croise plusieurs critères :
- le montant du virement = montant dû de la facture (avec tolérance) ;
- la communication structurée (la référence
XXX/XXXX/XXXXXest décodée — formatsSTRUCTUREDISO 20022,STRUCTURED_BEbelge+++xxx/xxxx/xxxxx+++, ou texte libreUNSTRUCTUREDnettoyé) ; - la date (proche de l'échéance) ;
- l'organisation (le payeur correspond à l'acheteur ; côté MangoPay, l'IBAN virtuel crédité identifie directement l'acheteur).
Un virement peut couvrir plusieurs factures (le cas normal en facturation double : un seul virement règle la SALES et la BUYER_FEES grâce à la référence partagée). Les comptables disposent dans l'admin des actions LINK / UNLINK / MANUAL_MATCH / AUTO_MATCH / UNMATCH / IGNORE.
Cas imparfaits
| Situation | Ce qui se passe |
|---|---|
| Trop-perçu (a payé 1 050 € au lieu de 1 000 €) | Le rapprochement automatique échoue (montants différents) → traitement manuel ; l'excédent est remboursé via un avoir/remboursement. |
| Paiement partiel (500 € sur 1 000 €) | Le mouvement est lié partiellement : amountPaid = 500 €, amountDue = 500 € ; la facture n'est pas encore PAID. Relance de l'acheteur. |
| Pas de référence / référence fausse | Suggestion par montant + organisation + date ; sinon lettrage manuel. |
| Jamais payé | Après l'échéance : action NO_PAY (manuelle ou NO_PAY_AUTO) → facture et item NOT_PAID, emails d'impayé, et éventuels frais d'annulation (BUYER_CANCELLATION_FEES_NOT_PAID). |
auctelia-models/src/schemas/BookKeeper/BankMovementInvoice.js (mouvement ↔ facture ↔ montant). Suggestions : book-keeper/src/controllers/invoices/guess.js et book-keeper/src/controllers/bankMovements/guess.js ; contrôle des montants : book-keeper/src/helpers/isBankMovementAmountCorrectForInvoice.js ; décodage des communications : book-keeper/src/helpers/parseRemittanceInformation.js. Sync bancaire : Ponto (API) pour les comptes du shop. Écrans admin : admin-frontend/src/pages/bank-movements/*.vue (liste, détail, match-list) et admin-frontend/src/pages/invoices/*.vue (liste, détail avec mouvements liés/suggérés, workflow).Les deux circuits d'encaissement en pratique
- L'email de confirmation d'achat contient soit une URL de paiement carte (3-D Secure), soit l'IBAN virtuel personnel de l'acheteur chez MangoPay ;
- Carte : une PaymentRequest (demande de paiement portant les factures et le montant) initie le PayIn ; le rapprochement est immédiat et certain (on sait exactement quelles factures sont payées) ;
- Virement : l'acheteur vire sur son IBAN virtuel ; le webhook
PAYIN_NORMAL_SUCCEEDEDcrée le mouvementIN, et comme l'IBAN virtuel appartient à un seul acheteur, l'auto-rapprochement est très fiable ; - Facture →
PAID, l'argent attend dans le wallet, prêt pour la répartition (chapitre suivant).
- L'email de confirmation contient l'IBAN du shop et la communication structurée à recopier ;
- Les mouvements du compte du shop sont synchronisés régulièrement via Ponto (agrégateur bancaire) ;
- Le lettrage (auto ou manuel) marie le virement aux factures →
PAID; - Plus tard, le reversement vendeur partira du même compte : mouvements
OUTregroupés dans un fichier XML SEPA (Isabel) signé par la direction, puis exécutés par la banque.