Fake orders in WooCommerce
Bots test stolen card numbers through your checkout. How to stop them without locking out real customers.
- You need
- WP admin
- Updated
A burst of orders with random names and email addresses, most of them with the status "Failed", is a card testing attack. Bots use your checkout to try stolen card numbers to find out which cards work. The order notes show whether the cards were declined.
Your shop isn't hacked, but the checkout is being used as a testing tool. You stop the attack by limiting the number of attempts and adding a bot check to the checkout. Real customers barely notice the difference.
Do this right away
- Go to WooCommerce → Orders and review the orders that actually went through. Don't ship anything, and refund the orders you believe are fraudulent as quickly as possible. That reduces the risk of disputes.
- Bots prefer cheap products, donations and pay-what-you-want products. Make them unavailable until the attack is over.
- Contact your payment provider early. Many declined payments in a short time can make the provider restrict your account, and they can turn on stricter fraud rules.
If the attack is still going on, you can turn off guest checkout for a period. Go to WooCommerce → Settings → Accounts & Privacy, untick "Enable guest checkout (recommended)" and click "Save changes". Customers then have to create an account, so turn guest checkout back on when the attack is over.
Limit attempts at checkout
Since WooCommerce 9.6 you can limit how many orders the same visitor can place in a short time.
- Go to WooCommerce → Settings → Advanced → Features.
- Tick "Rate limit Checkout" and click "Save changes".
The limit is three attempts per minute, so an ordinary customer will almost never notice it. It only applies when the checkout page uses the Checkout block, not the older [woocommerce_checkout] shortcode.
For visitors who aren't logged in, the limit is counted per IP address. If the shop is behind Cloudflare or another proxy and the server doesn't get the real IP address, WordPress only sees the proxy's addresses, and many customers share the same limit. In that case, turn on proxy support, for example in a small plugin or in your child theme's functions.php:
add_filter( 'woocommerce_store_api_rate_limit_options', function ( $options ) {
$options['proxy_support'] = true;
return $options;
} );
Only turn this on if the shop really is behind a proxy. Otherwise bots can bypass the limit with spoofed IP addresses. The limit and proxy support are described in the WooCommerce rate limiting documentation.
Add a bot check to the checkout
A bot check stops automated orders. Cloudflare Turnstile checks the browser in the background, so most real customers never have to solve a CAPTCHA. There are plugins that add Turnstile or Google reCAPTCHA to the WooCommerce checkout.
If your payment provider has its own fraud protection, such as Stripe Radar, turn it on and ask what they recommend. WooCommerce also has its own guide to card testing.
Clean up the order list
Review the list before you delete anything, so you don't remove orders from real customers whose card was simply declined.
- Go to WooCommerce → Orders and click "Failed" above the list.
- Select the orders, choose "Move to Trash" under "Bulk actions" and click "Apply".
If the attack continues
If orders keep coming with the limit and the bot check in place, the bots are bypassing them, for example by switching IP address for every attempt. In that case the traffic has to be stopped before it reaches WordPress, for example in Cloudflare's firewall or your host's. That requires access to the DNS or the hosting panel, and someone who can read the access logs.