Le verdict en trois phrases
Un webhook n'est jamais envoye une seule fois : Wave, Paystack ou Flutterwave peuvent retenter le meme evenement jusqu'a 5 fois sur 24 heures. Sans cle d'idempotence cote base de donnees, votre systeme livre la commande deux fois ou rembourse deux fois, et chaque doublon coute une marge produit perdue. La solution tient en trois briques : une cle unique par evenement, une table de deduplication, et un upsert atomique qui rend l'operation rejouable sans effet de bord.
Pourquoi les doublons arrivent
Un webhook est un appel HTTP. Si votre serveur repond lentement, plante, ou renvoie une erreur reseau apres avoir traite l'evenement, l'operateur considere l'envoi comme echoue et retente. Vous avez donc deja livre, mais vous recevez le meme evenement une deuxieme fois.
| Operateur | Nombre de retries 2026 | Fenetre | Backoff |
|---|---|---|---|
| Wave | Jusqu'a 5 | 24 h | Exponentiel |
| Paystack | Jusqu'a 5 | 24 h | Exponentiel |
| Flutterwave | Jusqu'a 5 | 24 h | Exponentiel |
| Orange Money | Variable | Selon config | Selon config |
Ces chiffres sont des ordres de grandeur 2026. Le point commun : tous retentent. Votre code doit partir du principe que chaque evenement arrivera plusieurs fois, et se comporter comme si c'etait la premiere.
Evenement, risque et garde-fou
Voici la matrice a graver dans votre architecture. Pour chaque type d'evenement, un risque de doublon et le garde-fou qui l'annule.
| Evenement | Risque du doublon | Garde-fou |
|---|---|---|
| payment.success | Double fulfillment | Cle unique + upsert |
| payment.success | Double email/SMS | Flag notified en base |
| refund.completed | Double remboursement | Statut refunded verrouille |
| payout.sent | Double versement vendeur | Ledger avec cle transaction |
| order.paid | Double decrement stock | Transaction atomique |
| subscription.renewed | Double facturation | Cle periode + upsert |
Le pattern universel : chaque webhook porte un identifiant unique (event id ou transaction reference). Vous l'inserez dans une table processed_events avec une contrainte d'unicite. Pseudo-code SQL : INSERT INTO processed_events (event_id, processed_at) VALUES ($1, now()) ON CONFLICT (event_id) DO NOTHING RETURNING event_id;. Si l'insert renvoie une ligne, c'est la premiere fois : vous traitez. S'il ne renvoie rien (conflit), l'evenement est deja traite : vous repondez 200 sans rien faire. L'atomicite de l'upsert evite meme les courses entre deux callbacks simultanes.
Mini cas pratique
Fatou, gerante d'une marketplace artisanale a Thies, versait automatiquement les vendeurs a reception du webhook payout. Un vendredi, un pic de latence a fait retenter Flutterwave 3 fois sur les memes commandes. Sans cle d'idempotence, son systeme a verse 3 fois a 14 vendeurs. Sur un panier moyen de 25 000 FCFA et une commission plateforme de 10 %, chaque commande reverse 22 500 FCFA au vendeur. Les 28 versements en trop (2 doublons x 14 vendeurs) representaient 630 000 FCFA sortis a tort, a recuperer un par un. Apres ajout d'un ledger avec cle de transaction unique et upsert atomique, les doublons sont tombes a zero. Le correctif a pris une demi-journee.
Besoin d'un site web professionnel ?
Kolonell crée des sites web qui attirent des clients, optimisés pour le marché sénégalais. Devis gratuit en 2 minutes.
FAQ
Combien de fois un webhook peut-il etre renvoye en 2026 ?
Jusqu'a 5 fois sur 24 heures chez Wave, Paystack et Flutterwave, avec un backoff exponentiel. Votre code doit traiter chaque evenement comme s'il pouvait arriver plusieurs fois.
Quelle est la cle d'idempotence a utiliser ?
L'identifiant unique de l'evenement ou la reference de transaction fournie par l'operateur. Vous la stockez avec une contrainte d'unicite en base pour bloquer tout retraitement.
Un doublon coute-t-il vraiment cher ?
Oui. Un double fulfillment perd une marge produit, un double remboursement ou un double payout sort de l'argent reel. Dans l'exemple ci-dessus, 630 000 FCFA verses a tort en un seul incident.
Dois-je repondre 200 meme si l'evenement est un doublon ?
Oui. Repondez 200 pour dire a l'operateur que vous avez recu, sinon il retentera encore. Simplement, en interne, vous ne rejouez pas le traitement.
Un upsert suffit-il contre deux callbacks simultanes ?
Oui, si l'upsert est atomique avec une contrainte d'unicite (ON CONFLICT DO NOTHING). La base arbitre la course : un seul insert gagne, l'autre est ignore proprement.
Discutons de votre projet. On rend vos webhooks paiement idempotents et on protege votre caisse des doubles encaissements. WhatsApp +221 77 596 93 33.
Mohamed Bah
Fondateur, Kolonell
Passionné par le digital et l'entrepreneuriat en Afrique, Mohamed accompagne les entreprises sénégalaises dans leur transformation digitale depuis 2020. Fondateur de Kolonell, il croit que chaque PME mérite une présence en ligne professionnelle et accessible.

