Money & Running the Business
How do I prevent duplicate charges and fix one quickly if it happens?
The short answer
Prevent duplicates by disabling the pay button after submission, giving every order a unique ID, making retries safe, and matching payment events before creating a second charge. If a duplicate happens, confirm both settled transactions, refund the extra one through the original processor, notify the customer, and preserve the records.
First confirm that it is truly a duplicate
Two lines can represent:
- one authorization and one completed charge.
- a pending attempt that will disappear.
- two legitimate installments.
- one sale and one tip or tax amount.
- two separate successful charges.
Open both transaction records. Compare amount, timestamp, customer, order ID, invoice ID, payment method, and status. Never ask the customer to email a card number or screenshot containing full account details.
Fix a confirmed duplicate
- Stop further retries. Pause the automation or checkout issue that created it.
- Refund the extra transaction. Use the original processor and reference the duplicate charge.
- Tell the customer plainly. Give the refunded amount, transaction date, and refund confirmation.
- Explain timing carefully. Say that the processor or bank controls when the credit appears. Don’t promise a date you cannot guarantee.
- Record the refund. Keep both charges and the refund visible in the books rather than deleting history.
- Check for other customers affected. Search the same time window, order route, or automation.
A useful note is: “We found two successful $85 charges for order 631. We refunded the second charge today through the original card. Here is the refund reference.”
Prevent double clicks and unsafe retries
In a checkout you control, disable the submit button after the first click and show a clear “processing” state. Don’t let a page timeout automatically create a new charge.
At the payment API level, use a unique idempotency key for one payment attempt. Stripe’s idempotent request documentation describes how repeating a request with the same key can return the original result instead of performing the operation again. This is technical guidance for Stripe integrations. Developers should follow the equivalent official pattern for the processor they use.
Also give each order and invoice one stable identifier. Before charging again, query the processor for the status of the original payment.
Watch automations that overlap
Duplicates often come from two systems doing the same job: an invoice set to auto-charge plus a separate recurring subscription, a store integration plus a manually sent link, or an employee retrying while a scheduled retry is still active.
Map which system owns each step:
- invoice creation.
- payment attempt.
- retry schedule.
- receipt.
- fulfillment.
- bookkeeping import.
One owner per step is much easier to debug.
Learn from the incident
Write a five-line incident note: what happened, who was affected, money refunded, root cause, and prevention change. If customer data or a system breach may be involved, follow your incident plan and applicable notification laws with qualified help.
Finally, reconcile the processor and bank. A refund can appear in a later payout than the original sale, so a single bank deposit may not tell the full story. Stripe’s payout reconciliation documentation shows how one payout can include multiple underlying transactions.
Sources and further reading
A free next step
You don't have to build this alone
Bring your questions, share what you're working on, and meet other women building businesses from home. It is free to join.
Related Questions
- What should I do when a customer's payment fails?
- What should I do when a customer disputes a credit-card charge?
- Stripe, PayPal, or Square: which payment processor fits service, local, ecommerce, or digital-product businesses?
- When should I invoice a client, and should I collect payment before or after the work?
