Skip to content
pluginloom

Guide

WooCommerce Card Testing: How to Stop It on Classic and Block Checkout

What WooCommerce card testing is, why attackers target the Store API checkout endpoint, what WooCommerce core already offers, and the limits, challenges and checks that stop it.

By the PluginLoom teamLast updated 5 sources

Card testing is when someone uses your WooCommerce checkout to try stolen card numbers until they find ones that work. The fix is to count failed payments where they happen, on both the classic checkout and the Store API, and block the shopper, network, browser or card that keeps failing. This guide explains how the attacks work in 2026, what WooCommerce core already does, and a setup that stops them without blocking real customers.

What does a card-testing attack look like?#

You usually notice it after the fact:

  • dozens or hundreds of Failed orders in minutes, often for your cheapest product;
  • many different names and emails, sometimes with +tags or dots in Gmail addresses;
  • one or a few IP networks, or IP addresses that change every order;
  • gateway fees for declined charges, and later, disputes for the few cards that worked.

A third-party fraud extension's documentation on woocommerce.com describes stores receiving "hundreds or thousands of fake transactions, often within minutes" (Velocity Attacks (opens in a new tab), checked 24 October 2026).

Why do attackers hit the Store API?#

WooCommerce has two ways to place an order:

CheckoutEndpoint
Classic ([woocommerce_checkout])POST /?wc-ajax=checkout, with a nonce from the checkout page
Checkout blockPOST /wp-json/wc/store/v1/checkout, the Store API

The Store API takes the whole order as JSON, so a script can call it directly without loading any page. WooCommerce's developer blog wrote on 18 December 2024: "Recently we have seen card attacks specifically targeting the Store API alone, even without the use of the Checkout block" (source (opens in a new tab)). The same post found that many captcha plugins "were not protecting the Checkout Block/Store API", so their checks were bypassed.

The endpoint exists on every store with WooCommerce active, whether or not you use the Checkout block, so protecting only the classic checkout leaves the door open.

What does WooCommerce core already do?#

Core has rate limiting for the Store API, documented at Store API rate limiting (opens in a new tab) (checked 24 October 2026):

FeatureDefaultNotes
Store API rate limiterOffWhen turned on with the woocommerce_store_api_rate_limit_options filter: 25 requests per 10 seconds, per user ID or IP
"Rate limit Checkout" feature (WooCommerce 9.6+)OffSettings > Advanced > Features. Limits POST /wc/store/v1/checkout to 3 requests per 60 seconds
Custom identifier (WooCommerce 9.8+)nonewoocommerce_store_api_rate_limit_id lets you limit by your own fingerprint instead of IP
Response when limitedHTTP 429, RateLimit-* headers, action woocommerce_store_api_rate_limit_exceeded

Turn on "Rate limit Checkout". It costs nothing. But know its limits:

  • It counts requests, not failed payments, so it treats a careful attacker and a real shopper the same.
  • It is per user or IP, and attackers rotate IPs.
  • Core has no rate limit on the classic checkout or the pay for order page. In the WooCommerce source, the only checkout rate limits are in the Store API.

What actually stops card testing?#

Four layers, in order of how much they matter:

1. Count failed payments, several ways#

Block when a shopper reaches a number of failed payments in a window, counted per IP address, per network (/24 for IPv4, /64 for IPv6), per normalised email, per browser, per card BIN and last four (where the gateway exposes them), and per session. A botnet that rotates IP addresses usually shares a network, a browser setup or the card list it is testing.

Starting points we use: 5 failures per IP in 10 minutes, 12 per network in 10 minutes, 4 per email in an hour, 3 per card in an hour. The third-party extension above suggests 3 to 5 attempts in a 300-second window and 10 per hour.

2. Cover every entry point#

The classic checkout, the Store API checkout, the pay for order page (/checkout/order-pay/) and the Store API pay for order route (/wc/store/v1/checkout/{id}), plus the saved-card form in My account.

3. Challenge only when risk is elevated#

A captcha on every checkout costs you sales. Show Cloudflare Turnstile or hCaptcha only to shoppers halfway to a limit, and to everyone during an active attack. Make sure the token is checked on the Store API request itself, not just on the page.

4. Have an emergency switch#

When failed payments spike store-wide, tighten every limit, challenge every checkout and refuse checkouts that did not run your checkout page's script (attack scripts calling the API directly do not).

What about the payment gateway's own tools?#

Use them too. WooPayments saves a fraud outcome (allow, review, block) and Stripe's risk level on each order, as _wcpay_fraud_outcome_status and _charge_risk_level in its source code. PayPal Payments ships reCAPTCHA. Gateway checks happen after the card reaches the gateway, which is after you have paid for the attempt, so block at checkout first and use gateway data to score the orders that get through.

How do I clean up after an attack?#

  1. Turn on your emergency mode, or temporarily disable the gateway being abused.
  2. Bulk-cancel the failed orders and check for any successful ones from the same networks or emails. Refund those before they become disputes.
  3. Tell your payment provider. Card testing can affect your account standing.
  4. Keep the blocklist entries the attack created for at least a day.

How ChargeWarden handles it#

ChargeWarden applies all four layers on the classic checkout, the Store API, the pay for order page and the add payment method form, builds on WooCommerce's own rate limiter instead of replacing it, and scores orders with written reasons. In our test run against a demo store on 24 October 2026, single-IP attacks were blocked after 5 failures on both checkouts, a 40-address botnet in one network after 12, and every real customer still paid. See how the limits work.

Sources#

Checked October 24, 2026.

Frequently asked questions

What is card testing in WooCommerce?

Card testing is when someone uses your checkout to try many stolen card numbers, usually with small orders, to learn which cards still work. You see bursts of failed orders, gateway fees and sometimes disputes.

Why do card testers use the Store API?

The Store API checkout endpoint (POST /wp-json/wc/store/v1/checkout) accepts orders as JSON without loading the checkout page. WooCommerce's developer blog reported on 18 December 2024 attacks targeting the Store API even on stores that do not use the Checkout block.

Does WooCommerce have built-in card testing protection?

WooCommerce core has an optional Store API rate limiter, off by default, and since version 9.6 a 'Rate limit Checkout' feature that limits POST /wc/store/v1/checkout to 3 requests per 60 seconds. Core has no rate limit on the classic checkout.

Is a captcha enough?

Only if it also validates Store API requests. WooCommerce found in December 2024 that many captcha plugins were not protecting the Checkout block or Store API, so invalid captcha checks were bypassed.

Should I block by IP address?

IP limits help but are not enough on their own, because attackers rotate addresses. Count failures per network, email, browser and card too.

Sources

The date shows when we last checked that the source still says what we say it says.

  1. WooCommerce Developer Blog: Card Testing Attacks and the Store API (18 Dec 2024), developer.woocommerce.com. Checked 2026-10-24
  2. WooCommerce Docs: Store API rate limiting, developer.woocommerce.com. Checked 2026-10-24
  3. WooCommerce source: StoreApi/Utilities/RateLimits.php and Authentication.php (trunk 8881dc3), github.com. Checked 2026-10-24
  4. Anti-Fraud for WooCommerce: Velocity Attacks (third-party extension docs), woocommerce.com. Checked 2026-10-24
  5. WooPayments source: class-wc-payments-order-service.php (11.2.0), github.com. Checked 2026-10-24