Virements et relevés
Une caisse paie un praticien par un seul virement par jour, qui regroupe des dizaines de factures. Chaque retour de paiement l’annonce : Ophelix en fait un virement (Payout, po_…), avec ses paiements et ses retenues.
Le virement réellement reçu n’arrive pas par Ophelix : il se lit sur le relevé du compte du praticien. Déposez ce relevé, CSV de la banque ou camt.053 (BankStatement, bst_…), ou saisissez un virement reçu à la main : chaque crédit (BankTransaction, btx_…) se rapproche du virement qu’il règle, et les écarts sont signalés.
Droits de clé : batches:read et batches:write, comme les lots et les retours.
Je veux…
| Je veux… | Appel |
|---|---|
| Lister les virements d’un mois | GET /v1/payouts?accounting_date[gte]=2026-11-01 |
| Trouver les virements en écart | GET /v1/payouts?status=discrepancy |
| Lister les factures qu’un virement règle | GET /v1/claims?payout=po_… |
| Lister ses paiements et retenues | GET /v1/payments?payout=po_… |
| Déposer un relevé de compte | POST /v1/bank-statements |
| Saisir un virement reçu | POST /v1/bank-transactions |
| Voir les crédits qu’aucun virement n’explique | GET /v1/bank-transactions?status=unmatched |
| Pointer un virement à la main | POST /v1/payouts/{id}/reconcile |
| Simuler l’arrivée d’un virement | POST /v1/test-helpers/payouts/{id}/arrival |
Cycle de vie
| État | Ce qu’il dit |
|---|---|
pending | Annoncé par un retour, pas encore vu sur le compte |
reconciled | Un crédit du relevé lui répond au centime près, ou il a été pointé à la main (reconciliation: "manual") |
discrepancy | Un écart est signalé : discrepancies dit lequel |
Un virement en écart repasse à reconciled quand l’écart disparaît, par exemple quand un paiement qui attendait sa facture est rapproché à la main. Pointé à la main, il reste reconciled et garde ses écarts pour mémoire.
Ce que le retour dit du virement
label.line_1etlabel.line_2: le libellé du virement. La ligne 1 nomme souvent l’organisme qui paie.statement_descriptor: ce qu’il faut chercher sur le relevé, la ligne 2 quand elle existe, sinon le libellé entier. Le régime général la reprend dans le libellé SEPA.accounting_date: la date d’émission du virement. Il arrive sur le compte un à trois jours plus tard.amount_cents: le montant du virement.breakdownle détaille : liquidations, régularisations, paiements ponctuels, retenues (négatives).
Relevés
POST /v1/bank-statements prend le relevé en base 64, comme la banque l’exporte :
- CSV : une colonne de date, une ou plusieurs de libellé, et un montant signé ou un couple débit et crédit. L’en-tête se cherche dans les quinze premières lignes. Point-virgule, virgule ou tabulation ;
1 248,30comme1,248.30; UTF-8 ou Windows-1252. - camt.053 : le relevé ISO 20022 de fin de journée, toute version. Un document qui déclare un DOCTYPE est refusé.
Seuls les crédits se gardent : un débit ne dit rien d’un virement de caisse. Un crédit déjà lu dans un relevé précédent n’est pas compté deux fois (duplicate_count). Libellé et donneur d’ordre d’un crédit sont chiffrés.
Un crédit se rapproche d’un virement émis dans les 30 jours qui précèdent quand son libellé contient statement_descriptor. Entre plusieurs virements qui le partagent, le montant puis la ligne 1 départagent. Sans libellé reconnu, il faut le même montant et le nom de l’organisme, et qu’un seul virement réponde.
Un crédit lu avant le retour qui l’annonce attend (status: "unmatched") : il se rapproche à l’arrivée du retour.
Saisie à la main
Sans fichier, POST /v1/bank-transactions enregistre un crédit lu sur le relevé : booked_on, amount_cents et le libellé tel quel. Il se rapproche comme un crédit de relevé. Un crédit identique déjà saisi répond 409.
Pour un virement vu sur le compte sans crédit à donner, POST /v1/payouts/{id}/reconcile sans corps le pointe. Avec bank_transaction, il rattache ce crédit.
Écarts
| Écart | Quand |
|---|---|
amount_mismatch | Le crédit reçu n’a pas le montant annoncé. gap_cents dit la différence |
not_received | Un relevé déposé couvre la date d’émission plus 5 jours, sans montrer le virement |
total_mismatch | Le cumul que le retour annonce n’égale pas la somme de son détail |
unmatched_payments | Des paiements du virement attendent leur facture |
Chaque paiement est rattaché à un virement : un paiement que rien n’explique se voit dans unmatched_payments.
Export comptable
Le tableau de bord exporte le journal de banque d’un mois au format du fichier des écritures comptables (FEC), en CSV : une écriture par virement, datée de son arrivée sur le compte, le compte de banque au débit, les honoraires de chaque part, les paiements ponctuels et les régularisations au crédit. Les comptes se règlent dans Paramètres, Export comptable. Le fichier ne porte ni patient ni acte.
Événements
| Événement | Quand |
|---|---|
payout.created | Un retour de paiement annonce un virement |
payout.reconciled | Un crédit lui répond, ou il est pointé à la main |
payout.flagged | Un écart nouveau apparaît |
Mode test
POST /v1/test-helpers/payouts/{id}/arrival fait écrire au simulateur le relevé camt.053 du compte, qui suit le chemin d’un relevé déposé. Voir Cartes et scénarios de test.
Pièges
accounting_dateest la date d’émission, pas celle de l’arrivée : un virement du vendredi arrive souvent le mardi.- Le libellé n’est pas toujours rempli par la caisse. Sans lui, seuls le montant et le nom de l’organisme rapprochent, et deux virements du même montant attendent un pointage à la main.
not_receivedsuppose que le relevé est celui du compte qui reçoit les virements. Un relevé d’un autre compte du cabinet signalerait à tort.- Un relevé ne supprime rien : déposer le même relevé deux fois ne change rien.