If your WooCommerce store suddenly receives a wave of fake orders, failed payments, or very small test transactions, your checkout may be under a card testing attack.
Card testing happens when bots try stolen card numbers against a real payment form to see which cards are still valid. WooCommerce stores are common targets because checkout pages are public and easy to automate.
The damage is not limited to fake orders. Card testing can create payment gateway fees, fraud alerts, failed order spam, higher server load, damaged merchant reputation, and in some cases account review from your payment processor.
This guide explains how card testing works in WooCommerce, why CAPTCHA alone may not stop it, and how to block direct checkout abuse using session validation, rate limiting, payment rules, and gateway-level fraud controls.
Signs Your WooCommerce Store Is Being Used for Card Testing
You may be seeing a card testing attack if you notice:
- Many failed WooCommerce orders in a short time
- Repeated small transactions, such as $0.00, $1.00, or low-value product orders
- Many different card attempts from similar checkout details
- Orders using random names, emails, or addresses
- Many failed payments in Stripe, WooPayments, PayPal, Braintree, Authorize.net, or another gateway
- High traffic to checkout endpoints but no matching real customer behavior
- Repeated POST requests to checkout or Store API endpoints
- Hosting CPU spikes during the fake order wave
If the attack is active, do not only delete the fake orders. You need to reduce access to the checkout flow before more card attempts reach the payment gateway.
Why CAPTCHA Alone May Not Stop Fake Orders
CAPTCHA can help, but it is not always enough.
Many WooCommerce bots do not browse the store like a normal customer. They may skip the visual checkout page and send automated requests directly to a checkout endpoint.
For classic WooCommerce checkout, attackers often target:
/?wc-ajax=checkout
/checkout/?wc-ajax=checkout
For stores using WooCommerce Cart and Checkout Blocks, checkout behavior may involve the WooCommerce Store API. WooCommerce describes the Store API as public, unauthenticated endpoints used for customer-facing cart, checkout, and product functionality.
That means you need layered protection. Stripe recommends mitigations such as CAPTCHA, rate limits, limiting access to the payment form, and requiring login or session validation for sensitive actions.
The Direct Checkout Request Problem
A normal customer usually follows this path:
- Visits a product page
- Adds an item to cart
- Loads the cart or checkout page
- Fills billing details
- Clicks Place Order
A card testing bot may skip most of that flow and send a direct checkout request with fake customer and payment data.
If your protection only runs in the browser, the bot may avoid it. That is why server-side checks are important.
A Better Defense: Session-Based Checkout Validation
One practical way to reduce direct checkout abuse is to require proof that the visitor actually loaded the checkout page before submitting the order.
The idea is simple:
- When a real visitor loads the checkout page, WooCommerce creates a short-lived checkout token in their session.
- The checkout form includes that token as a hidden field.
- When the order is submitted, the server checks whether the submitted token matches the session token.
- If the token is missing or invalid, the order is blocked before payment processing.
This does not stop every advanced bot. A bot that fully loads the checkout page and preserves cookies may still pass this check. But it can block many direct POST attacks that hit checkout endpoints without first creating a valid customer session.
Important Notes Before Using the Code
The code below is intended for the classic WooCommerce checkout shortcode flow.
Use it only if your checkout page uses the traditional WooCommerce checkout form. If your store uses the newer Checkout Block, this exact hook-based approach may not apply because the checkout flow uses the Store API. For Checkout Blocks, focus on Store API-aware rate limiting, CAPTCHA support, gateway fraud rules, and firewall rules.
Also test this on staging first. Checkout customizations can affect payment gateways, subscriptions, express checkout buttons, Apple Pay, Google Pay, and custom checkout plugins.
Code: Block Direct WooCommerce Checkout Submissions
Add this code to a small custom plugin or a code snippets plugin. A custom plugin is usually safer than adding it directly to the theme’s functions.php, because theme updates or theme changes can remove the protection.
/**
* WooCommerce checkout session validation.
*
* Helps block direct bot submissions to the classic checkout endpoint
* by requiring a short-lived token created when the checkout page loads.
*
* Test on staging before using on production.
*/
/**
* Create a short-lived checkout token when the classic checkout form loads.
*/add_action( 'woocommerce_before_checkout_form', 'swp_set_checkout_session_token', 5 );
function swp_set_checkout_session_token() {
if ( ! function_exists( 'WC' ) || ! WC()->session ) {
return;
}
$token = wp_generate_password( 32, false, false );
WC()->session->set( 'swp_checkout_token', $token );
WC()->session->set( 'swp_checkout_token_time', time() );
}
/**
* Add the token as a hidden field inside the checkout form.
*/add_action( 'woocommerce_review_order_before_submit', 'swp_add_checkout_session_token_field' );
function swp_add_checkout_session_token_field() {
if ( ! function_exists( 'WC' ) || ! WC()->session ) {
return;
}
$token = WC()->session->get( 'swp_checkout_token' );
if ( empty( $token ) ) {
return;
}
echo '<input type="hidden" name="swp_checkout_token" value="' . esc_attr( $token ) . '" />';
}
/**
* Validate the token before WooCommerce processes the order.
*/add_action( 'woocommerce_after_checkout_validation', 'swp_validate_checkout_session_token', 10, 2 );
function swp_validate_checkout_session_token( $data, $errors ) {
if ( ! function_exists( 'WC' ) || ! WC()->session ) {
$errors->add(
'swp_checkout_session_missing',
__( 'Your checkout session could not be verified. Please refresh the checkout page and try again.', 'woocommerce' )
);
return;
}
$session_token = WC()->session->get( 'swp_checkout_token' );
$token_time = absint( WC()->session->get( 'swp_checkout_token_time' ) );
$posted_token = isset( $_POST['swp_checkout_token'] )
? sanitize_text_field( wp_unslash( $_POST['swp_checkout_token'] ) )
: '';
$max_age = 30 * MINUTE_IN_SECONDS;
if (
empty( $session_token ) ||
empty( $posted_token ) ||
! hash_equals( $session_token, $posted_token ) ||
empty( $token_time ) ||
( time() - $token_time ) > $max_age
) {
$errors->add(
'swp_checkout_session_invalid',
__( 'Your checkout session expired or could not be verified. Please refresh the checkout page and try again.', 'woocommerce' )
);
}
}
/**
* Clear the token after order completion to reduce reuse.
*/add_action( 'woocommerce_thankyou', 'swp_clear_checkout_session_token' );
function swp_clear_checkout_session_token( $order_id ) {
if ( function_exists( 'WC' ) && WC()->session ) {
WC()->session->__unset( 'swp_checkout_token' );
WC()->session->__unset( 'swp_checkout_token_time' );
}
}
Why This Helps Stop Fake Orders
This check happens on the server before the order is allowed to continue.
A direct bot request that skips the checkout page will not have the expected session token. When that happens, WooCommerce returns a validation error instead of sending the payment attempt to the gateway.
That can help reduce:
- Fake failed orders
- Payment gateway authorization attempts
- Card testing noise
- Checkout endpoint abuse
- Server load from automated checkout requests
This is not a complete anti-fraud system. It is one useful gate in a layered defense.
If You Use WooCommerce Checkout Blocks
If your store uses the Checkout Block instead of the classic shortcode checkout, do not rely on the code above as your main protection.
WooCommerce has specifically discussed card testing attacks involving the Store API and notes that rate limiting and CAPTCHA are two effective mitigation tools for Store API card testing.
For Checkout Blocks, focus on:
- Rate limiting checkout and Store API requests
- Using CAPTCHA support compatible with your checkout flow
- Gateway-level fraud rules
- Blocking repeated abusive IPs or patterns
- Monitoring failed payment attempts
- Temporarily requiring accounts for checkout during an active attack
Add Rate Limiting to Checkout Requests
Rate limiting is one of the most important defenses against card testing.
It prevents one IP address, IP range, session, or pattern from submitting too many checkout attempts in a short time.
Consider rate limiting:
/?wc-ajax=checkout/checkout//wp-json/wc/store/v1/checkout/wp-json/wc/store/v1/cart- Payment method setup endpoints
- Account registration endpoints
Be careful not to make rules too aggressive. Real customers may refresh checkout, fail a card once, update billing details, or use express payment methods. Start with moderate limits and review logs before tightening rules.
Use Payment Gateway Fraud Rules
Your payment processor may already provide tools for card testing protection.
Stripe recommends using a combination of mitigations for card testing, including CAPTCHA, rate limiting, limiting access to payment forms, and Radar rules for suspicious behavior.
For Stripe or WooPayments, consider rules that watch for:
- Too many failed attempts from the same customer or IP
- Too many cards used by the same customer
- Very small transaction amounts
- High-risk countries where you do not sell
- Mismatch between billing country and card country
- Repeated failures before one success
WooPayments also documents fraud protection rules that can block suspicious orders before the customer is charged, including examples for blocking very low-value orders during an attack.
Emergency Steps During an Active Attack
If the attack is happening right now, take fast action first. You can refine the setup later.
- Temporarily disable guest checkout if your store can tolerate it.
- Enable CAPTCHA on checkout, login, registration, and account creation where supported.
- Apply rate limits to checkout, Store API, login, and registration endpoints.
- Block obvious abusive IPs and user agents, but avoid blocking legitimate payment gateways or search engines.
- Raise minimum order value temporarily if bots are using very low-value products.
- Enable gateway fraud rules for repeated failed attempts and suspicious card patterns.
- Watch failed payment logs to confirm the attack is slowing down.
- Contact your payment processor if authorizations or fees are piling up.
Do not delete evidence too quickly. Failed order details, IPs, user agents, timestamps, and payment gateway logs help you identify the pattern.
Where SiteFort Can Help
This is one place where a WordPress security plugin can help, but it should be part of a wider checkout protection plan.
SiteFort can help reduce bot-driven checkout abuse with firewall rules, rate limiting, bot blocking, IP and user-agent blocking, login protection, audit logs, and Cloudflare Sync for selected block rules.
For WooCommerce card testing, the most useful layer is usually rate limiting and blocking repeated abusive patterns before they keep reaching checkout. Gateway fraud rules should still be configured separately inside your payment processor.
Test Carefully After Adding Protection
Checkout security changes should always be tested.
Place test orders using:
- A normal product
- A coupon if your store uses coupons
- Guest checkout if enabled
- Logged-in checkout
- Mobile checkout
- Stripe/PayPal test mode
- Apple Pay, Google Pay, or express checkout if enabled
- Subscription or membership checkout if used
Make sure legitimate customers can still complete checkout without confusing errors.
Long-Term Prevention Checklist
- Keep WooCommerce, payment gateway plugins, and WordPress updated.
- Use payment gateway fraud tools such as Stripe Radar or WooPayments fraud rules.
- Rate-limit checkout, Store API, login, and registration endpoints.
- Use CAPTCHA where it fits the checkout flow.
- Consider session validation for classic checkout.
- Disable guest checkout temporarily during severe attacks if needed.
- Use 2FA for store administrators.
- Monitor failed payment attempts and unusual order patterns.
- Block repeated abusive IPs, user agents, or countries only when the pattern is clear.
- Keep logs long enough to investigate attacks.
- Review low-value products that make card testing cheap.
- Use Cloudflare or another edge firewall to reduce repeated automated requests.
Final Thoughts
WooCommerce fake orders and card testing attacks are not just a spam problem. They can create payment gateway fees, failed order noise, fraud risk, server load, and merchant account problems.
CAPTCHA can help, but it should not be your only defense. Bots may bypass the visible checkout page and submit directly to checkout or Store API endpoints.
A better approach is layered: session validation for classic checkout, rate limiting for checkout endpoints, CAPTCHA where supported, payment gateway fraud rules, bot blocking, and careful monitoring of failed payment patterns.
If the attack is active, start with emergency controls to slow it down. Then test your checkout carefully so real customers are not blocked while bots are.