Notes
What a BIN attack looks like in a WooCommerce order list
A BIN attack fixes one bank's card range and varies everything else. Here is what that leaves behind in your own order data, and what it does not.
6 min read
A BIN attack is card testing with one very particular shape. Someone picks a single bank's card range, generates thousands of candidate numbers inside it, and pushes them at a live payment form to see which ones an issuer will approve. So your checkout becomes the test rig. Then the wreckage lands in your order list, where it leaves a signature you can learn to read.
Worth knowing before anything else. A BIN attack fixes the leading digits of the card number and varies everything else. Also, none of the mechanism is secret. Both card schemes and gateways describe it in plain language.
What the card schemes call it
Visa's 2021 best practice notice for acquirers, processors and merchants sets the mechanism out directly. It describes an enumeration attack as "a scheme where fraudsters systematically submit card-not-present (CNP) authorization attempts, while concentrating on a single Bank Identification Number (BIN) or multiple BINs and iterating through various combinations of payment values". Those values, the notice adds, "generally include the primary account number (PAN), expiration date, Card Verification Value 2 (CVV2), and postal code".
So a BIN attack has two halves. One part stays fixed, and that part is the BIN. Another part varies, and a script walks through it.
Then the arithmetic does the rest. Issuers decline until a combination lands, and an approval tells the attacker the card is live. Visa's guidance to guard against enumeration attacks also calls this a brute force attack, which is exactly what it is.
What a BIN actually is
The PCI Security Standards Council gives the definition in one sentence: "The BIN, which is used to identify the institution that issued the card, has traditionally composed the first six digits of the Primary Account Number (PAN)." Six is no longer the only length. As the same post on 8-digit BINs records, the ISO standard "now also defines a format for the use of 8-digit BINs as an alternative to 6-digit BINs".
For an attacker that fixed prefix is a shortcut. Cards sharing a BIN share an issuer, a country and a product type. So one BIN cuts the search space down hard, and it also picks the victim. If a particular issuer declines slowly or checks CVV loosely, its range is worth more attempts than a stricter bank's. Hence a BIN attack usually stays on one prefix until that prefix stops paying.
Why the generated numbers still look real
Card numbers carry a check digit, so any number either satisfies the Luhn formula or fails it. Stripe's testing documentation shows the deliberate failure case: "Use a card number that fails the Luhn check, such as 4242424242424241". Change that last digit and the same number passes.
Because a Luhn-valid number is trivial to generate, no front end can filter these out. Your checkout's own validation accepts them and posts them on. Every attempt therefore reaches your gateway, and every one costs somebody something to make. Notably, that is the whole economics of a BIN attack: cheap for the attacker, billable for you.
What a BIN attack looks like in your order list
Now the part you can act on. Ordinary declines scatter. Different hours, different baskets, different people. A BIN attack clusters instead, and the signals only mean much together:
- Dozens of attempts inside a few minutes, often from one or two addresses.
- Small basket totals, frequently identical. Visa's enumeration mitigation guide for merchants notes that attack transactions "are often less than $10 USD".
- Expiry dates and CVV values that change while the card range does not.
- Names and email addresses that read like filler. Stripe lists "A spike in suspicious payments with low transaction amounts, often with nonsensical customer names and emails" among the symptoms in its card testing prevention guide.
- One product, or one shipping country, over and over.
Those signals overlap heavily with card testing generally, which spotting card testing in your own order data covers at length. Specifically, the BIN dimension adds the one thing that note cannot: shared leading digits.
The digits your store probably does not hold
Here is the honest limit. Your store almost certainly cannot see the BIN at all. WooCommerce's PCI-DSS compliance documentation is blunt: "WooCommerce never stores card details, and official WooCommerce payment gateways only retain partial data when using payment tokens (e.g., last 4 digits)."
So the sharpest signal of a BIN attack sits outside the screen you were staring at. Last four digits cluster in no readable way, because the last four are the random end of the number rather than the shared start. Instead of the prefix, your order list gives you timing, totals and contact details.
Your gateway does hold the prefix. Stripe, for instance, exposes it to fraud rules and describes it as "The Bank Identification Number (BIN) of the card used to make the payment", in its supported attributes reference. Whether you can group or export on that field depends on your provider and your plan. Either way, the dashboard is where the prefix pattern lives, and your orders screen is where the timing, totals and email addresses live. Read both.
What to check first
- Count attempts in the gateway rather than rows in WooCommerce. One order record can absorb several declines, a trap that reading a wall of failed orders goes into properly.
- Group the gateway's declines by card prefix. If one prefix carries most of them, the question is settled.
- Read the timestamps. Machine intervals look nothing like human ones.
- Check the IP, but do not trust it far. The stored address is a header, not the network, and it is cheap to rotate.
- Work out which route the attempts took, because a checkout usually has more than one.
Finally, tell your gateway or acquirer. Since they see BIN ranges across many merchants, they can confirm a BIN attack that your own data can only hint at.
Where Checkout Bouncer fits
Checkout Bouncer scores every WooCommerce checkout submission with Google reCAPTCHA v3 and covers each route an order can take into the store, including the classic AJAX path, the Store API used by the block checkout, and the pay for order page. Since a scripted run has to post through one of those routes, a bot score applied on all of them is a reasonable first barrier. Visa's merchant guidance asks for exactly that placement, saying a CAPTCHA should validate "on all request that enable card validation or payments".
But the limits matter more than the pitch. It is reCAPTCHA v3 only, never v2, hCaptcha or Turnstile. It guards the WooCommerce checkout only, not login, registration, comments or contact forms. Nothing here is a firewall or a malware scanner, and a determined operator with a solver service will still get attempts through.
Nor does the plugin show you a BIN, because your store never receives one. That evidence stays with your payment provider. The free checkout scanner tells you which routes are open on your site, and the plugin itself is free and GPL on WordPress.org. Everything else you need for this job is in the gateway dashboard.