The verdict in three sentences
Double charging is the worst payment incident: it does not just cost money to refund, it destroys customer trust instantly. The one reliable countermeasure: an idempotency key (a single reference_id) attached to each attempt, which blocks any second collection for the same purchase intent. On mobile money, about 1.2% of payments suffer a double click or network replay, and without idempotency, each becomes a double charge to refund.
Where the double charge comes from
The double charge almost never comes from the operator: it comes from your app sending the same collection request twice. Three causes dominate. The double click: the user, seeing the screen freeze, taps "Pay" twice. The network replay: the first request goes out, the network times out before the response, and your code automatically resends. The badly designed retry: a retry mechanism that re-launches the collection instead of checking the status.
| Double-charge cause | Estimated 2026 frequency | Without idempotency | With idempotency |
|---|---|---|---|
| User double click | About 1.2% | 2 debits | 1 debit, 2nd ignored |
| Network replay (timeout) | About 0.8% | 2 debits | 1 debit, 2nd ignored |
| Retry that re-collects | Variable | 2 debits | 1 debit, 2nd ignored |
| Replayed webhook | About 2% | 2 credits | 1 credit, 2nd ignored |
The USSD timeout, typically 60 s on mobile money, worsens the problem: during that minute of waiting, the user thinks nothing happened and retries. The idempotency key is what lets the second request be recognized as a duplicate and set aside.
The anti-duplicate sequence with the MoMo API
The principle: generate one unique idempotency key per purchase intent (not per click), and send it as reference_id (or externalId) to the operator. If a second request arrives with the same key, the API returns the first result without creating a new debit. With the MTN MoMo Collection API, the sequence relies on requestToPay then a status check before any capture.
| Transaction state | Meaning | Correct action |
|---|---|---|
| PENDING | Collection requested, waiting | Wait, do not re-collect |
| SUCCESSFUL | Debit confirmed | Mark paid, fulfil |
| FAILED | Debit declined | Show the cart again |
| TIMEOUT | No USSD response | Check status, do not re-collect |
| Same reference_id | Duplicate detected | Return the first result |
The golden rule: check the status before capturing. Never re-launch a requestToPay on timeout; first query the status by externalId. If the payment is already SUCCESSFUL, you have avoided a double charge. If it is FAILED, only then offer a retry — with a new key if it is genuinely a new intent.
Mini case study
Aminata runs an online store in Accra with MTN MoMo. In May 2026, she processes 5,000 payments. Statistically, about 60 payments (1.2%) suffer a double click. Without idempotency, that would be 60 customers charged twice, that is — at an average basket of 12,000 FCFA — 720,000 FCFA to refund, and 60 furious customers.
Need a professional website?
Kolonell builds websites that attract clients, optimized for the Sénégalese market. Free quote in 2 minutes.
After setting up the idempotency key per purchase intent, the second collection of each duplicate is ignored: zero double charge. On the rare USSD timeout cases, her code checks status by externalId before any re-capture, recovering another dozen payments that would have looked failed. Result: 0 FCFA of double-charge refunds, and a payment complaint rate divided by more than ten.
Become a Kolonell referral partner
Do you know merchants, restaurateurs or entrepreneurs losing sales because of unreliable payments? Refer them and earn a commission on every signed project. The Kolonell referral partner program is simple and transparent.
| Referred project type | Sale commission | Recurring commission |
|---|---|---|
| Showcase site | 15% | 5% on maintenance/SEO |
| E-commerce (Wave/OM) | 12% | 5% on maintenance/SEO |
| Marketplace | 10% | — |
| Institutional | 8% | — |
Concretely: referring an e-commerce project at 2,000,000 FCFA earns you 240,000 FCFA in commission, plus 5% recurring if the client takes maintenance. No technical skills required: you open the door, Kolonell delivers, you get paid.
FAQ
What exactly is an idempotency key? It is a unique identifier generated per purchase intent, not per click, sent with each payment attempt. If two requests carry the same key, the operator processes a single collection: the 1.2% double clicks become harmless.
Should you regenerate the key on each retry? No for a retry of the same intent: keep the same key so a duplicate is detected. Only generate a new key if the customer deliberately restarts a purchase after a confirmed failure.
What do you do during the 60 s USSD timeout? Do not re-collect anything. Check the status by externalId: if the payment is already SUCCESSFUL, you avoided a double charge; if it is FAILED, offer a clean retry.
Does idempotency also protect webhooks? Yes: the same logic by transaction_id absorbs the 2% of replayed webhooks without double credit. It is the same discipline applied on the receiving side.
How much does a double charge really cost? Beyond the amount to refund, it costs trust: a customer charged twice rarely returns. Avoiding 720,000 FCFA of refunds on 5,000 payments is as much about image as money.
Let's talk about your project. We secure your payments with idempotency to eliminate any double charge — and if you refer a client, you earn up to 15% commission. 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.
