How do you know the failed orders are card testing?
Look at the pattern, not at any single order. One failed payment is a customer with an expired card. Hundreds of failed or pending orders placed within a few hours, with small totals and email addresses nobody recognises, are bots running card numbers through your checkout to see which ones work.
The giveaway is usually in the details you can see on each order: the billing email, the customer’s IP address and the country. A real customer who fails twice tries again with the same email. A bot rarely does. Our attack report, covered below, counts the distinct emails, IP addresses and countries behind a batch of orders, and that count is the quickest way to tell the two apart.
We built this guide on a test store where we seeded 541 failed and pending orders from a made-up attack. Every number here comes from that store, and the screens are the real ones.
Why is clearing them by hand such a slog?
WooCommerce’s Orders screen lets you select orders and move them to the trash, but only the ones on the page in front of you. Tens of thousands of orders means hundreds of rounds of select all, move to trash and wait. Meanwhile the junk sits between you and the orders you want to ship.
It is also easy to get wrong. If you filter by status and clear everything, you can take a real order with it: a customer who failed once, retried, and paid. That is the part worth getting right.
Which orders should you never clear?
Four kinds, and Failed & Spam Order Cleaner leaves all of them alone even when they match your filters.
- Orders that were paid at some point. An order with a recorded payment date took real money, whatever status it is in now. This protection is a checkbox on the Settings tab, called Never touch orders that have a recorded payment, and it is on by default. Leave it on.
- Orders linked to a WooCommerce Subscriptions subscription. Parent and renewal orders keep their history. This applies when WooCommerce Subscriptions is active on the site.
- Orders from the last hour. A customer may still be filling in their card details. The Skip orders created in the last hour option on the Clean Up tab is ticked by default.
- Orders that changed status after you previewed. If a customer pays between the preview and the run, that order is no longer in a status you chose, so it is skipped.
On our test store, one of the 541 orders was a failed order that had once been paid. The preview counted 540.
Which statuses should you tick?
Start with Failed only. It is the one ticked by default, and it is where most card-testing orders end up. Add Pending payment and Draft (abandoned checkout) when the first run looks right.
Be careful with On hold. Plenty of shops use it for real bank-transfer and cheque orders that simply haven’t been paid yet, and those are not junk.

Set the date range to match the attack. If it started on Tuesday night, choose Tuesday to now rather than All time. The quick ranges (Last 24 hours, Last 7 days, Last 30 days, Older than 30 days, All time) fill the dates in for you.
How do you check what will be cleared before anything changes?
Click Preview matching orders. Nothing is changed. You get the number of orders the cleanup will act on, split by status, and the newest matches with their date, email, IP address and total. Click an order number to open it.

Read the newest few. If any of them look like a customer you’d recognise, narrow the filters before you go on. The count already leaves out the orders listed above, which is why ours said 540 and not 541.
Should you move orders to the trash or delete them?
Trash them first. Move to trash is the default, and it is what makes the whole run reversible. Orders go to WooCommerce’s trash, where you can look at them and bring them back.

Deleting permanently removes the orders, their notes and their line items from the database. The plugin asks you to tick a box and type DELETE, and the server checks both again, so it can’t be skipped by accident. One catch: if your site has the trash switched off (EMPTY_TRASH_DAYS set to 0), WordPress would delete trashed orders straight away, so the screen only offers permanent deletion. Take a backup before you use it.
When you click Clean Up, the work runs in the background through Action Scheduler, which comes with WooCommerce. Each batch stops after a short time budget (15 seconds by default) so it doesn’t hit the timeouts the Orders screen runs into, and you can leave the page and come back through the Activity Log. Our 540 test orders took about a minute. A big cleanup on shared hosting takes longer, but it keeps moving.
What does the attack report tell you?
When a cleanup finishes, the page turns into a report. The four numbers at the top are the orders handled and the distinct email addresses, IP addresses and countries behind them.

How you read them matters. A handful of emails and IP addresses behind thousands of orders points to one bot, and blocking that IP at your host or firewall may help for a while. Hundreds of each, like our 201 emails and 151 IPs, points to a spread-out attack, and blocking individual addresses will not keep up. Emails are compared without case, so Bot@Example.com and bot@example.com count once.

Export attack report (CSV) downloads the full list of emails, IP addresses and countries with the number of orders each one placed. It opens in Excel or Google Sheets, so you can hand it to your host, your payment provider or your developer.
One setting to know about: the per-email and per-IP lists are deleted after 90 days by default (Settings, Keep email / IP breakdowns for). The summary numbers stay in the Activity Log. If you want the full lists to outlast that, export the CSV the same day, or set the value to 0 to keep them until you delete them yourself.
What if you cleared too much?
If you moved the orders to the trash, you can undo the whole run. Open the report and use Restore these orders from the trash. Every order from that run goes back in the status it had, and large restores run in the background in batches too.

The same panel has the permanent option, Delete these trashed orders permanently, with the same tick box and DELETE check. WordPress empties the trash after its usual period, so if you think you might want something back, don’t leave it long. Permanently deleted orders can’t be restored.
What won’t a cleanup do?
It cleans up after an attack. It does not stop the next one. There is no CAPTCHA, rate limiting or fraud scoring, and it never blocks an email or IP address on its own, because attackers change both between runs. Deleting an order here also doesn’t remove data already sent to Stripe, PayPal, a shipping service or an email tool. You manage that in each service.
So use it alongside something that stops the traffic: a bot-blocking or anti-fraud plugin, your payment provider’s own fraud settings, or a rule at your host. The report is useful there too. It tells you which countries and addresses to look at first.
What should you do first?
- Preview a narrow range. Failed only, from the start of the attack to now, and read the newest orders.
- Move to trash. Check the report and the trash, and confirm no real order is in there.
- Widen it. Add Pending payment and Draft, or an older date range, for the next run.
- Delete for good last. Only after you’ve looked at the trash, and only if you don’t need the orders back.
- Then deal with the cause. Put bot blocking or fraud checks in place, or the same orders will be back next week.
Failed & Spam Order Cleaner for WooCommerce. Clear the failed and pending orders a card-testing attack leaves behind, in the background, trash first, with a report on who sent them.
View the add-on