Websites11 min read

Idempotent Payment Webhooks: Preventing Duplicate Orders (2026)

Mohamed Bah·Fondateur, Kolonell
August 22, 2026
Share:
Idempotent Payment Webhooks: Preventing Duplicate Orders (2026)

Idempotent Payment Webhooks: Preventing Duplicate Orders (2026)

Websites

The verdict in three sentences

A payment webhook sent by CinetPay, Paystack or Flutterwave can arrive 3 to 8 times for a single transaction, because the aggregator retries until it receives a clean HTTP 200. Without an idempotency key stored in your database, each attempt recreates an order: double shipping, double email, double stock deduction. The fix rests on three blocks: HMAC signature verification, a deduplication table indexed on the transaction ID, and a persisted status (pending/success/failed).

Why a webhook arrives multiple times

Aggregators guarantee "at least once" delivery, never "exactly once". If your server responds in 6s, if the network drops, or if you return a 500, the PSP treats the event as undelivered and replays it. This is intentional: two notifications beat a lost transaction. Deduplication is therefore your code's responsibility.

PSP (2026 order of magnitude)Attempts in 24hRetry windowBackoff
CinetPay3 to 5up to 24hincreasing
Paystack5 to 8up to 72hexponential
Flutterwave3 to 6up to 48hexponential
PayDunya3 to 5up to 24hincreasing
Wave (direct API)2 to 4up to 12hincreasing

The lesson: design for at least 8 possible replays, even if the average is lower.

The real cost of a duplicate

A duplicate is not a cosmetic bug. On a physical order you lose 100% of the margin on the second shipment, plus return fees and support time.

Duplicate impact2026 estimateComment
Lost margin (2nd shipment)100% of productneither paid nor recoverable
Return shipping fees2,000 to 5,000 FCFAif the customer returns
Support time15 to 30 minper dispute
Non-refunded PSP fees1.5 to 3%on the reprocessed amount
Negative review riskhigh1-star reviews common

The three technical blocks

1. Verify the HMAC signature. Each PSP signs the webhook body with your secret key. Recompute the HMAC-SHA256 and compare it with the received header. An improperly signed webhook is rejected before any processing: your first line of defense against fake payments.

Need a professional website?

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

2. Deduplication table. Create a webhook_events(transaction_id UNIQUE, status, received_at) table. On receipt, attempt an INSERT. If the UNIQUE constraint fails, the event is already processed: return 200 and stop. That is your idempotency guarantee.

3. Respond fast, process later. Acknowledge (200) in under 2s, then run business logic in the background. Heavy synchronous processing causes timeouts... which cause replays.

Mini case study

Awa runs a cosmetics shop in Dakar, 900 orders/month via CinetPay. Before idempotency she saw about 2.5% duplicates, roughly 23 orders/month shipped twice. Average basket 18,000 FCFA, 40% margin: each duplicate cost her the margin (7,200 FCFA) plus 3,000 FCFA return, i.e. 10,200 FCFA. Total: 23 x 10,200 = 234,600 FCFA/month wasted. After adding a deduplication table (2 dev days), duplicates drop to near zero: the investment pays back in under two weeks.

FAQ

How many times can a webhook really arrive? Depending on the PSP, 2 to 8 attempts over a 12 to 72h window. Always design for the widest case, at least 8 replays.

Which key should I deduplicate on? The PSP transaction ID (not your order ID), set as a UNIQUE constraint. It is the only stable identifier across all replays of the same payment.

Should I return 200 even for a duplicate? Yes. Returning 200 in under 2s stops the retries. A 500 or a timeout restarts the full retry sequence.

Is the HMAC signature mandatory? Functionally no, but without it anyone can fake a successful payment. It is essential in production: the omission can cost 100% of the fraudulent basket.

How much does this hardening cost? Roughly 1 to 3 dev days for the dedup table, HMAC verification and async processing: negligible against the losses avoided.

Let's talk about your project. We integrate idempotent, signed webhooks for your mobile money aggregator, tested end to end. WhatsApp +221 77 596 93 33.

Tags:#webhook#idempotence#agregateur#paiement#cinetpay#paystack#integration#dev
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.