
A card testing attack is a script that runs stolen card numbers through your checkout to find out which ones still work. You see it as a burst of small orders or payment attempts, most of them declined, with customer names and email addresses that make no sense. The fraudster wants a yes or no from the card issuer, and your store supplies it.
To stop one, confirm the pattern in your payment dashboard, add friction to the endpoints the script uses (rate limits and a server-side CAPTCHA first), refund any test payments that went through, and keep watching declines for a few days, because attackers switch tactics once they get blocked. Do this before Black Friday on 27 November 2026. An attack in the middle of peak traffic is harder to see and more expensive to clean up.
Stripe's card testing documentation, as of October 2026, lists the consequences: disputes when some test payments succeed, a higher decline rate that can hurt your standing with issuers and card networks, extra fees, load on your infrastructure, and polluted business data, because test payments look like new customers. Stripe also says that firewall rules built on a single signal, such as IP address, are generally not enough.
On the card network side, Stripe's page on monitoring programs describes how Visa's VAMP monitors a merchant's disputes and fraud and, separately, its enumeration activity. Visa uses a machine learning model to identify enumerated authorization transactions and counts them whether the payment was approved or declined. An account lands on the "Excessive" enumeration list when it exceeds both 300,000 enumerated transactions and a 20% enumeration ratio. Visa does not fine for the enumeration list, but successful test charges that later become early fraud warnings or disputes count toward the separate VAMP ratio, which does carry fees. Most small stores will never get near 300,000 enumerated attempts. The dispute side is the part that reaches them.
For WooCommerce stores, the WooCommerce developer blog published a post on card testing and the Store API in December 2024. It says the Store API includes rate limiting that is off by default, that WooCommerce 9.6 added a stricter limit for the place-order endpoint you can enable from the settings screen, and that several CAPTCHA plugins needed patches to protect the Checkout block properly. If your CAPTCHA plugin was installed years ago and never rechecked, it may not cover the endpoint the bots call.
Timing matters too. Declines rise during a sale for ordinary reasons, so an attack that would be obvious on a quiet Tuesday blends in on Cyber Monday.
Steps 1 to 4 are the incident response. Steps 5 to 7 are preparation for this week, attack or not.
Confirm the pattern. Open your payment provider's dashboard and look at the last 24 hours. In Stripe, the signs are a spike in failed or blocked payments, a spike in requests returning 402 errors in the developer logs, and suspicious low-value payments with nonsense names or emails. In WooCommerce, the store side shows a sudden rise in orders with the Failed status. On any platform, check whether the attempts cluster on a single low-priced product or a single checkout path. On hosted checkouts such as Shopify you cannot rate-limit the checkout endpoint yourself, so the levers are the platform's fraud and bot settings, your payment provider's rules and the platform's support team.
Find the endpoint. Card testers rarely browse your site. Check server or CDN logs for POST requests to the checkout or payment endpoint with no preceding page views. On WooCommerce Blocks checkout that is POST /wc/store/v1/checkout. On a custom build it may be your own payment intent or "save card" endpoint. Stripe notes that card setup flows are a favourite target, because a card validation usually does not show up on the cardholder's statement.
Add friction to that endpoint. Turn on rate limiting and a CAPTCHA that is validated on the server, not only rendered in the browser. If the attack continues, Stripe's advice is to check that the CAPTCHA covers every request that can validate a card or create a payment, tighten the score threshold, or switch to a different CAPTCHA. Temporary measures are fine during an incident: hide the cheapest product, set a minimum order value, or require an account for checkout until the traffic stops.
Refund and cancel. Refund every successful payment you believe came from the test run, before the cardholder disputes it. WooCommerce's WooPayments documentation calls refunding suspected unauthorized orders "of the utmost importance" and says WooPayments support can issue bulk refunds when more than 20 such orders succeed. Do not retry the failed payments. Stripe warns that retrying fraudulent cards repeats the attack.
Tune gateway rules. If your provider supports custom rules, add velocity limits based on your real traffic. In Stripe Radar, custom rules depend on your Radar plan. Block rules that do not depend on issuer checks run before the payment reaches the card issuer, so the test never gets an answer.
Check for leaked keys. A card tester with your secret API key does not need your checkout at all. Rotate keys if anything looks off, and confirm no secret key sits in front-end code or a public repository.
Set an alert you will actually notice. The default signal on many stores is a "failed order" email per attempt, which people filter out within an hour. Alert on the rate instead: failed payments per hour against a normal baseline, sent to a channel someone watches during the sale.
| Control | Owner | What to check | Frequency |
|---|---|---|---|
| Checkout rate limiting (platform or CDN) | Developer or agency | Enabled on the actual place-order endpoint; proxy headers set if behind a CDN so real customers are not grouped under one IP | Before peak, after every checkout change |
| Server-side CAPTCHA | Developer or agency | Token verified on the server for every payment and card-save request, including headless and Blocks checkout | Before peak, after plugin updates |
| Gateway fraud rules (Radar, WooPayments fraud protection, PSP rules) | Store owner or ecommerce manager | Velocity rules present; CVC check failures blocked; rules reviewed against current product prices | Monthly; daily during peak |
| Failed-payment rate alert | Operations or agency | Alert fires on a test; reaches someone during sale hours | Weekly during peak |
| Refund queue for suspected tests | Store owner or support | Suspicious successful payments refunded the same day | Daily during an incident |
| API key hygiene | Developer | No secret keys in client code or repos; keys rotated after staff or agency changes | Quarterly |
Treat these as starting points and set thresholds from your own order history. A store that sells refill packs to returning customers will need higher limits than one selling furniture.
Stripe Radar custom rules (attribute names from Stripe's supported attributes list, as of October 2026):
Block if :card_count_for_ip_address_hourly: > 3
Block if :declined_charges_per_ip_address_hourly: > 5
Review if :email_count_for_ip_hourly: > 3
Block if :cvc_check: = 'fail'
Stripe's velocity counts exclude the payment being evaluated, so > 3 blocks the fifth card from the same IP within roughly an hour. Stripe notes that wallets such as Apple Pay typically do not provide a CVC, which is why it recommends its built-in rules for CVC handling. Test any CVC rule in preview before you enable it.
WooCommerce Store API rate limit, set in a small custom plugin or a code snippets plugin:
add_filter( 'woocommerce_store_api_rate_limit_options', function() {
return [
'enabled' => true,
'proxy_support' => true, // only if the store sits behind a proxy or CDN that sets X-Forwarded-For
'limit' => 25,
'seconds' => 10,
];
} );
The values above are WooCommerce's documented defaults with the feature switched on. For the place-order endpoint only, the setting at WooCommerce > Settings > Advanced > Features ("Rate limiting Checkout block and Store API") applies a much stricter limit of three requests per 60 seconds to POST /checkout and the Checkout block's Place Order flow. WooCommerce's documentation describes this setting for the Checkout block. If your store still uses the classic shortcode checkout, test whether your payment plugin and CAPTCHA cover that path.
Incident checklist to paste into your runbook:
[ ] Confirm: failed/declined payments per hour vs normal, last 24h
[ ] Identify endpoint and product targeted (logs, gateway dashboard)
[ ] Enable/tighten rate limit on that endpoint
[ ] Confirm CAPTCHA is verified server-side on that endpoint
[ ] Temporary friction if needed: hide cheapest SKU, minimum order, require login
[ ] Refund successful test payments; do not retry failed ones
[ ] Add or tighten gateway velocity rules
[ ] Check API keys are not exposed; rotate if in doubt
[ ] Watch declines for 72h; attackers change pattern after a block
[ ] Note what happened and which control worked
A small homeware store on WooCommerce normally sees about 4 failed payments an hour on a weekday. At 02:00 on a Sunday the count reaches 180 in an hour, almost all on a sample product priced at 2.00, each with a different billing name. The owner is asleep. By morning there are about 1,100 failed orders and 9 successful 2.00 payments. All numbers here are invented for illustration.
The agency that maintains the store enables the place-order rate limit from the WooCommerce Features screen, confirms the CAPTCHA plugin is a version that validates Store API requests, and sets the sample product to private. Failed orders fall back to single digits within an hour. The owner refunds the 9 successful payments the same morning. Two days later a smaller burst hits a different product, and a Radar rule on cards per IP stops it at the gateway. The agency adds an hourly failed-payment alert so the next attack reaches someone at 02:00, not at 09:00.
Limitations: no control set stops every card testing attempt, and every layer of friction costs some real conversions. A visible CAPTCHA on every checkout during a flash sale will lose some buyers. Balance the two with the approach in fraud controls vs conversion, and loosen temporary measures once the attack stops.
Card testing is fraud in which someone holding stolen card details runs small payments or card validations through a store to learn which cards are still valid. Stripe notes it is also called carding, account testing, enumeration or card checking.
It depends on your payment provider and pricing plan. Stripe lists possible additional fees, such as authentication fees on custom pricing plans and dispute fees. Check your provider's pricing page and ask support during an incident.
Usually not. The attacker uses your public checkout the way a customer would, only at machine speed. If you see payments created outside your checkout, or the attack bypasses all front-end controls, check whether your secret API key has leaked. If you find signs of a compromise, follow what to do when a client site returns 200 but is hacked.
Last reviewed: 2026-10-16
If your stores run on WooCommerce, Pingvera's WordPress connector sends order.created and order.failed events in real time and places them on one timeline next to deploys and incidents, so a 2 a.m. wall of failed orders shows up next to the plugin update that preceded it. Its order-anomaly detection alerts when the site is up but orders stop arriving, which covers the opposite case: a fix so strict it blocks real buyers. More on reading failed-order patterns in WooCommerce failed orders: what a spike, a stall and a silence each mean.
Pingvera watches whether an online business actually works — uptime, checkout, orders, domain, SSL and server — and alerts you in Telegram, email or a webhook before a customer has to tell you.
Start freeRead next: Website Stress Test Before Black Friday: Store Plan · Black Friday Code Freeze 2026: What to Lock and Still Patch · Know your client's site is down before they call · Update PHP on WordPress: WooCommerce Plan Before 11.6 · Run a free site check.