The verdict in three sentences
A duplicate charge almost always comes from three sources: the customer re-clicking, the server replaying a request, or the provider sending two webhooks. The single sufficient defense is called idempotency: one unique key per payment attempt, honored from the button all the way to the webhook. Without it, the observed frequency in 2026 ranges from 0.5% to 2% of transactions — largely avoidable.
The three entry points for duplicates
Each layer must protect itself independently; a single barrier is never enough.
| Duplicate source | Trigger | Defense |
|---|---|---|
| Customer | Double-click, back button, refresh | Disable button + idempotency key |
| Server | Network retry, timeout then re-send | Idempotency key stored in DB |
| Provider | Webhook sent twice | Dedupe by event reference |
| Reconciliation | CSV import replayed | Unique constraint on reference |
The idempotency key is generated once when checkout opens and travels with every request. If the server sees the same key twice, it returns the first result instead of creating a new payment.
The anti-duplicate checklist
From UI to back office, seven measures cover 99% of cases.
| # | Measure | Layer | Effect |
|---|---|---|---|
| 1 | Disable button after click | UI | -60% of customer duplicates |
| 2 | Idempotency key per checkout session | Client | Deduplicated requests |
| 3 | Unique constraint on reference | Database | Rejects the 2nd record |
| 4 | Webhook deduplication | Backend | One event = one processing |
| 5 | Check status before new charge | Backend | No recharge if paid |
| 6 | Double-charge detection (alert) | Monitoring | Refund < 24 h |
| 7 | Express refund procedure | Support | Trust preserved |
If a double charge still slips through, refund speed makes all the difference: aiming for under 24 h turns an incident into proof of seriousness.
Need a professional website?
Kolonell builds websites that attract clients, optimized for the Sénégalese market. Free quote in 2 minutes.
Mini case study
Moussa sells phone accessories in Dakar: 1,200 orders/month. With no protection, he suffered ~1.3% double charges, i.e. 16 orders/month at 8,000 FCFA = 128,000 FCFA to refund, plus ~5 h of support. After adding button disabling, an idempotency key and webhook deduplication, the rate fell to ~0.1% (1-2/month). Monthly saving: ~120,000 FCFA + 5 h, and above all zero "charged twice" negative reviews.
FAQ
What is an idempotency key concretely? It's a unique identifier generated at the start of checkout, sent with every payment request. The server uses it to recognize an already-processed attempt and not replay it. It's the central defense against duplicates.
Is disabling the button enough? No. It cuts about 60% of customer duplicates but protects against neither server retries nor duplicated webhooks. You must combine UI + idempotency + deduplication.
How do I detect a double charge quickly? A monitoring alert on two successful payments with the same amount, same customer and a short interval (< 2 min). Handled in under 24 h, the incident stays painless.
Does a duplicate webhook really create a double payment? It doesn't create a second provider charge, but it can create a second order or decrement stock twice if processing isn't idempotent. Hence deduplication by event reference.
What duplicate rate should I target in 2026? Without protection: 0.5% to 2%. With the full checklist: under 0.1%. Every tenth of a point avoided means fewer refunds and less support.
Let's talk about your project. We audit your checkout and add complete anti-duplicate protection, from button to webhook. 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.

