The verdict in three sentences
A payment webhook is never guaranteed unique or on time: 3 to 7 % arrive duplicated or late. Without an idempotency key, each duplicate can double-credit an order and corrupt your stock and accounting. The right pattern (unique key, exponential retry, nightly reconciliation) cuts phantom orders from 2 % to under 0.1 %.
Why webhooks betray you without protection
Mobile money providers resend webhooks until they receive a 200 acknowledgement. A slow server, and the same payment is notified several times. Here are the typical problems and their 2026 frequency.
| Problem | Observed frequency | Consequence without protection |
|---|---|---|
| Duplicate webhook | 3-7 % | Double credit, corrupted stock |
| Late webhook (> 30 s) | 4-9 % | Order wrongly marked failed |
| Reversed order (success before pending) | 1-3 % | Inconsistent status |
| Missing or invalid signature | 0.5-2 % | Security hole |
| Webhook never received | 1-2 % | Collected payment not credited |
Each of these cases means lost money or lost trust. The defense rests on three complementary mechanisms.
The idempotency and retry pattern
The idempotency key is a unique identifier per transaction, stored in the database; if the same identifier returns, the duplicate is ignored. Retry handles webhooks not received on the sender side. Here is the recommended retry queue.
| Attempt | Delay after failure | Action |
|---|---|---|
| 1 | Immediate | Processing + 200 response |
| 2 | 1 second | Retry if no 200 |
| 3 | 5 seconds | Retry |
| 4 | 30 seconds | Retry |
| 5 | 5 minutes | Retry, then alert |
| Night | Reconciliation | Match against provider API |
Need a professional website?
Kolonell builds websites that attract clients, optimized for the Sénégalese market. Free quote in 2 minutes.
Add an HMAC signature check and a 5-minute anti-replay window on the timestamp: any older webhook is rejected, blocking replay attacks.
Mini case study
Ibrahim runs a ticketing site in Dakar processing 3,000 payments per month. Before, about 2 % of orders were phantoms (duplicates or inconsistent statuses), or 60 orders to fix manually, each costing 15 minutes of support. After adding the idempotency key and nightly reconciliation, he drops to under 3 problematic orders per month. He saves nearly 14 hours of monthly support and eliminates double-credit refunds.
FAQ
Where should I store the idempotency key? In a dedicated table with a uniqueness constraint on the provider transaction identifier. The database natively rejects any duplicate, making processing safe.
What do I do with a late webhook? Never cancel an order on webhook silence alone. Nightly reconciliation queries the provider API to settle pending cases definitively.
How do I verify the HMAC signature? Recompute the payload hash with your shared secret and compare it to the received header, in constant time. Add a 5-minute timestamp window against replay.
How often should I run reconciliation? A nightly pass suffices for most shops, plus an hourly pass at peak hours. It catches the 1 to 2 % of webhooks never received.
Let's talk about your project. We audit your webhook funnel and install idempotency, retry and reconciliation to eliminate phantom orders. WhatsApp +221 77 596 93 33.
Mohamed Bah
Fondateur, Kolonell
Passionate about digital and entrepreneurship in Africa, Mohamed has been helping Sénégalese businesses with their digital transformation since 2020. Founder of Kolonell, he believes every SME deserves a professional and accessible online présence.
