If your WooCommerce store suddenly receives dozens or hundreds of failed orders, low-value transactions, or payment attempts using different cards, it may be under a card testing attack.

Card testing happens when attackers use a real checkout to find out which stolen card numbers still work. They are usually not interested in your products; they are using your payment form as the testing tool.

If the attack is active, focus first on reducing the number of automated attempts reaching your payment gateway. Then tighten the checkout without making it unnecessarily difficult for real customers.

1. Check Whether This Is Card Testing

Common signs include:

  • a sudden increase in failed WooCommerce orders
  • many low-value orders or payment attempts
  • different cards being tried with similar customer details
  • random names, email addresses, or billing information
  • many payment declines within a short period
  • unusual traffic to checkout endpoints
  • fraud alerts or unexpected payment-processing fees

Do not assume every failed order is an attack. Look for a sudden volume or pattern that does not match normal customer activity.

2. If the Attack Is Happening Right Now

Do not spend the first hour building custom rules. Start with controls that can reduce payment attempts quickly:

  1. Enable a WooCommerce card-testing or fake-order protection plugin.
  2. Review your payment gateway’s fraud controls.
  3. Enable checkout rate limiting.
  4. Add Turnstile or CAPTCHA if your checkout protection does not already include a bot challenge.
  5. Temporarily disable guest checkout if your store can tolerate it.
  6. Review very low-value, donation, or pay-what-you-want products that make cheap card testing possible.
  7. Review successful suspicious payments and refund fraudulent transactions promptly.
  8. Contact your payment provider if authorizations, disputes, or processing fees are accumulating.

Keep failed order and gateway logs while you investigate. Timestamps, IP addresses, customer details, user agents, and payment responses can help identify the attack pattern.

WooCommerce also maintains official guidance for responding to card testing attacks.

3. Use a WooCommerce Fake-Order and Card-Testing Protection Plugin

If you want a no-code solution, use a plugin designed specifically for checkout abuse rather than relying only on CAPTCHA.

Free Option: Checkout Shield for WooCommerce

Checkout Shield for WooCommerce is a WordPress.org plugin built specifically to stop fake orders, scripted checkout submissions, and card-testing bots.

It protects both classic WooCommerce checkout and Checkout Blocks. Its main checkout check verifies that a submission came through a real checkout visit instead of accepting a direct scripted request blindly.

It can also detect repeated payment failures, maintain blocklists, log blocked attempts, and handle visitors behind services such as Cloudflare.

The plugin is newer than long-established WooCommerce extensions, so test it with your checkout and payment methods before relying on it on a busy production store.

For most stores trying to stop direct fake-order or card-testing traffic without writing code, this is more relevant than installing a CAPTCHA-only plugin.

More Complete Option: Anti-Fraud for WooCommerce

If you need broader fraud controls rather than only bot protection, Anti-Fraud for WooCommerce is available through the WooCommerce ecosystem.

It adds fraud risk scoring, card-testing protection, payment and order attempt limits, checkout CAPTCHA, block and allow lists, and automated handling of suspicious orders.

This is a better fit when the problem includes both automated card testing and genuine-looking fraudulent orders that need risk evaluation.

What you needBetter starting point
Direct checkout bots and fake-order floodsCheckout Shield for WooCommerce
Card-testing attempt limits and broader fraud scoringAnti-Fraud for WooCommerce
Only a bot challenge on checkoutCloudflare Turnstile or reCAPTCHA
Payment-card risk and authorization controlsYour payment gateway’s fraud tools

Do not install several fraud plugins at once unless you understand how their checkout hooks interact. Multiple plugins blocking the same request can make failed legitimate orders much harder to diagnose.

4. Add Turnstile or CAPTCHA Where It Helps

CAPTCHA is useful, but it should be treated as one layer rather than the complete card-testing solution.

If your fraud plugin does not already include a challenge, one free option is Simple CAPTCHA with Cloudflare Turnstile.

After enabling checkout protection:

  1. open checkout in a private browser window
  2. place a test order
  3. confirm the challenge validates correctly
  4. verify that a failed challenge actually prevents checkout submission

Seeing a CAPTCHA or Turnstile widget on the page is not enough. The important part is whether invalid automated submissions are rejected.

Do not stack several CAPTCHA plugins on the same checkout. That can cause duplicate challenges, JavaScript conflicts, or failed legitimate orders.

5. Use Your Payment Gateway’s Fraud Controls

Your payment provider can see payment signals that WordPress cannot, so checkout protection should not stop at the website.

If you use Stripe, review its card-testing and Radar controls. Stripe recommends combining CAPTCHA, rate limiting, session validation, and Radar rules rather than relying on one measure.

See Stripe’s card testing guidance.

If you use WooPayments, review its fraud protection settings and the suspicious transactions generated during the attack.

With any payment provider, look for controls around:

  • repeated failed payment attempts
  • many cards tried by the same customer or session
  • unusually high order velocity
  • very low-value transactions
  • patterns your store would never normally accept

Do not copy aggressive fraud rules from another store without reviewing them. A rule that makes sense for a local retailer can block legitimate customers on an international store.

6. Rate-Limit Repeated Checkout Attempts

Card testing depends on volume. Limiting how quickly repeated checkout attempts can be submitted makes the store much less useful for testing cards.

If You Use WooCommerce Checkout Blocks

WooCommerce includes optional rate limiting for the Checkout Block and Store API.

For the checkout Place Order flow, check:

WooCommerce → Settings → Advanced → Features
→ Rate limiting Checkout block and Store API

WooCommerce documents the current configuration here:

WooCommerce Store API rate limiting

If your site is behind Cloudflare, another reverse proxy, or a load balancer, make sure WooCommerce is identifying the real visitor correctly before relying heavily on IP-based limits.

If You Use Classic Checkout

Classic checkout can be rate-limited at the CDN, web server, firewall, or WordPress security layer.

Apply limits conservatively. Real customers may retry a declined card, correct billing information, refresh checkout, or return from an external payment provider.

If you already use SiteFort, its rate limiting, firewall controls, and Cloudflare Sync can help reduce repeated abusive requests. Fraud decisions should still remain with WooPayments, Stripe, or your payment provider.

7. Advanced: Block Direct Classic Checkout Submissions

If you prefer a custom solution and your store still uses classic checkout, you can require a valid WooCommerce session token before an order submission is accepted.

This specifically helps with bots that send requests directly to checkout without loading the checkout page first.

It is not a complete fraud system. A bot that loads the real checkout page and maintains its session can still pass the check.

Do not use this code for WooCommerce Checkout Blocks. Blocks use the Store API and need Store API-compatible protection.

Add the code through a small custom plugin or trusted code snippets plugin and test it before deploying it to a live store.

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_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 ) . '" />';
}

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' )
);
}
}

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' );
}
}

If fake orders continue after adding session validation, check which requests are still reaching WooCommerce. The bots may be loading checkout normally, using Checkout Blocks or the Store API, rotating sessions, or attacking another payment flow.

8. Test Real Checkout Before You Finish

Any protection strong enough to stop bots can also stop customers if it is configured badly.

Test the checkout paths your store actually uses:

  • guest checkout
  • logged-in checkout
  • mobile checkout
  • your main payment gateway in test mode
  • coupons if you use them
  • Apple Pay, Google Pay, or other express payment methods
  • subscriptions or memberships if applicable

Then compare the attack traffic with what you saw before the changes.

You want fewer automated checkout and payment attempts without an increase in legitimate checkout failures.

If fake orders continue despite checkout protection, rate limiting, and gateway fraud controls, identify the exact checkout or payment endpoint still being abused before adding stricter rules. The logs should tell you what to fix next.