How to Block Fake and Disposable Emails at Shopify Checkout

workerslab ·

Someone used [email protected] to grab your 15% welcome discount last Tuesday. The order went through. Shopify didn’t flinch. Now that address is sitting in your Klaviyo account, racking up profile fees, and your cart abandonment flow is about to fire three emails into the void.

Shopify’s checkout validates exactly one thing about an email: does it have an @ sign and a dot? That’s it. No MX record check. No disposable domain detection. No “hey, gmial.com isn’t a real domain” warning. Every throwaway address sails right through.

There are over 100,000 known disposable email domains across various blocklists. New ones pop up daily. And your checkout is wide open to all of them.

Why Shoppers Use Disposable Emails

They’re not all malicious. Most are just avoiding you.

A shopper wants to see the final price with tax and shipping before committing. They need an email to get past the checkout page. So they grab a 10-minute address from Temp Mail, check the total, and bounce. Your store never hears from them again, but Klaviyo adds them as a profile anyway.

Others want the discount code without the marketing emails. Pop up says “Get 15% off, enter your email.” They enter a Guerrilla Mail address, copy the code, and use their real email at checkout. Or they use the disposable address everywhere and you’re left emailing nobody.

Bots are the third bucket. Automated scripts that stuff checkout forms with fake entries, sometimes hundreds in a week. Multiple Shopify merchants have reported waves of mail##@protonmail.com-style fake abandoned checkouts clogging their analytics.

What This Actually Costs You

The damage isn’t abstract. It shows up in four places.

Your cart abandonment emails start bouncing. Klaviyo’s benchmark data shows abandoned cart flows recover 3-7% of lost orders, with top performers hitting double digits. For a store doing $50,000/month with a 70% abandonment rate, that recovery flow generates thousands in monthly revenue. If 12% of those emails go to disposable addresses, hundreds of dollars in recoverable revenue evaporate every month.

Your ESP bill inflates. Klaviyo charges per active profile. Every disposable address that hits checkout becomes a profile you pay for. A store with 30,000 profiles and 3,000 dead addresses is overpaying its tier by 10%. That’s real money every billing cycle.

Your sender reputation erodes. Industry guidance treats bounce rates above 2% as a warning threshold, and ISPs factor bounce trends into reputation scoring. Gmail and Yahoo don’t publish exact cutoffs, but sustained high bounces lead to throttling and spam folder placement. They don’t just slow down the bounced sends. They throttle everything, your welcome sequence, your shipping notifications, your Black Friday campaign. All of it.

Your analytics lie. Open rates, click rates, revenue per recipient. Every metric gets diluted when your denominator includes thousands of addresses that don’t exist. You might think your subject lines are underperforming when really your list is polluted.

Solution 1: Shopify Plus Checkout Extensibility

If you’re on Plus, you’ve got the strongest option. Shopify’s Checkout Extensibility framework lets you run validation functions directly in the checkout flow, server-side, compiled to WebAssembly. They work across all payment methods including Shop Pay, Apple Pay, and Google Pay.

The Cart and Checkout Validation Function API is the specific tool. You scaffold it with Shopify CLI:

shopify app generate extension --template cart_checkout_validation --name email-validator

Then write your validation logic. Here’s a function that blocks disposable domains and catches common typos:

// src/run.js
const DISPOSABLE_DOMAINS = [
  "guerrillamail.com", "mailinator.com", "tempmail.com",
  "yopmail.com", "throwaway.email", "sharklasers.com",
  "grr.la", "dispostable.com", "10minutemail.com",
  "trashmail.com", "fakeinbox.com"
];

const TYPO_SUGGESTIONS = {
  "gmial.com": "gmail.com",
  "gmal.com": "gmail.com",
  "gamil.com": "gmail.com",
  "yaho.com": "yahoo.com",
  "hotmial.com": "hotmail.com",
  "outlok.com": "outlook.com",
  "iclould.com": "icloud.com"
};

export function run(input) {
  const errors = [];
  const email = input.cart.buyerIdentity?.email;

  if (!email) return { operations: [] };

  const domain = email.split("@")[1]?.toLowerCase();

  if (DISPOSABLE_DOMAINS.includes(domain)) {
    errors.push({
      localizedMessage: "Please use a permanent email address for order updates.",
      target: "$.cart.buyerIdentity.email"
    });
    return { operations: [{ validationAdd: { errors } }] };
  }

  if (TYPO_SUGGESTIONS[domain]) {
    errors.push({
      localizedMessage: `Did you mean @${TYPO_SUGGESTIONS[domain]}?`,
      target: "$.cart.buyerIdentity.email"
    });
  }

  if (errors.length === 0) return { operations: [] };
  return { operations: [{ validationAdd: { errors } }] };
}

The input query tells Shopify what data your function needs:

query Input {
  cart {
    buyerIdentity {
      email
    }
  }
}

One catch: accessing buyerIdentity.email requires level 2 protected customer data access. You apply through the Shopify Partner Dashboard. Approval takes a few days, so submit early.

A static blocklist covers the obvious domains, but tens of thousands of disposable domains exist and new ones appear constantly. For real coverage, pair this with an API call to a validation service. MailCop’s API checks MX records, detects disposable domains in real time (including brand-new ones), and catches typo domains in a single request. That turns your static list into a living filter.

Solution 2: Post-Checkout Webhook Validation

Not on Plus? You can still catch bad emails, just not before the order completes.

Register a webhook for the orders/create event. When an order comes in, validate the email and flag or tag orders with disposable addresses.

// webhook handler for orders/create
app.post("/webhooks/orders/create", async (req, res) => {
  const order = req.body;
  const email = order.email;

  if (!email) return res.sendStatus(200);

  const result = await fetch("https://api.truemail.io/v1/verify", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.TRUEMAIL_API_KEY}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ email })
  });

  const data = await result.json();

  if (data.disposable || data.result === "undeliverable") {
    // Tag the order for review
    await tagOrder(order.id, "suspect-email");
    // Suppress from marketing flows
    await suppressFromKlaviyo(email);
  }

  res.sendStatus(200);
});

This won’t stop the disposable email from entering your system, but it catches it seconds after. Tag the order, suppress the profile from Klaviyo, and keep your flows clean. No abandoned cart sequence fires to a dead address. No profile fees pile up.

For stores processing fewer than 500 orders a month, this approach covers you well. The validation API cost is negligible at that volume.

Solution 3: Shopify Flow for Non-Technical Stores

If webhooks aren’t your thing, Shopify Flow handles this visually.

Create a Flow that triggers on “Order created.” Add a condition that checks the email domain against a list of known disposable providers. If it matches, tag the order, add an internal note, and optionally cancel it.

Shopify Flow includes a built-in “Send HTTP request” action that calls external APIs directly. Point it at a validation API endpoint, pass the customer email in the request body, and use the response to branch your workflow. No third-party connector needed. Your Flow becomes an email quality gate with zero code.

The limitation: Flow runs after checkout, not during. The customer completes the purchase with their throwaway address. You’re catching it retroactively. Still better than not catching it at all.

The Blocklist Problem

A hardcoded list of disposable domains works today. Tomorrow, it’s already outdated.

The disposable email blocklist world is a moving target. The most popular open-source list on GitHub tracks around 4,000 battle-tested domains. Larger aggregated lists reach 100,000+. But new disposable services launch weekly, and they register fresh domains specifically to dodge static lists.

Subdomain tricks are another gap. Some disposable providers let users generate addresses on random subdomains of their main domain. Your blocklist has tempmail.com but the shopper uses anything.tempmail.com. Static matching misses it unless you’re checking parent domains too.

API-based validation solves this. Instead of maintaining a list, you check each email against a service that updates its disposable domain database continuously. MailCop’s disposable detection covers known and newly registered throwaway domains, updated in real time. One API call replaces a blocklist you’d never keep current yourself.

Which Solution Fits Your Store?

For Shopify Plus stores, use Checkout Extensibility. Block disposable emails before the order completes. Pair the validation function with an API for maximum coverage. The Shopify checkout optimization guide walks through the full Plus setup.

For standard stores with a developer, go with the webhook approach. Validate on orders/create, tag suspect orders, suppress bad profiles from your ESP. You won’t block the email at checkout, but you’ll stop it from doing damage downstream.

For standard stores without a developer, install an app from the Shopify App Store. Express Email Validator or EmailVerify handle disposable detection out of the box. Or use Shopify Flow with its built-in HTTP request action for API-based validation.

For every store regardless of plan, clean your existing list first. Run a bulk validation on your Klaviyo or Mailchimp profiles. Suppress the invalids. Stop paying for dead contacts. Then add real-time validation so the problem stops growing. The email validation for e-commerce guide covers the full list-cleaning workflow.

Get It Done This Week

Here’s the minimum viable setup, any Shopify store, one afternoon.

Export your customer email list from Shopify (Settings > Customers > Export). Run it through a bulk validation service. Suppress every disposable and invalid address from your ESP. That’s step one, and it stops the bleeding.

Step two: pick one of the three solutions above and implement it. Plus stores should have a validation function running by end of week. Standard stores can install an app in under an hour or set up a webhook in a few hours.

The hidden cost of invalid emails in Shopify compounds every day you wait. Every disposable address that slips through checkout is a profile you’re paying to store, a recovery email that’ll never convert, and a small hit to your sender reputation.

Block them at the door. Or at least catch them in the hallway. Just don’t let them sit in your database forever.