Guide12 min read2026-05-21

Why Shopify's 'Limit One Per Customer' Isn't Enough (2026 Guide)

ByViralPilot|Ecommerce SaaS agency, 8 years experience

If you've ever set "limit one use per customer" on a Shopify discount, watched it apply to the first checkout, and then watched the same buyer redeem it again two hours later under a different email, you've already found out the setting doesn't do what most merchants assume it does.

The reality is that "limit one per customer" is four different problems wearing the same name, and Shopify's built-in setting solves about half of one of them.

This guide covers all four modes:

| Buyer state | Enforcement intent | What Shopify's built-in does | What actually works | |---|---|---|---| | Logged in | New customer only | Checks customer.numberOfOrders | Works, with caveats | | Logged in | Lifetime cap (1 ever) | Checks code redemption history | Mostly works | | Guest | New customer only | Falls back to email match, easily bypassed | Needs multi-signal identity | | Guest | Lifetime cap | Doesn't really exist as a native concept | Needs multi-signal identity |

If your store offers guest checkout, and most do, because turning it off hurts conversion roughly 1–4 percentage points on most catalogs, at least two of the four modes are not working the way you think.

The rest of this guide breaks each mode down: what Shopify's native setting actually checks, where it fails, and what the durable fix looks like.

TL;DR

  • Shopify's discount-level "limit to one use per customer" toggle checks email when guest, customer ID when logged in. Either one is trivially bypassable (Gmail aliases, fresh emails, new account).
  • Shopify's order-level quantity rules don't extend across separate orders, so they can't enforce a lifetime-per-product limit.
  • The four enforcement modes, guest × logged-in crossed with new-customer × lifetime-cap, each break differently and each need a different fix.
  • The only durable fix across all four modes is multi-signal identity matching: email, phone, address, IP, and device signature, checked server-side at Shopify checkout before the order is placed.

Mode 1: Logged-in customer, new-customer-only offer

This is the mode Shopify handles best.

When a buyer is logged in to a customer account and you've set a discount to "limit to one use per customer", Shopify checks the customer ID against the discount's redemption history. If the customer ID has redeemed before, the code is rejected.

Where it still leaks:

  1. A customer can create a second account. Shopify doesn't deduplicate accounts. Two Gmail aliases (or one Gmail and one work email) become two distinct customer IDs that both look "new" to Shopify.
  2. The customer can log out and check out as a guest. Once that happens, you're now in Mode 3 (see below) and the check is much weaker.
  3. Shopify's native "must be new customer" eligibility on a discount only enforces numberOfOrders == 0. If the buyer has any prior order, including one from a year ago that's nothing to do with this offer, the discount is rejected, which can frustrate legitimate customers. The setting has the opposite false-positive problem to what merchants usually worry about.

The honest verdict: for logged-in new-customer enforcement, Shopify's native setting works if you can be confident every checkout is logged in. Most stores can't be confident of that, which is why this mode usually gets bundled with Mode 3 in production.

Mode 2: Logged-in customer, lifetime per-product cap

This is the "you can only ever buy one of this product, no matter how many separate orders you place" use case. Examples:

  • A limited-edition drop where each customer is capped at one
  • A trial-size product that only ships once per household
  • A welcome-gift SKU that's a one-time-ever thing

Shopify doesn't really have a native control for this. The closest things are:

  • Order-level quantity rules (max 1 per order), these apply per-cart, not per-customer-lifetime. The buyer can simply place a second order.
  • Discount-level "limit to one use per customer", this enforces a per-customer cap on a discount code, not on a product. If the product is sold at full price too, the cap doesn't apply.

The community workarounds are well-known: a 0% discount code limited to one-per-customer that's required to check out with the product (clunky UX), or a Shopify Function via the Functions API. Both work for logged-in customers and both break the moment a guest checkout happens.

The Shopify Community forum has a long-running thread on this exact question with no clean native answer.

The honest verdict: logged-in lifetime caps are workable with custom development. They're not a built-in feature.

Mode 3: Guest checkout, new-customer-only offer

This is where most of the abuse actually lives, because most of the checkouts actually live here.

When a buyer checks out as a guest, Shopify has no customer account to check. The "limit to one use per customer" setting falls back to checking the email address on the checkout against the discount's redemption history.

That single fallback creates four well-known bypass paths:

Bypass 1: Gmail dot tricks. Gmail and Google Workspace ignore dots in the local part of an address. [email protected], [email protected], [email protected] all deliver to the same person. Shopify treats them as different emails. A buyer can mint several dozen of these for one Gmail account.

Bypass 2: Plus addressing. [email protected], [email protected], [email protected] all deliver to [email protected]. Most email providers support this. Shopify sees each one as a unique customer.

Bypass 3: Fresh email accounts. Free email at iCloud, Outlook, Proton, ProtonMail, Tutanota, Yahoo, GMX. Two minutes to set one up. Disposable-email services (Mailinator, GuerrillaMail, TempMail) are even faster.

Bypass 4: Same household, different person on file. Spouse's email, roommate's email, parent's email, same shipping address, same payment method, technically different "customer" by Shopify's email-only check.

The interaction with the Shopify discount Function (the Rust function at cart-submit) makes this worse: that function only sees customer.numberOfOrders, which is zero for every guest checkout regardless of how many prior orders the same person has placed.

The honest verdict: in guest mode, Shopify's "limit one per customer" doesn't really enforce a per-customer limit. It enforces a per-email limit. Anyone with five email addresses gets five "new customer" discounts.

Mode 4: Guest checkout, lifetime per-product cap

This is the hardest mode and Shopify essentially doesn't address it.

The use case: a high-value gift-with-purchase or limited drop where each person (not each email, not each session) can claim it exactly once, ever, including from guest checkout.

The native tools available:

  • Email-only matching, same bypasses as Mode 3.
  • Per-order quantity limits, caps the cart, not the lifetime.
  • Tagging customers post-purchase, works only if the customer is logged in to be tagged.
  • Manual review, possible at low volume, doesn't scale.

This mode is where serious abuse compounds. A single buyer running four orders over six months through four email addresses, all guest checkouts, all to the same shipping address, Shopify's native protections have nothing to anchor against.

What actually closes all four modes

For a "limit one per customer" rule to work across all four modes, the enforcement layer needs three things that Shopify's native settings don't have:

1. Multi-signal identity matching. Email alone is bypassable. Email plus phone is harder. Email plus phone plus shipping address plus IP plus device signature is significantly harder still, high enough that the small number of buyers willing to commit that level of disguise are also identifiable by behavioral patterns (multiple checkouts in rapid succession, mismatched geo signals, etc.).

The five signals that actually matter at Shopify checkout:

  • Email (normalized, Gmail dots stripped, plus aliases collapsed, common providers canonicalized)
  • Phone (E.164 normalized, last-10-digits comparison to allow formatting variation)
  • Shipping and billing address (fuzzy match, 123 Main St Apt 4 matches 123 Main Street #4)
  • IP address (low-precision on its own, useful when combined)
  • Device signature (a probabilistic feature vector across user agent, screen dimensions, hardware, timezone, not a true fingerprint, but enough to bridge same-browser sessions across multiple emails)

No single one of these is sufficient. Combining them is.

2. Enforcement before the order is placed. Post-purchase detection (auto-tagging suspicious orders, holding fulfilment, refunding programmatically) helps you understand the abuse pattern but doesn't stop the discount from being applied in the first place. The reward is already gone; you're just doing cleanup.

The fix runs at Shopify checkout itself, via the Checkout UI Extensions API and the Cart-and-Checkout Validation Function. Both run server-side, can't be bypassed from the browser, and decide before the order completes.

3. Independent of login state. The same identity check has to work whether the buyer is signed in or shopping as a guest. Otherwise every protection collapses the moment a buyer logs out, which is exactly when an abuser would do it.

OfferGuard runs this check at Shopify checkout in under 100ms, guest or logged in. The five identity signals are checked in parallel against your full order history, and the rule fires the verdict (block, warn, allow, or remove the code) before the order is placed. The same engine handles all four modes from this guide, new-customer-only, logged-in lifetime cap, guest new-customer, and guest lifetime cap, through one rule definition.

When a single signal is enough, and when it isn't

It's worth being honest about false positives, because over-aggressive blocking is its own kind of damage. Some signals are safe to block on alone:

  • Email exact match (after normalization): two distinct buyers don't share a normalized email. A match here is essentially certain identity.
  • Shopify customer ID match: two distinct buyers don't share a customer ID inside one shop.

Other signals are only useful when combined:

  • Same IP: coffee shops, offices, schools, apartment buildings, mobile carriers all share IPs. Two buyers from the same IP is meaningless without something else.
  • Same device signature: two iPhones in the same city with the same OS version produce identical signatures. A device match without other corroborating signals isn't enough for a hard block.
  • Same phone or same shipping address: spouses, roommates, family members. A phone or address match is strong evidence of household identity but not necessarily individual identity.

The right enforcement model is therefore not "block on any single signal," but "block when the composite confidence is high enough", usually two or more strong signals, or one strong signal plus several weak corroborating ones. This is the same model professional identity-resolution systems use, and it's what keeps false positives close to zero while still catching the patterns that actually matter.

Common bypasses, ranked by frequency

If you're looking at your order history right now and trying to estimate how much exposure you have, here's roughly the order of how common each bypass is in production:

  1. Plus-addressing aliases ([email protected]), by far the most common because it requires zero effort. Catch rate with email normalization alone: ~100%.
  2. Gmail dot tricks, second-most common. Same trivial effort. Catch rate with normalization: ~100%.
  3. Fresh email from same person, same shipping address, high frequency. Requires phone or address matching to catch.
  4. Fresh email, guest checkout, same device, moderate frequency. Requires device signature matching.
  5. Fresh email, fresh device, same household, lower frequency. Requires multiple soft signals (IP + shipping address + phone) to flag.
  6. Anti-detect browser, residential VPN, fresh everything, rare. Requires either behavioral analytics or just accepting that the smallest residual percentage of sophisticated abuse isn't worth chasing if the cost of false positives is high.

Most stores find that the top three account for 80–90% of their abuse, and the first two alone often capture more than half. Starting with email normalization plus phone matching is usually enough to recover most of the lost margin.

Frequently asked questions

Why does Shopify's "limit to one use per customer" let the same buyer use the code twice?

Because the setting checks the customer account, not the customer. When a buyer is logged in, Shopify checks the customer ID. When they're a guest, Shopify checks the email. Both can be changed without any verification. A fresh Gmail alias counts as a "new customer" to the setting.

Does turning off guest checkout fix this?

Partially. Forcing login closes the guest-mode bypass, but it doesn't stop a buyer from creating a second customer account with a different email. It also has a measurable conversion cost, most stores see 1–4 percentage points lower checkout completion when guest is disabled. For most catalogs, that conversion loss is larger than the discount abuse you'd prevent.

Can a Shopify Function enforce a lifetime per-product limit?

For logged-in customers, yes, a custom Discount Function or Cart Validation Function can read customer.numberOfOrders (or query historical orders via the Admin API) and reject orders that exceed your cap. For guest checkouts, the Function has no customer record to check against. You need an external identity layer for the guest case.

How can I tell if I'm being abused right now?

Look at your last 90 days of discounted orders and check for these patterns:

  • Multiple orders with the same shipping address but different emails
  • Similar-looking emails (e.g. name1@gmail, name.1@gmail, name+2@gmail)
  • Multiple orders from the same phone number
  • Repeated checkouts with disposable-domain emails (mailinator, tempmail, guerrillamail, etc.)

If you see any of these patterns in more than 2–3% of discounted orders, the abuse rate is high enough to be worth solving.

What's the most common false-positive risk with multi-signal blocking?

Couples and households. A spouse, parent, or roommate sharing a phone, address, and sometimes a device with another buyer is a real and legitimate pattern that looks like identity reuse on the surface. The fix is to block only when multiple strong signals align (e.g. email + phone, or address + device), not when a single soft signal matches. A well-tuned ruleset blocks 80–90% of abuse with near-zero false positives.

Does OfferGuard work without a Shopify Plus plan?

Yes. OfferGuard uses the public Checkout Extensions API and the public Discount Function, both available on standard Shopify plans, not just Plus.

How does this compare to Shopify Flow?

Shopify Flow runs after the order is placed. It can tag, hold, or trigger workflows in response to an order, but it can't block the order before checkout completes. Multi-signal enforcement at checkout solves the prevention problem; Flow remains useful for the post-purchase pipeline (tagging, fulfilment holds, audit logs) on top.

Next steps

If you want to see what your current exposure looks like, the free Watchdog plan on OfferGuard runs email-normalization checks on every checkout and surfaces matches in the admin, enough to see whether you have a problem before paying anything. The paid tiers add the other four signals and unlimited rules.

If you'd rather understand the full mechanics first, how OfferGuard works walks through the checkout pipeline step by step.

Try OfferGuard on your store.

Free plan available. No credit card.

Install free on Shopify