WooCommerce: Prevent Duplicate Orders

Sometimes customers accidentally submit the same order twice, or there may be a temporary issue with a WooCommerce payment gateway or a plugin conflict—such as the Sucuri Firewall problem in March 2025.

This can result in duplicate charges, refunds, chargebacks, admin costs and a poor user experience.

I recently ran into this issue myself and decided to create a simple solution. By checking if the same customer placed an identical paid order within the last 2 minutes, we can block the second attempt and show a helpful message.

If you’ve experienced something similar or want to proactively prevent it, here’s a quick snippet you can add to your site to avoid duplicate WooCommerce orders.

A real case study: on April 3, a duplicate order was created just seconds after the previous one—same customer, same amount, same product. I had to refund the second order, which meant losing 3–4% in fees, and I could have lost a customer over this!

PHP Snippet: Return Error If “Same” Order Was Submit <2 Minutes Ago @ WooCommerce Checkout

This snippet hooks into the WooCommerce checkout process using woocommerce_checkout_process. The goal is to prevent customers from accidentally placing duplicate orders within a short time frame.

Inside the function, we first define a set of arguments to query recent orders. We look for a maximum of one order ('limit' => 1) placed by the same customer, using the billing email from the current checkout ($_POST['billing_email']).

We also check if the order was created within the last 2 minutes. This is done using 'date_created' => '>' . ( time() - 2 * MINUTE_IN_SECONDS ), which filters out older orders.

Next, we only consider orders that have a paid status, using wc_get_is_paid_statuses(). This ensures we’re not comparing against failed or pending orders.

We then match the total amount of the current cart with the order total ('total' => WC()->cart->get_total( 'edit' )) to confirm it’s an identical order.

Finally, the 'return' => 'ids' parameter makes the query more efficient by only retrieving order IDs.

If a matching order is found, we use wc_add_notice() to block the checkout and display an error message, advising the customer to wait before retrying.

/**
 * @snippet       WooCommerce Prevent Duplicate Order
 * @tutorial      https://businessbloomer.com/woocommerce-customization
 * @author        Rodolfo Melogli, Business Bloomer
 * @compatible    WooCommerce 9
 * @community     https://businessbloomer.com/club/
 */

add_action( 'woocommerce_checkout_process', 'bb_prevent_duplicate_orders' );

function bb_prevent_duplicate_orders() {
    $args = [
        'limit' => 1,
        'customer' => $_POST['billing_email'],
        'date_created' => '>' . ( time() - 2 * MINUTE_IN_SECONDS ),
        'status' => wc_get_is_paid_statuses(),
		  'total' => WC()->cart->get_total( 'edit' ),
		  'return' => 'ids',
    ];
    $orders = wc_get_orders( $args );
    if ( $orders ) {
    	wc_add_notice( __( 'It looks like you already placed this order recently. Please wait a minute before trying again.' ), 'error' );
    }
}

Where to add custom code?

You should place custom PHP in functions.php and custom CSS in style.css of your child theme: where to place WooCommerce customization?

This code still works, unless you report otherwise. To exclude conflicts, temporarily switch to the Storefront theme, disable all plugins except WooCommerce, and test the snippet again: WooCommerce troubleshooting 101

Related content

Rodolfo Melogli

Business Bloomer Founder

Author, WooCommerce expert and WordCamp speaker, Rodolfo has worked as an independent WooCommerce freelancer since 2011. His goal is to help entrepreneurs and developers overcome their WooCommerce nightmares. Rodolfo loves travelling, chasing tennis & soccer balls and, of course, wood fired oven pizza. Follow @rmelogli

2 thoughts on “WooCommerce: Prevent Duplicate Orders

  1. I have experienced this exact problem where customers accidentally double-submit orders. Your snippet is elegant and addresses the problem perfectly by checking for identical orders within that critical 2-minute window.
    I appreciate how you’ve targeted specific matching criteria (same email, paid status, identical total) rather than blocking all repeat purchases. The explanatory comments make implementation straightforward even for those with basic php knowledge. Thanks…

Questions? Feedback? Customization? Leave your comment now!
_____

If you are writing code, please wrap it like so: [php]code_here[/php]. Failure to complying with this, as well as going off topic or not using the English language will result in comment disapproval. You should expect a reply in about 2 weeks - this is a popular blog but I need to get paid work done first. Please consider joining the Business Bloomer Club to get quick WooCommerce support. Thank you!

Your email address will not be published. Required fields are marked *