Sin impuesto Con impuesto

Duplicate orders and double charges in PrestaShop: causes and how to prevent them

A customer pays once and two orders appear, two invoices, or a repeated payment status. We explain where it comes from, how to detect it in your history and how to clean it up without creating a bigger problem.

Equipo Rekire
Updated: 23/10/2026 24
Duplicate orders and double charges in PrestaShop: causes and how to prevent them
Share:

The customer paid once. In your back office there are two orders from the same cart, each with its own invoice and its stock deducted. Or there is a single order, but with the “Payment accepted” status twice and two numbered invoices. Looked at separately, both orders seem correct; that is why this problem goes unnoticed until you reconcile the bank or the customer complains.

Where duplicates come from

1. Two gateway notifications at once

It is the most frequent and least visible cause. Many payment gateways report the payment by two routes: the server-to-server notification (webhook, IPN, online notification) and the customer's return to the store. If both arrive at almost the same time, each one asks “is there already an order for this cart?”, both get “no” because neither has created it yet, and each one creates its own. It is a classic race condition.

2. Webhook retries

If your server is slow to respond or returns an error, the gateway sends the notification again. If the payment module does not check that it has already processed it, the order or the status is repeated.

3. Double click or reload

The customer clicks “Pay” twice or reloads the confirmation page. With methods that do not redirect (bank transfer, cash on delivery) this can be enough to create two orders.

4. The back office

An employee changes an order's status, the page is slow and they click again. The status is applied twice and, if that status generates an invoice, two come out.

5. Modules reacting to the same event

Two modules that listen for the status change and one of them changes it again, or an ERP that resends a status already applied.

Why it is hard to find: PrestaShop's normal checks look at each order internally, and each one is fine. The error only shows when comparing orders with each other: same cart, same customer, same amount, seconds apart.

How to detect it in your history

  1. Carts with more than one order. In PrestaShop one cart should produce a single order (except orders split by carrier, which share a reference). A query that groups orders by id_cart and counts those with more than one is the first filter.
  2. Repeated statuses. Orders with the same payment status twice in their history.
  3. Duplicate invoices for the same order.
  4. Payments versus orders. Compare the payments recorded on each order with what the gateway says. Two orders and one charge is a stock and invoicing problem; two orders and two charges is extra money that has to be refunded.

How to clean them up without making things worse

  • Do not delete orders. You lose traceability and, if there was an invoice, you break the numbering. Cancel the surplus one.
  • A numbered invoice is not withdrawn: it is cancelled with a corrective invoice, as required by Spain's Invoicing Regulation (Royal Decree 1619/2012, article 15).
  • Restore the stock of the surplus order, checking that it has not already been restored.
  • If there were two charges, the refund is decided by a person and made from the gateway.
  • Do not touch orders already shipped without reviewing them one by one.

How to prevent it

  1. A lock per cart when creating the order. The second notification must wait for the first to finish and, when it gets in, see that the order already exists. It is the fundamental solution to the race condition.
  2. Idempotency in webhooks: store the identifier of each processed notification and do not repeat what has already been done.
  3. Respond quickly to the gateway: if the webhook is slow, the gateway retries. Anything slow (emails, ERP) is better done afterwards.
  4. Disable the pay button when clicked, and the status forms in the back office too.
  5. A single route that creates the order per gateway, if the module allows it.
  6. Monitoring: an alert the moment a duplicate appears is worth more than finding it months later.

What not to do

  • Modify the PrestaShop core or the payment module to “fix it”: the next update undoes it.
  • Disable the server notification and rely entirely on the customer's return: if they close the tab, the order is not created.
  • Clean up in bulk without a prior dry run.

Checklist

  1. Look for carts with more than one order across your whole history.
  2. Classify: one charge and two orders, or two charges.
  3. Cancel surplus orders, restore stock and issue corrective invoices where needed.
  4. Check how each gateway notifies and whether its webhooks are retried.
  5. Put a lock on order creation and on status changes.
  6. Enable alerts so you find out the same day.

How to handle it in PrestaShop

RKR Order Guard takes a MySQL lock before the payment module's controller loads anything, so that the second notification waits and finds the order already created; it also locks the order while its status changes, so that two invoices are not created, and prevents double submission of the status form in the back office. No overrides. In Orders → Duplicate orders it reviews your whole history and classifies each cart: one charge and two orders (it cancels the surplus and restores the stock), two charges (the refund is decided by a person) or undetermined (it only lists it). It lets you simulate before executing, never deletes orders, does not issue refunds or touch orders with a shipped parcel or invoices already numbered, and if the lock times out the sale goes ahead. RKR Sentinel, which accompanies this article, sends Telegram alerts about payments without an order, amounts that do not match and stuck orders.

Loading...
Cookie consent
Back to top