
La façon la plus rapide de livrer un portefeuille électronique est un simple nombre dans une ligne : une colonne balance que l'on augmente quand l'argent arrive et que l'on diminue quand il part. Cela fonctionne pendant la démonstration. Cela fonctionne pendant le pilote. Puis, vers les dix mille premières transactions réelles, quelqu'un lance un rapport, les chiffres ne concordent pas, et personne ne peut dire où est passé l'argent. Dès que de la valeur réelle est en jeu, ce n'est plus un bug : c'est la fin de la confiance, et la confiance est la seule chose qu'un produit financier vend réellement.
La discipline qui empêche cela a six cents ans. La comptabilité en partie double n'est pas un raffinement comptable greffé sur un logiciel ; c'est le modèle de données qui rend un système monétaire démontrable. C'est pourquoi tout registre de niveau compensation repose sur elle, et pourquoi celui de votre portefeuille doit en faire autant.
L'invariant dont tout le reste dépend
Dans un registre en partie double, l'argent n'est jamais créé ni détruit : il ne fait que circuler. Chaque transaction passe un ensemble d'écritures dont les débits et les crédits s'additionnent exactement à zéro. Un dépôt débite le compte de float d'un agent et crédite le portefeuille d'un client du même montant. Un envoi débite l'expéditeur, crédite le destinataire et crédite un compte de produits pour les frais. Sur l'ensemble du système, à chaque instant :
La somme de tous les débits est toujours égale à la somme de tous les crédits. Les comptes s'équilibrent à zéro. Toujours.
Cette seule propriété accomplit un travail énorme. Elle signifie qu'il n'existe aucun chemin de code capable de créer ou de détruire de la valeur : un solde ne peut changer qu'en miroir du changement d'un autre solde. Elle signifie qu'un directeur financier peut signer les comptes et qu'un régulateur peut s'y fier, parce que le système est correct par construction, et non par espoir. Et elle signifie que le rapprochement cesse d'être une enquête judiciaire pour devenir une propriété que l'on peut affirmer et tester.
Comparez avec l'approche du solde unique. Là, un solde est un fait sans provenance. S'il est faux, impossible de savoir si un crédit a été appliqué deux fois, si un débit a été perdu ou si une condition de concurrence a entrelacé deux écritures. Vous avez un nombre, mais pas d'histoire. Un registre en partie double est avant tout un système qui conserve l'histoire.
Comptes, écritures, et pourquoi modéliser l'argent comme un mouvement
Le changement de perspective consiste à cesser de voir un solde comme une chose que l'on stocke pour le voir comme une chose que l'on déduit. Un solde est la somme des écritures passées sur un compte. Les portefeuilles sont des comptes. Les floats des agents sont des comptes. Les produits de frais, les comptes d'attente, de règlement, les fonds non réclamés : tous sont des comptes. Chaque mouvement de valeur est une transaction contenant deux écritures ou plus qui s'équilibrent à zéro.
Cela a une conséquence profonde : le registre est en ajout seul. On ne met jamais à jour un solde sur place ; on passe de nouvelles écritures. L'historique n'est jamais réécrit. C'est ce qui rend le système auditable : chaque unité de monnaie qui a circulé a laissé une trace permanente et ordonnée, et n'importe quel solde à n'importe quel moment passé peut être reconstitué en rejouant les écritures jusqu'à ce point.
Les éléments que l'on oublie, et que l'on paie plus tard
L'invariant est nécessaire mais pas suffisant. Trois propriétés transforment un registre correct sur le papier en un registre qui survit au contact des réseaux réels et des adversaires réels.
L'idempotence
Les réseaux décrochent. Un client envoie une requête, la réponse se perd en route, et le client, à juste titre, réessaie. Sans protection, la seconde requête passe une seconde transaction et le client est débité deux fois. La solution est une clé d'idempotence : chaque opération logique porte un jeton unique, le registre note les jetons déjà appliqués, et une requête rejouée avec un jeton connu renvoie le résultat d'origine au lieu de passer une nouvelle écriture.
Cela paraît simple et c'est subtil. La vérification et l'écriture doivent être atomiques : si deux tentatives arrivent en même temps, une seule doit l'emporter et l'autre doit constater le résultat, sans aucune fenêtre où les deux avancent. Si vous vous trompez ici, vous avez construit une double dépense sous charge, précisément la panne qui n'apparaît pas pendant les tests et qui apparaît le jour du lancement.
Des contre-passations, pas des suppressions
Les choses tournent mal : un litige, une erreur, une réclamation pour fraude. Le réflexe est de supprimer la transaction en cause. Ne supprimez jamais. Une transaction supprimée est un trou dans la piste d'audit, et un régulateur lit un trou comme une dissimulation. Passez plutôt une contre-passation : une nouvelle transaction dont les écritures sont le miroir de l'originale, qui reste intacte. L'effet net sur les soldes est nul ; l'historique montre à la fois l'erreur et sa correction, avec un motif et un opérateur associés. Un moteur de contre-passation unique capable de défaire n'importe quel service (P2P, paiement de factures, achat de biens, espèces chez l'agent, float, épargne) fait la différence entre un système auditable et une dispute.
Les contrôles préalables
Le solde, les plafonds et le statut KYC sont vérifiés avant qu'une transaction soit passée, dans la même opération atomique qui la passe : jamais après, et jamais dans l'application où ils pourraient être contournés. Le plafond qu'un client ne peut dépasser n'est pas un bouton désactivé ; c'est une contrainte appliquée à l'endroit même où l'argent bougerait. L'application est une commodité ; le registre est l'autorité. Toute règle qui compte doit vivre là où vit l'argent.
La concurrence : là où les bonnes conceptions viennent mourir
Deux requêtes frappent le même portefeuille au même instant : un envoi et un retrait, chacun valide séparément, mais dépassant ensemble le solde. Une implémentation naïve lit le solde dans les deux cas, le trouve suffisant dans les deux cas et passe les deux, mettant le compte à découvert. C'est la condition de concurrence financière classique, et elle reste invisible tant que vous n'êtes pas soumis à une concurrence réelle.
La parade consiste à faire du compte l'unité de sérialisation : passer une écriture sur un compte prend un verrou ou utilise une écriture conditionnelle atomique, de sorte que les deux requêtes sont ordonnées, que la seconde voit l'effet de la première, et qu'une seule réussit. La difficulté est de le faire sans sérialiser le registre tout entier : verrouiller par compte, et non globalement, pour que le système reste rapide tout en restant correct. C'est le genre de problème qui sépare les ingénieurs qui ont déjà construit des registres de ceux qui sont sur le point d'apprendre pourquoi c'est difficile.
Le rapprochement devient une propriété, pas un exercice d'incendie
Dans un système à solde unique, le rapprochement est une enquête nocturne : tout exporter, comparer avec les rails de paiement, traquer l'écart, en espérant le trouver avant le matin. Dans un système en partie double, le rapprochement est pour l'essentiel une tautologie que l'on peut affirmer : les comptes internes s'équilibrent à zéro par construction, et le travail restant consiste à rapprocher les règlements externes (ce que la banque, l'opérateur de mobile money et le processeur de cartes ont réellement transféré) des comptes d'attente et de règlement que le registre suit déjà. Les écarts apparaissent sous forme d'écritures précises non rapprochées, assorties d'une question claire, et non d'un nombre manquant sans histoire.
Un exemple concret : un envoi, comptabilisé
Prenons un client qui envoie 1 000 à un ami, avec des frais de 25. Dans un registre en partie double, cet envoi unique est une transaction comportant trois écritures. Les montants sont indicatifs.
| Compte | Débit | Crédit |
|---|---|---|
| Portefeuille de l'expéditeur | 1 025 | |
| Portefeuille du destinataire | 1 000 | |
| Produits de frais | 25 | |
| Total | 1 025 | 1 025 |
Les débits égalent les crédits, la transaction s'équilibre donc à zéro. Toute question que l'on pourrait se poser à son sujet trouve sa réponse dans les écritures : combien l'expéditeur a payé, combien le destinataire a reçu, combien l'opérateur a gagné, et quand. Si l'envoi est contre-passé plus tard, une transaction miroir passe les mêmes trois lignes en sens inverse, et les deux restent dans l'historique.
Des espèces chez un agent, comptabilisées
Les transactions d'agent montrent pourquoi le modèle passe à l'échelle. Lorsqu'un client dépose 2 000 en espèces chez un agent, la monnaie électronique de l'agent passe au client, et l'agent touche une commission. Avec une commission indicative de 20 :
| Compte | Débit | Crédit |
|---|---|---|
| Float de l'agent | 2 000 | |
| Portefeuille du client | 2 000 | |
| Charge de commissions | 20 | |
| Commissions dues à l'agent | 20 | |
| Total | 2 020 | 2 020 |
Les espèces elles-mêmes n'apparaissent jamais dans le registre, car elles ont changé de mains physiquement au comptoir. Ce que le registre enregistre, c'est la valeur électronique qui passe de l'agent au client, et l'obligation de rémunérer l'agent pour le service. Lorsque les commissions sont versées, une autre transaction équilibrée solde la dette. Rien n'est estimé, rien n'est calculé plus tard dans un tableur.
Concevoir le plan de comptes
Les comptes que vous créez déterminent les questions auxquelles le registre peut répondre. Une plateforme de portefeuille a généralement besoin de :
- Portefeuilles clients, agents, marchands et entreprises, un compte chacun ;
- Comptes de produits de frais ventilés par produit, pour voir ce que rapporte chaque service ;
- Charges de commissions et commissions à payer pour les agents et les partenaires ;
- Comptes de règlement par partenaire externe : chaque banque, switch, facturier et rail ;
- Comptes d'attente pour l'argent dont la destination finale n'est pas encore confirmée, comme un transfert en attente de la réponse d'un partenaire ;
- Un miroir de cantonnement qui suit ce qui doit se trouver sur le compte fiduciaire, pour que la comparaison quotidienne avec le relevé bancaire soit un simple contrôle.
Un test utile : si la finance pose une question et que la réponse exige un tableur, il vous manque probablement un compte.
Tester correctement un registre
Les tests unitaires ordinaires ne suffisent pas pour un système qui ne doit jamais se tromper. Les tests qui comptent vérifient des propriétés plutôt que des exemples :
- Chaque transaction s'équilibre à zéro, sur des milliers de types de transactions et de montants générés aléatoirement.
- Le rejeu égale l'état : reconstruire chaque solde à partir des écritures donne exactement les soldes stockés.
- Les tentatives répétées ne dupliquent jamais : envoyer la même requête de nombreuses fois, y compris simultanément, ne passe qu'une écriture.
- Les accès concurrents ne mettent jamais à découvert : lancer des débits concurrents sur un compte ne le fait jamais descendre sous son plafond.
- Les contre-passations restaurent : contre-passer n'importe quelle transaction ramène chaque solde concerné à sa valeur précédente.
Ces tests ont leur place dans la chaîne de mise en production, et ils doivent aussi tourner sur les données de production en lecture seule, afin que l'invariant soit vérifié en continu sur les vrais comptes, et pas seulement sur des données de test.
Migrer depuis un système à solde unique
Beaucoup d'équipes découvrent ces principes après le lancement. La migration est possible sans interrompre le service :
- Figer le schéma des soldes existants et en prendre un instantané à une heure de coupure.
- Créer dans le nouveau registre des transactions de solde d'ouverture qui passent chaque solde de l'instantané contre un compte de capitaux ou de migration.
- Faire tourner les deux systèmes en parallèle pendant une période, en passant chaque nouvelle transaction dans les deux et en comparant les soldes chaque jour.
- Examiner chaque écart jusqu'à ce que l'exécution parallèle soit propre plusieurs jours de suite.
- Basculer les lectures vers le nouveau registre, puis retirer l'ancienne colonne de solde.
L'exécution parallèle révèle généralement des erreurs historiques dans l'ancien système. Prévoyez du temps pour les résoudre honnêtement plutôt que de forcer le nouveau registre à reproduire un nombre faux.
Ce que l'on y gagne
Construisez le registre de cette façon et une série de choses difficiles deviennent faciles. Les relevés sont une requête sur les écritures. Les audits sont un rejeu. Les litiges ont une piste écrite. Les nouveaux canaux (un envoi USSD, un envoi par l'application, un débit via l'API) ne sont que des portes d'entrée différentes vers le même noyau garanti, ce qui signifie qu'ils ne peuvent pas diverger les uns des autres. Les règles vivent en un seul endroit, appliquées une fois, pour tout le monde.
Construisez-le à la hâte et vous héritez de l'inverse : un nombre que vous ne pouvez pas expliquer, un rapprochement auquel vous ne pouvez pas vous fier, et un jour de lancement où vous découvrez que la chose la moins chère à construire était aussi la plus coûteuse à posséder.
Plusieurs devises
Les portefeuilles qui gèrent des transferts internationaux ou des paiements régionaux rencontrent une seconde dimension : la devise. La règle reste la même, mais elle s'applique devise par devise. Chaque compte détient une seule devise, et chaque transaction doit s'équilibrer à zéro dans chacune des devises qu'elle touche. Une conversion est donc composée de deux jambes équilibrées reliées par un compte de change : la monnaie locale du client passe à la position en monnaie locale de l'opérateur, et les dollars passent de la position en dollars de l'opérateur au destinataire. Les comptes de change montrent à tout moment l'exposition de change de l'opérateur, ce dont la trésorerie a précisément besoin pour gérer le risque. Mélanger des devises dans un même compte, ou convertir à la volée sans enregistrer les deux jambes, est la façon dont les registres multidevises perdent de l'argent sans bruit.
Relevés, clôture mensuelle et audit
Comme les soldes sont déduits des écritures, un relevé n'est que l'ensemble des écritures d'un compte sur une période, avec un solde d'ouverture et un solde de clôture qui doivent concorder avec les écritures intermédiaires. La clôture mensuelle devient un contrôle plutôt qu'un projet : la balance s'équilibre à zéro, le cantonnement correspond à la banque, les comptes d'attente sont expliqués, et les totaux de frais et de commissions concordent avec les rapports produits. Les auditeurs peuvent choisir n'importe quel solde et le remonter jusqu'aux transactions individuelles, chacune avec un horodatage, un canal, une référence et, lorsqu'une personne est intervenue, un opérateur. C'est cette traçabilité qui fait d'un premier audit une routine plutôt qu'une épreuve.
Bien gérer les comptes d'attente
Le compte d'attente est l'endroit où l'argent patiente quand sa destination finale n'est pas encore connue : un transfert vers un autre réseau en attente de confirmation, un dépôt dont la référence ne correspond à aucun client, un paiement de partenaire arrivé sans détails. Il est utile parce qu'il garde les comptes équilibrés tant qu'une question reste ouverte. Il devient dangereux quand il se transforme en lieu où l'argent est oublié. La bonne pratique est simple : chaque élément en attente porte sa référence et la raison de sa présence, chaque élément a un responsable et une ancienneté, le solde est revu chaque jour, et tout ce qui dépasse quelques jours est remonté. Un solde d'attente qui ne fait que croître est le signe que quelque chose est cassé en amont.
Questions fréquentes
La partie double est-elle plus lente que la mise à jour d'un solde ?
Passer deux ou trois écritures au lieu d'une mise à jour ajoute peu de coût, et les soldes peuvent être tenus à jour à côté des écritures pour des lectures rapides. Le vrai travail de performance réside dans le verrouillage par compte plutôt que global, ce que fait un registre bien conçu.
A-t-on encore besoin de comptables si le registre est en partie double ?
Oui. Le registre garantit la cohérence interne ; ce sont toujours des personnes qui décident du traitement comptable des produits, qui examinent les écarts externes et qui rendent compte aux régulateurs. Ce qui change, c'est qu'elles consacrent leur temps au jugement plutôt qu'à la recherche de chiffres manquants.
Une écriture du registre peut-elle jamais être modifiée ?
Non. Les corrections sont de nouvelles transactions, généralement des contre-passations, avec un motif et un opérateur enregistrés. Un registre modifiable ne peut pas être audité.
PesaBridge applique l'invariant au cœur du système. Les applications, l'USSD et l'API pour développeurs ne réimplémentent pas le mouvement de l'argent : ils présentent des règles que le registre garantit déjà, si bien que chaque canal est correct parce que le centre est correct.