Websites11 min read

Webhook idempotency: preventing double charges in Durban (2026)

Mohamed Bah·Fondateur, Kolonell
August 18, 2026
Share:
Webhook idempotency: preventing double charges in Durban (2026)

Webhook idempotency: preventing double charges in Durban (2026)

Websites

The verdict in three sentences

A payment webhook can be delivered several times — it is an at-least-once guarantee, not exactly-once. Without an idempotency key and a deduplication table, 2% to 5% of duplicates turn into double charges and customer disputes. The fix rests on three elements: unique key, transactional lock, and always responding 200.

Why duplicates are inevitable

Mobile money operators replay a notification until they receive a clear acknowledgement. If your server responds slowly, returns a 500, or times out, the operator treats delivery as failed and retries. Your code must therefore handle every event as if it could arrive multiple times.

Webhook behaviour 2026Typical valueConsequence without idempotency
Observed duplicate rate2–5%Double charge
Operator retriesup to 5xUp to 5 debits
Delay between retries1 → 30 minDeferred duplicates
Expected responseHTTP 200500/timeout = replay
Recommended dedup window24hDuplicates outside window

The golden rule: respond 200 only once the event is recorded, never before. A premature 200 loses the event if the process crashes.

The idempotency pattern

Each event carries a stable identifier supplied by the operator (transaction id or event id). We use it as the primary key in a deduplication table. On receipt: attempt to insert the key; if it already exists, ignore it and respond 200 without reprocessing.

Pattern elementRoleImplementation detail
Idempotency keyIdentify the eventoperator transaction id
Dedup tableRemember what's processedUNIQUE constraint on key
Transactional lockPrevent concurrencySELECT ... FOR UPDATE
Audit logTraceabilitytimestamp + raw payload
200 responseStop replaysafter commit only
Retention windowCleanuppurge after 24–72h

Need a professional website?

Kolonell builds websites that attract clients, optimized for the Sénégalese market. Free quote in 2 minutes.

Two identical webhooks received in parallel are the real trap: without a lock or a database uniqueness constraint, both pass the "does it already exist?" check before either writes. The database UNIQUE constraint is your last line of defence.

Mini case study

Ibrahim runs an online grocery in Durban with 1,500 payments a month. With 4% unmanaged duplicates, that is 60 double charges monthly. At an average basket of 12,000 FCFA, that means 720,000 FCFA to refund each month, plus dispute costs and lost trust. After implementing idempotency, duplicates drop to zero: one day of integration work pays for itself in under a week.

FAQ

Is a database UNIQUE constraint enough? It is essential but not sufficient alone: combine it with transactional processing to cleanly handle concurrent webhooks and guarantee a consistent state.

What should I return if the event is already processed? HTTP 200. The operator understands delivery succeeded and stops replaying. Returning an error would needlessly restart the cycle.

How long should I keep the keys? A window of 24 to 72 hours covers nearly all replays. Beyond that, purge them so the table does not grow indefinitely.

Should I verify the webhook signature? Yes, always. Idempotency prevents duplicates; signature verification prevents malicious fake events. The two are complementary.

Let's talk about your project. We secure your payment webhooks with idempotency, locking, and an audit log, tested against real replays. WhatsApp +221 77 596 93 33.

Tags:#idempotence#webhook#double paiement#conakry#integration#fiabilite
Share:

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.