Afrique Digitale11 min de lecture

Webhooks de paiement fiables : idempotence et vérification de signature

Mohamed Bah·Fondateur, Kolonell
20 août 2026
Partager :
Webhooks de paiement fiables : idempotence et vérification de signature

Webhooks de paiement fiables : idempotence et vérification de signature

Afrique Digitale

Le verdict en trois phrases

Un webhook de paiement n'est pas un appel unique et garanti : il est rejoué 3 à 10 fois sur 24 à 72 heures, dans le désordre, parfois après un timeout de votre serveur. Sans clé d'idempotence, vérification de signature HMAC et protection contre le rejeu, vous encaissez des doubles débits et perdez des commandes. La règle d'or : vérifier la signature, dédupliquer par event id, répondre 200 vite, traiter en asynchrone, et réconcilier avec l'API de statut comme source de vérité.

Pourquoi les webhooks arrivent en double

Les fournisseurs considèrent un webhook comme livré uniquement si vous répondez 200 rapidement. Le moindre délai déclenche un rejeu. Voici les politiques typiques 2026 (ordre de grandeur, à vérifier dans la doc de chaque fournisseur).

FournisseurNb de tentativesFenêtre de rejeuTimeout attenduSignature
Paystackjusqu'à ~5~72 h< 10 sx-paystack-signature (HMAC SHA512)
Wave3 à 1024-48 h< 10 stoken / signature
CinetPay3 à 8~48 h< 15 stoken de vérification
Flutterwavejusqu'à ~5~24 h< 10 svérif-hash header
Stripejusqu'à ~15 sur 72 h72 h< 10 sStripe-Signature

Conclusion : concevez TOUJOURS votre endpoint comme s'il allait recevoir chaque événement plusieurs fois. L'idempotence n'est pas optionnelle.

Les 5 bugs les plus fréquents

BugConséquenceCorrectif
Pas de vérification de signatureFaux webhook -> fausse commande payéeVérifier HMAC avant tout traitement
Traitement synchrone lourdTimeout -> rejeu -> double débitRépondre 200 vite, traiter en file async
Pas de déduplicationMême event traite 2 foisStocker event id, ignorer si déjà vu
Confiance au montant du payloadMontant falsifié acceptéRéconcilier via l'API de statut
Retour 500 sur erreur métierRejeu infini du fournisseurRetourner 200 + logguer pour rejouer soi-même

Ces cinq erreurs représentent la quasi-totalité des incidents de paiement que nous auditons chez Kolonell.

Le patron robuste en 6 étapes

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.

Vous préférez qu’on vous rappelle ?

Laissez votre WhatsApp, un expert Kolonell vous recontacte sous 24h ouvrées. Gratuit et sans engagement.

  • Vérifier la signature (HMAC) avec le secret du fournisseur, avant de lire quoi que ce soit d'autre. Signature invalide -> 401.
  • Extraire l'event id et vérifier en base s'il a déjà été traité. Déjà vu -> répondre 200 et sortir.
  • Enregistrer l'événement brut (event id, payload, date) dans une table de journal.
  • Répondre 200 immédiatement, avant tout traitement métier lourd.
  • Traiter en asynchrone (file d'attente) : mise à jour de la commande, envoi de la facture, notification.
  • Réconcilier avec l'API getStatus du fournisseur comme source de vérité avant de marquer "payé".

Mini cas pratique

Ibrahim vend des billets d'événement en ligne à Abidjan. Un vendredi soir, son serveur rame sous la charge : le webhook Wave met 12 secondes à répondre, le timeout est à 10 s. Wave rejoue l'événement 4 fois. Sans idempotence, Ibrahim crée 4 billets pour un seul paiement de 15 000 FCFA et débité... non, en réalité le client n'est débité qu'une fois, mais Ibrahim envoie 4 billets valides, dont 3 seront utilisés frauduleusement : perte de 45 000 FCFA sur une seule commande. Après correction (déduplication par event id + réponse 200 immédiate + traitement async), le même scénario ne crée qu'un billet, quel que soit le nombre de rejeux. Sur un week-end à 400 billets, l'incident aurait coûte plusieurs centaines de milliers de FCFA.

FAQ

Pourquoi vérifier la signature si l'URL du webhook est secrète ? Parce qu'une URL n'est jamais vraiment secrète : elle fuite dans les logs, les proxies, les captures réseau. La signature HMAC prouve que le message vient bien du fournisseur et n'a pas été falsifié. Sans elle, n'importe qui connaissant l'URL peut simuler un paiement.

Que veut dire idempotence concrètement ? Cela signifie que traiter le même événement 1 fois ou 10 fois produit exactement le même résultat. En pratique : stocker l'event id du fournisseur et ignorer tout événement déjà enregistré. Une commande passe à "payée" une seule fois, même après 10 rejeux.

Faut-il faire confiance au montant présent dans le webhook ? Non. Le payload peut être incomplet ou, en cas de faille, falsifié. Réconciliez toujours le montant et le statut via l'API de statut du fournisseur avant de livrer la commande.

Pourquoi répondre 200 avant de traiter ? Parce que le fournisseur attend un accusé rapide (souvent < 10 s). Si votre traitement métier est lent, vous dépassez le timeout et déclenchez des rejeux. Accusez réception d'abord, traitez ensuite en file asynchrone.

Comment tester tout ça sans vrais paiements ? Utilisez le sandbox du fournisseur et sa fonction de rejeu d'événements. Envoyez deux fois le même event pour vérifier la déduplication, envoyez une signature invalide pour vérifier le rejet 401. Kolonell livre chaque intégration avec cette batterie de tests.

Discutons de votre projet. On audite vos webhooks ou on livre une intégration paiement idempotente et signée, testée en sandbox. WhatsApp +221 77 596 93 33.

Tags :#webhooks#idempotence#signature HMAC#paiement#Wave#Paystack#fiabilite#backend
Partager :

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.