That spike in abandoned checkouts isn’t lost revenue—it’s bots polluting your data and wrecking your email automation. I’ve seen Shopify merchants spend months optimizing their abandoned cart sequences, A/B testing subject lines, and tweaking discount offers, only to discover that 40% of their “abandoned checkouts” were never real customers in the first place. They were bots, scrapers, and automated scripts filling out checkout forms with fake emails, impossible addresses, and credit card numbers that were never going to work.
Last month, I audited a mid-size Shopify Plus store that was sending 12,000 abandoned cart emails per month. Their open rate had cratered to 8%, their email domain reputation was tanking, and their “cart abandonment rate” was a horrifying 89%. After implementing the detection framework I’m about to share, we discovered that 47% of their abandoned checkouts were fake. Their real abandonment rate? A much more reasonable 62%. Their email open rate after cleaning the list? 34%.
This isn’t a theoretical problem. The Reddit threads are full of merchants dealing with this exact issue, and the parallel conversation in GTM communities about blocking bot traffic at the source rather than filtering after the fact applies directly to Shopify checkout flows. Most guides tell you to filter bot traffic in GA4 after it’s already polluted your data. That’s backwards. By the time fake checkouts hit your analytics, they’ve already triggered your email automation, skewed your conversion funnels, and cost you money.
Here’s the practical framework for identifying fake checkouts at the source, scoring them before they enter your automation, and protecting your data pipeline from the ground up.
Why Fake Abandoned Checkouts Are Exploding
Before we fix the problem, you need to understand why it’s getting worse. Three converging trends are driving the explosion in fake checkout traffic:
Credential testing at scale. Fraudsters use checkout forms to validate stolen credit card numbers. They don’t care about completing the purchase—they just need to see if the card passes initial validation. Your checkout form becomes a testing ground, and each test registers as an “abandoned checkout.”
Email harvesting bots. Sophisticated scrapers fill out checkout forms with throwaway emails to see what kind of confirmation or abandoned cart emails you send. They’re mapping your automation sequences, looking for discount codes, or building profiles of your marketing stack.
Competitor intelligence tools. Some “competitive analysis” tools automatically fill out checkout forms on competitor sites to trigger abandoned cart sequences. They want to see your email copy, discount strategies, and timing. Your data becomes their research project.
The common thread? None of these actors have any intention of buying. But every single one of them looks like a “lost sale” in your analytics dashboard.
How to Identify Fake Abandoned Checkouts
Let’s get into the detection patterns that actually work. I’ve organized these by signal strength—start with the high-confidence indicators and work down to the probabilistic ones.
Pattern 1: Checkout Field Anomalies
Real customers make predictable mistakes. Bots make distinctive ones.
Email domain patterns. Fake checkouts cluster around specific email patterns:
- Temporary email services (guerrillamail, 10minutemail, tempail)
- Randomized strings followed by common domains (xk7n2m9p@gmail.com)
- Sequential patterns across multiple checkouts (test1@example.com, test2@example.com)
Address validation failures. Look for:
- ZIP codes that don’t match the city/state
- Addresses that pass format validation but fail USPS/postal verification
- PO boxes with “Suite” or “Apt” additions (a common bot pattern)
- Phone numbers that are all the same digit or sequential (111-111-1111, 123-456-7890)
Name field anomalies. Bots often use:
- Single-character names
- Names that match the email prefix exactly
- Famous names or obvious placeholders (“John Doe”, “Test User”)
- Non-alphabetic characters in name fields
Pattern 2: Timing Analysis
This is where the signal gets strong. Human checkout behavior follows predictable timing patterns. Bots don’t.
Form completion velocity. Real customers take 45-180 seconds to fill out a checkout form. They pause, correct typos, think about shipping options. Bots complete forms in 2-8 seconds. If you’re tracking checkout_started and checkout_completed events, any completion under 15 seconds is suspicious.
Session duration before checkout. Real customers browse before buying. They view products, add items to cart, maybe check shipping policies. Bots often hit the checkout page directly or within seconds of landing on the site.
Time-of-day clustering. Legitimate abandoned checkouts distribute roughly following your traffic patterns. Bot traffic often clusters at specific hours—either because the bot operator is running batches or because they’re operating in a different timezone and running during their business hours.
Here’s a quick SQL query (for Shopify Plus merchants with checkout data in a data warehouse) to identify timing anomalies:
WITH checkout_timing AS (
SELECT
checkout_token,
email,
created_at,
EXTRACT(HOUR FROM created_at) as checkout_hour,
TIMESTAMP_DIFF(updated_at, created_at, SECOND) as time_on_checkout,
LAG(created_at) OVER (PARTITION BY email ORDER BY created_at) as prev_checkout,
TIMESTAMP_DIFF(created_at, LAG(created_at) OVER (PARTITION BY email ORDER BY created_at), MINUTE) as minutes_since_last
FROM shopify.abandoned_checkouts
WHERE created_at > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
)
SELECT
checkout_token,
email,
created_at,
time_on_checkout,
minutes_since_last,
CASE
WHEN time_on_checkout < 15 THEN 'FAST_COMPLETION'
WHEN minutes_since_last < 5 THEN 'RAPID_REPEAT'
WHEN checkout_hour BETWEEN 2 AND 5 THEN 'ODD_HOURS'
ELSE 'NORMAL'
END as timing_flag
FROM checkout_timing
WHERE time_on_checkout < 15
OR minutes_since_last < 5
ORDER BY created_at DESC;
Pattern 3: Geographic and Technical Signals
IP geolocation mismatches. If the billing address says “Los Angeles, CA” but the IP geolocates to Eastern Europe, that’s a strong signal. This isn’t foolproof—people use VPNs—but in aggregate, it’s useful.
Known datacenter IP ranges. Legitimate customers don’t typically browse from AWS, Google Cloud, or DigitalOcean IP addresses. Tools like IPinfo or MaxMind can flag these.
User agent analysis. Headless browsers (Puppeteer, Playwright) and older bot frameworks leave distinctive user agent signatures. Look for missing or inconsistent user agents, or user agents that claim to be Chrome 80 when everyone else is on Chrome 120+.
Why Your Abandoned Cart Email Open Rates Are Tanking
Let me be direct: if your abandoned cart open rate is below 20%, you’re probably emailing bots.
Industry benchmarks for abandoned cart emails sit around 40-45% open rates. These are warm leads who already expressed intent. If your sequence is performing at half that benchmark, the problem isn’t your subject lines—it’s your list quality.
Here’s what happens when you email fake checkouts:
| Metric | Clean List | Bot-Polluted List | Impact |
|---|---|---|---|
| Open Rate | 42% | 11% | -74% |
| Click Rate | 8.5% | 1.2% | -86% |
| Conversion Rate | 4.2% | 0.4% | -90% |
| Bounce Rate | 2% | 18% | +800% |
| Spam Complaints | 0.02% | 0.15% | +650% |
| Email Domain Score | 95 | 67 | -29 points |
That last row is the killer. Email service providers (Klaviyo, Mailchimp, etc.) and inbox providers (Gmail, Outlook) are tracking your sender reputation. When you consistently email invalid addresses that bounce, or addresses that never open anything, your domain reputation drops. Eventually, even your legitimate emails start landing in spam folders.
I’ve seen merchants tank their entire email program—not just abandoned cart flows—because they let bot checkouts pollute their automation for six months before catching it.
The fix isn’t just filtering bots from your abandoned cart flow. It’s catching them before they ever enter your email platform.
Shopify Flow + GTM: Flagging Suspicious Checkouts Before Automation
This is where we shift from detection to prevention. The goal is to intercept suspicious checkouts before they trigger your email automation, not filter them out afterward.
Approach 1: Shopify Flow Conditions (Shopify Plus)
If you’re on Shopify Plus, Flow gives you native access to checkout data. You can build a workflow that evaluates each abandoned checkout against your bot criteria and either tags it for review or excludes it from automation entirely.
Here’s a Flow workflow structure that works:
Trigger: Checkout abandoned
Conditions (ANY):
- Email domain contains “tempmail” OR “guerrillamail” OR “10minutemail”
- Phone number matches regex
^(\d)\1{9}$(all same digit) - Billing country ≠ Shipping country AND total > $500
- Customer note is empty AND email matches
^[a-z0-9]{10,}@(gmail|yahoo|outlook)\.com$
Actions:
- Add tag: “suspicious_checkout”
- Add tag: “exclude_from_email”
- (Optional) Send internal Slack notification for manual review
The limitation here is that Flow can’t access timing data or IP information directly. For that, you need to layer in GTM or a custom app.
Approach 2: GTM-Based Bot Scoring at the Checkout Page
This is the more powerful approach, and it works on any Shopify plan. You’re using GTM to score the visitor before the checkout even completes, then passing that score into your tracking and automation systems.
Here’s a JavaScript snippet to calculate a basic bot score. Add this to a Custom HTML tag in GTM that fires on checkout pages:
<script>
(function() {
var botScore = 0;
var signals = [];
// Check for headless browser signals
if (navigator.webdriver) {
botScore += 30;
signals.push('webdriver_detected');
}
// Check for automation frameworks
if (window.callPhantom || window._phantom || window.phantom) {
botScore += 40;
signals.push('phantom_detected');
}
// Check for missing plugins (common in headless browsers)
if (navigator.plugins.length === 0) {
botScore += 15;
signals.push('no_plugins');
}
// Check for inconsistent screen dimensions
if (screen.width < 100 || screen.height < 100) {
botScore += 20;
signals.push('impossible_screen');
}
// Check for missing language
if (!navigator.language || navigator.language === '') {
botScore += 10;
signals.push('no_language');
}
// Time on page check (requires previous timestamp)
var pageLoadTime = window.performance.timing.navigationStart;
var timeOnPage = (Date.now() - pageLoadTime) / 1000;
if (timeOnPage < 3) {
botScore += 25;
signals.push('instant_checkout');
}
// Store in dataLayer for GTM
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'event': 'bot_score_calculated',
'bot_score': botScore,
'bot_signals': signals.join(','),
'is_suspicious': botScore >= 30
});
// Also store in sessionStorage for checkout form submission
sessionStorage.setItem('aumlytics_bot_score', botScore);
sessionStorage.setItem('aumlytics_bot_signals', signals.join(','));
})();
</script>
Now you can:
- Pass the
bot_scoreto GA4 as a custom dimension on your checkout events - Use GTM’s built-in conditions to block certain tags from firing when
is_suspiciousis true - Send the score to your email platform via a hidden field or webhook
This approach catches bots at the source—before they pollute your GA4 funnels or trigger your Klaviyo flows. If you need help implementing this across your analytics stack, our GTM service specializes in exactly this kind of fraud-resistant tracking architecture.
Building a Checkout Bot Scoring System
Let’s formalize this into a proper scoring system you can implement. The key is weighting signals by confidence level and setting appropriate thresholds.
Signal Weights
| Signal | Weight | Confidence | Notes |
|---|---|---|---|
| Webdriver flag detected | 40 | High | Almost always a bot |
| Form completed < 10 seconds | 35 | High | Humans can’t type that fast |
| Datacenter IP detected | 30 | Medium-High | Could be VPN, but suspicious |
| Temp email domain | 30 | High | No legitimate reason to use these |
| Phone number all same digits | 25 | High | Obviously fake |
| ZIP/City mismatch | 20 | Medium | Could be typo, but flag it |
| Session < 30 seconds before checkout | 20 | Medium | Unusual browsing pattern |
| Email matches random string pattern | 15 | Medium | Probabilistic |
| Checkout at 3-5am local time | 10 | Low | Night owls exist |
| Multiple checkouts from same email in 24h | 15 | Medium | Could be legitimate retry |
Threshold Actions
- Score 0-20: Normal processing, include in all automation
- Score 21-45: Flag for review, include in automation with “review” tag
- Score 46-70: Exclude from email automation, include in analytics with “suspicious” flag
- Score 71+: Exclude from all automation, filter from analytics, log for security review
Implementation via Shopify Webhook + Cloud Function
For a production-grade system, you’ll want to score checkouts server-side where you have access to IP data and can query external services. Here’s a Python Cloud Function that receives Shopify checkout webhooks and applies scoring:
import functions_framework
from flask import jsonify
import re
import requests
TEMP_EMAIL_DOMAINS = [
'guerrillamail.com', 'tempmail.net', '10minutemail.com',
'throwaway.email', 'mailinator.com', 'fakeinbox.com'
]
DATACENTER_ASNS = [
'AS14061', # DigitalOcean
'AS16509', # Amazon AWS
'AS15169', # Google Cloud
'AS14618', # Amazon AWS
]
@functions_framework.http
def score_checkout(request):
data = request.get_json()
score = 0
signals = []
email = data.get('email', '').lower()
phone = data.get('phone', '').replace('-', '').replace(' ', '')
billing_zip = data.get('billing_address', {}).get('zip', '')
billing_city = data.get('billing_address', {}).get('city', '')
client_ip = data.get('client_details', {}).get('browser_ip', '')
created_at = data.get('created_at')
# Check temp email domains
email_domain = email.split('@')[-1] if '@' in email else ''
if email_domain in TEMP_EMAIL_DOMAINS:
score += 30
signals.append('temp_email')
# Check for random string email pattern
email_local = email.split('@')[0] if '@' in email else ''
if re.match(r'^[a-z0-9]{12,}$', email_local):
score += 15
signals.append('random_email_pattern')
# Check phone patterns
if phone and len(set(phone.replace('+', ''))) == 1:
score += 25
signals.append('fake_phone')
# Check ZIP/City (simplified - production would use USPS API)
# This is a placeholder for actual validation logic
# Check IP against datacenter ranges (using ipinfo.io)
if client_ip:
try:
ip_info = requests.get(
f'https://ipinfo.io/{client_ip}/json',
timeout=2
).json()
org = ip_info.get('org', '')
if any(asn in org for asn in DATACENTER_ASNS):
score += 30
signals.append('datacenter_ip')
except:
pass # Don't fail scoring if IP lookup fails
# Determine action
if score >= 71:
action = 'block'
elif score >= 46:
action = 'exclude_email'
elif score >= 21:
action = 'flag_review'
else:
action = 'allow'
return jsonify({
'checkout_token': data.get('token'),
'bot_score': score,
'signals': signals,
'action': action
})
You’d deploy this to Google Cloud Functions (or AWS Lambda) and configure it as a Shopify webhook receiver for the checkouts/create topic. The response can then feed into your email platform via Zapier, a custom integration, or Shopify Flow’s HTTP request action.
For stores dealing with sophisticated bot attacks, we often recommend layering this with our AI agents service to build adaptive scoring models that learn from confirmed fraud patterns over time.
How Fake Checkouts Distort Your GA4 Funnel Data
Let’s talk about what happens to your analytics when fake checkouts go undetected.
Funnel Conversion Rates
Your GA4 checkout funnel shows the progression from view_item to add_to_cart to begin_checkout to add_payment_info to purchase. Fake checkouts inflate the begin_checkout stage while contributing nothing to purchase, artificially depressing your checkout conversion rate.
If you’re seeing a checkout-to-purchase conversion rate below 20%, compare that against your industry benchmark. E-commerce averages around 45-50% for the checkout-to-purchase step. A massive drop-off here often indicates bot traffic, not a UX problem with your checkout flow.
Attribution Pollution
This one’s sneaky. Fake checkouts still carry UTM parameters and traffic source data. If a bot wave hits your site with utm_source=google&utm_medium=cpc, your attribution reports will show Google Ads driving high-intent traffic that doesn’t convert. You might reduce spend on a channel that’s actually performing well because the bot traffic made it look bad.
Audience Pollution
If you’re building GA4 audiences for remarketing—like “users who started checkout but didn’t purchase”—you’re now including bots in those audiences. You’ll retarget them across Google Ads, Facebook, wherever. You’re paying to show ads to bots.
The Fix: Segment or Exclude at Collection Time
You have two options:
Option 1: Custom dimension filtering. Pass your bot score to GA4 as a custom dimension on all checkout events. Then build audience segments and reports that filter for bot_score < 30. This preserves the raw data while letting you analyze clean data separately.
Option 2: Block collection entirely. Use GTM conditions to prevent the begin_checkout event from firing when the bot score exceeds your threshold. This keeps your GA4 data clean but means you lose visibility into bot patterns over time.
I generally recommend Option 1 unless your bot traffic is so extreme that it’s affecting your GA4 event quota. You want to see the patterns, even if you’re filtering them from your operational reports.
If you’re dealing with severe data pollution, our GA4 service includes audit protocols specifically designed to identify and remediate historical bot contamination in your analytics.
Common Mistakes and Troubleshooting
Mistake 1: Setting the threshold too aggressive initially.
Start with a high threshold (score 70+) for blocking and lower it gradually as you validate your signals. I’ve seen merchants accidentally block legitimate international customers because they set the “billing/shipping country mismatch” weight too high. Test your scoring against known-good conversions before deploying to production.
Mistake 2: Not accounting for legitimate test transactions.
Your own team creates test checkouts. Your developers test the checkout flow. These will trigger your bot detection. Build in an allowlist for internal IP ranges or specific test email domains (test@yourcompany.com) before you deploy.
Mistake 3: Relying solely on client-side detection.
The JavaScript-based detection I showed earlier can be bypassed by sophisticated bots that spoof browser properties. It catches 80% of automated traffic, but the remaining 20% requires server-side signals (IP analysis, behavioral patterns over time). Layer both approaches.
Mistake 4: Forgetting to update temp email domain lists.
New disposable email services launch constantly. The list I provided is a starting point. Services like Kickbox or ZeroBounce maintain updated lists you can query via API for production systems.
Mistake 5: Not monitoring the scoring system over time.
Bot operators adapt. A detection method that works today might fail next month. Build alerting for when your “suspicious checkout” rate suddenly drops (they found a workaround) or spikes (new attack vector). Review flagged checkouts monthly to validate your scoring accuracy.
Troubleshooting: Score seems accurate but email automation still includes bots.
Check the timing. If your email platform pulls abandoned checkout data on a schedule (every 15 minutes, hourly), your scoring webhook might not have processed the checkout before it gets pulled into the email queue. You may need to add a delay to your abandoned cart flow or switch to a real-time webhook integration.
Troubleshooting: GTM tags not firing on checkout pages.
Shopify’s checkout is on a separate subdomain (checkout.shopify.com) for non-Plus stores. Your GTM container from your main domain won’t load there unless you’re on Shopify Plus with checkout extensibility. For standard Shopify stores, you’re limited to the information you can gather before the customer enters checkout.
Key Takeaways
-
Fake abandoned checkouts are a data quality problem, not just a fraud problem. They distort your conversion rates, tank your email metrics, and pollute your remarketing audiences. Treating them as a minor nuisance underestimates the damage.
-
Detect bots at the source, not after the fact. Filtering bot traffic from GA4 reports is reactive. Scoring checkouts before they enter your automation systems is proactive and prevents the downstream damage.
-
Build a weighted scoring system, not binary rules. Single signals are often unreliable. A checkout from a datacenter IP might be a legitimate VPN user. A randomized email might be privacy-conscious. But a datacenter IP + randomized email + 3-second form completion + fake phone number? That’s a bot.
-
Your abandoned cart email performance is a leading indicator. If open rates drop below 25%, investigate list quality before you blame your copy. You may be emailing bots.
-
Start conservative and tighten gradually. Block obvious bots immediately (score 70+), flag medium-confidence cases for review (score 30-70), and refine your weights based on manual verification of flagged checkouts.
-
Layer client-side and server-side detection. JavaScript-based detection catches most automated browsers. Server-side IP analysis and behavioral patterns catch the sophisticated ones. Neither alone is sufficient for a determined attacker.