Expertise 04 / 07

Fintech & paiement

Encaisser en Mobile Money sans jamais perdre ni doubler une transaction.

Prouvé sur :Syitech CashKultixEbedouFlokSydica

Depuis juin 2022

  • idempotence
  • webhooks signés
  • partie double
  • temporisation exponentielle
  • réconciliation
  • machine à états
  • USSD / OTP
  • multi-opérateurs

Démonstration — aucun paiement réel, aucun opérateur contacté.

Machine à états de la transaction

  1. INITIÉ

    clé d'idempotence émise

  2. EN_ATTENTE_OTP

    USSD puis code OTP

  3. CONFIRMÉ

    webhook signé vérifié

  • ÉCHOUÉ
  • EXPIRÉ
  • REMBOURSÉ

Opérateur

Sélectionné : Orange Money — USSD puis code OTP

Simulateur de pannes

aucune panne simulée

L'idempotence, en une action

Le réseau coupe en cours d'appel : la requête repart, la transaction ne double pas.

Requêtes envoyées
0
Transactions créées
0
Clé rejouée

Journal des webhooks

0 événements

Écritures en partie double

15 000 F CFA · frais de service 1,00 %

Aucune écriture tant que la transaction n'est pas confirmée.

Panneau technique

Identifiant de transaction

Clé d'idempotence

Tentatives— / 5

Signature du webhook

En attente

Latence par étape

Initiation
OTP
Confirmation

Montant / frais / net

15 000F CFA

1,00 % de frais · net 14 850 F CFA

État du grand livre

4
Opérateurs intégrés

Orange · MTN · Moov · Wave

5
Tentatives de reprise

temporisation exponentielle

Le mécanisme

Comment ça marche.

Client

clé d'idempotence générée

API

création de la transaction

PSP

Wave · CinetPay · Fineopay

Opérateur

USSD puis code OTP

Webhook signé

reprise 5 tentatives

Vérification

HMAC-SHA256

Partie double

débit = crédit · réconciliation

Côté encaissement — le webhook fait foi.

Le retour synchrone de l'API est immédiat mais ment : l'opérateur peut confirmer après coup, ou infirmer. Seul le webhook signé fait foi ; le retour synchrone ne sert qu'à afficher un état d'attente. La reprise applique une temporisation exponentielle sur cinq tentatives, parce qu'un réseau qui coupe en cours d'appel est la règle et non l'exception.

Côté comptabilité — l'équilibre d'abord.

Chaque transaction confirmée produit ses écritures en partie double, contrôlées à l'enregistrement : une écriture déséquilibrée n'est jamais émise. La clé d'idempotence est générée par le client à l'ouverture du formulaire et rejouée telle quelle à chaque tentative, ce qui protège du double appui avant la première réponse — une contrainte d'unicité en base rattrape les collisions.

Les arbitrages

Ce que j'ai écarté, et pourquoi.

Un choix technique sans son coût n'est pas un choix, c'est une préférence.

01

Se fier au retour de l'API, ou attendre le webhook ?

Le problème

Le retour synchrone de l'API est immédiat mais ment : l'opérateur peut confirmer après coup, ou infirmer.

Les options

Se fier au retour synchrone · attendre le webhook · combiner les deux.

Ce que j'ai choisi

Le webhook signé fait seul foi ; le retour synchrone ne sert qu'à afficher un état d'attente.

Le coût

L'interface doit gérer un état intermédiaire, et une transaction peut rester en attente plusieurs minutes.

02

Clé d'idempotence : client ou serveur ?

Le problème

Une clé d'idempotence générée par le serveur ne protège pas d'un double appui avant la première réponse.

Les options

Clé côté serveur · clé côté client · pas de clé, déduplication a posteriori.

Ce que j'ai choisi

Clé générée par le client à l'ouverture du formulaire, rejouée telle quelle à chaque tentative.

Le coût

Il faut faire confiance au client sur l'unicité — d'où une contrainte d'unicité en base qui rattrape les collisions.

03

Un seul prestataire de paiement, ou plusieurs ?

Le problème

Un seul prestataire de paiement simplifie tout, mais une panne de son côté arrête l'encaissement.

Les options

Un PSP unique · plusieurs PSP derrière une interface commune.

Ce que j'ai choisi

Plusieurs, avec les frais de service paramétrés par méthode en points de base.

Le coût

Chaque PSP a son format de webhook, sa signature et ses codes d'erreur — la couche d'abstraction est une vraie charge de maintenance.

Preuves dans le code

Deux extraits réels.

app/Services/Payment/PaymentStateMachine.php

Extrait à fournir

app/Http/Controllers/Webhooks/PspWebhookController.php

Extrait à fournir

Code Mes Rêves

Alexis Kouakou