Stopping Card Testing Bots: A Shopify Community Deep Dive into Fraud Prevention
Hey everyone! Let's talk about something that can be a real headache for Shopify store owners: card testing bots. We recently had a fantastic discussion in the Shopify community that really peeled back the layers on how these bots operate and, more importantly, how we can fight back. It was a lively thread, full of sharp insights from folks like NativeCode, lumine, and Alpize, and I wanted to share the key takeaways with you.
For those unfamiliar, card testing bots are essentially automated programs that use your store's checkout process to validate stolen credit card numbers. They try a bunch of cards, and whichever ones go through are marked as "live." The kicker? You, the merchant, can end up with a pile of fraudulent orders to refund, and often, you're stuck paying the non-refundable processing fees. It's literally paying for a bot's experiment – not cool!
A Multi-Layered Defense: The Halt App Approach
NativeCode, the original author of the thread, got so frustrated with the lack of simple solutions that they built their own app called Halt, a card testing blocker for Shopify. What I found really interesting about Halt is its multi-layered approach to fraud prevention.
1. The Decoy Product
One clever strategy Halt uses is a "decoy product." This is a product designed to be so cheap or obscure that real customers wouldn't typically buy it, but bots, especially those that browse for the lowest-priced items, might fall for it. As NativeCode explained, the decoy acts as another signal and a way to catch bots that browse for products to test against.
However, lumine raised a great point about how bots often interact with your store. They might not always "browse" your storefront. Many bots go straight to the /products.json endpoint, which by default returns 30 products. If your decoy isn't among the cheapest 30, or if a bot uses a variant ID directly from that payload to create a cart permalink, it could bypass the decoy. NativeCode acknowledged this, stating they'd be adding notes to the app's setup to guide merchants on optimizing the decoy's visibility.
2. The Repeat Rule: Blocking Before Payment
The core of Halt's defense, and where much of the community discussion focused, is its "repeat rule." This rule identifies and blocks suspicious repeat behavior. If the same email, address, or phone number shows up too many times in a day, the checkout is refused at the payment step. The best part? This block happens before the card reaches the processor. That means no authorization attempt, and crucially, no processing fees for you!
How does this magic happen? NativeCode explained the technical breakdown:
- Shopify Functions: Halt runs as a checkout validation function right inside Shopify's own checkout. These functions are powerful because they execute directly within Shopify's environment, allowing for real-time validation.
- Webhooks & Metafields: The system isn't fed by completed orders (which a refused checkout never becomes). Instead, it uses
checkouts/createandcheckouts/updatewebhooks. These fire the moment the contact step is saved. Every webhook recounts the last 24 hours of activity and writes a list of hashed buyer details (email, address, phone) along with their count into shop metafields. - Real-time Lookup: When a buyer reaches the payment step, the Shopify Function hashes their details, finds them in the metafields, and checks the count against the limit you've set in the app. If it exceeds the limit, the checkout is refused.
Community-Driven Enhancements & Insights
The community discussion really shone a light on how to make these systems even more robust.
Metafield Capacity & "Sharding"
One of the most critical points came from lumine, who highlighted a potential pitfall: Shopify Functions input queries do not return metafield values larger than 10,000 bytes. If the list of distinct checkouts grew too large, the function would quietly receive "null," and the rule would stop firing without warning. This is especially problematic during a bot attack, when the list would be at its longest.
NativeCode took this feedback to heart and implemented a brilliant solution: "sharding." The data is now split across three metafields, each around 9,800 bytes, sorted by highest count first. This means the entries that get "dropped off" if the list overflows are the ones seen only once, preserving the integrity of rules that fire on higher counts.
Pro Tip: This kind of technical detail shows why it's crucial to understand how your apps interact with Shopify's underlying architecture. Small technical limits can have big impacts!
Logging & Automated Strict Mode
Lumine also suggested logging how many entries fell off the metafields, not just the byte size, to truly understand how "blind" the count-based rules became during an overflow. NativeCode quickly shipped an update to log write sizes and email daily reports on what was kept versus what fell off. Lumine also suggested that when a shard fills, the app should automatically flip to a "strict" mode for the rest of the day, rather than requiring manual intervention, which NativeCode found very useful.
The "Small Guest Orders" Rule (Minimum Order Value)
Alpize brought up another excellent point: bots often use minimal cart values because a tiny cart answers the same validation question as a large one, at almost no cost. They suggested a configurable minimum order value rule that refuses any guest checkout below a merchant-set amount before payment processing.
NativeCode confirmed that Halt already has this feature, called "Small guest orders." By default, it fires only on the second attempt by the same details (because a single cheap item isn't always fraud!), but there's a checkbox to make it "strict" and stop every guest cart under the amount if your store is under heavy attack.
How to leverage a Minimum Order Value rule (within an app like Halt):
- Identify Your Minimum: Determine the lowest order value you would legitimately accept from a guest customer. Bots usually go for $0.01-$5.
- Set the Rule: Within your chosen fraud prevention app (e.g., Halt), find the "Small guest orders" or "Minimum order value" setting.
- Enter Your Value: Input the minimum amount. For example, if you rarely sell anything under $10, set $10.
- Consider "Strict" Mode: If you're experiencing a bot attack, activate the "strict" checkbox to refuse all guest checkouts under that amount, even first-timers.
It's important to remember that card testing bots are constantly evolving their tactics. As justjessica24 pointed out, relying on one detection method probably isn't going to hold up for long. A multi-layered approach, combining decoy products, repeat transaction rules, and minimum order values, all working together, provides a much stronger defense.
This discussion really highlighted the power of the Shopify community in tackling real-world problems. By sharing knowledge and providing constructive feedback, we can collectively build more secure and resilient stores. If you're looking to start your own online store and want to ensure you have these kinds of protective measures in place from day one, you can sign up for Shopify here and then explore the app store for robust fraud prevention tools. Staying proactive and leveraging these community-tested strategies is key to keeping your business safe from these automated threats.