Security

How to Stop Discount Code Abuse on Shopify

Learn how Shopify discount code abuse happens on spin-to-win popups and the server-side mechanisms that prevent it, from cryptographically secure prize selection to single-use codes minted via Shopify Functions.

A shopper wins 20% off on your wheel, posts the code to a coupon-sharing site that evening, and by morning a few hundred strangers have tried to redeem it. Or a shopper opens their browser’s dev tools, edits what comes back from the popup, and lands on the jackpot slice every single spin. Both are the same underlying problem: something that should be decided and enforced on your server has instead been trusted to the shopper’s browser.

Why a wheel is a specific target for abuse

A spin-to-win popup makes two promises at once: the prize is picked fairly, and the code it hands out only works for the person who won it. If either promise is enforced client-side — the browser decides the outcome, or the same code gets reused for everyone — a shopper who knows how to open dev tools or a forum post that spreads a working code can break it. Neither requires much sophistication. Both just require the app to have left the decision somewhere the shopper can reach.

Prize selection happens on the server, not in the browser

Profiter picks the winning slice on the server, using a cryptographically secure random number generator (a CSPRNG) and the odds and stock caps you set for that campaign. The browser never runs the odds calculation and never gets to choose — it receives the result the server already committed to, and its only job is to animate the wheel to a stop on that slice.

This server-side decision is designed to feel instant. A feature we call a “zero-dead-time spin” begins the wheel’s wind-up animation while the request to the server is still in flight. This overlaps the animation with the network round-trip, so the shopper perceives no delay. Editing the page, replaying a request, or inspecting network traffic doesn’t change which slice was picked, because the picking already happened somewhere the shopper’s browser can’t touch.

Building features like this without slowing down your store requires a strict performance budget. Every feature is weighed against the bytes it adds. Here is the actual history of our JavaScript budget for the wheel, showing what each increase paid for.

BudgetWhat the extra bytes bought
16 KBbaseline physics spin, clacker pointer, victory effects
18 KBthemes + hub logo
19 KBpost-win coupon reminder bar
19.5 KBfirst-touch source capture
20 KBzero-dead-time spin (wind-up overlaps the /spin round-trip)
20.5 KBlatency failsafe: cruise spin while server is slow, animated already_spun replays
21 KBmint-failure recovery: “generating your code” bar + recover polling

Budget is for raw or gzipped JS, whichever is larger. Measured 28 July 2026 from the built extension assets.

Every win gets a unique, single-use code

The second half of code abuse is reuse: one code, shared or leaked, redeemed far more times than the one shopper it was meant for. Profiter doesn’t hand out from a shared pool. To avoid API latency during the spin, codes are minted ahead of demand. Each win claims a pre-minted, single-use discount code via a Shopify Function, and that code is applied straight to the cart rather than typed in at checkout.

It’s single-use by construction — good for exactly one redemption. If a shopper copies it and posts it somewhere before checking out, the first person to redeem it consumes it. Every attempt after that hits a code that’s already spent.

Are Shopify discount codes case-sensitive?

No, discount codes on Shopify are not case-sensitive. A code entered as SAVE20 works the same as save20. This is a platform-level behavior, not specific to any app. It’s another reason why simply creating a complex, hard-to-guess code isn’t enough to prevent it from being shared and abused; technical enforcement is required.

What this actually protects

Put together, the two mechanisms cover the two ways a wheel gets gamed. You can’t force a better prize than the odds allow, because the browser never had the odds to begin with. And a leaked code doesn’t turn into free discounts for a coupon forum, because there’s no shared code sitting there to leak — only a pre-minted, one-time code already spoken for by the shopper who won it. Neither fix depends on the shopper behaving well. Both hold regardless of what happens in their browser, which is the only place a popup app can’t fully trust.

Give shoppers a 🎡 spin and keep the ✅ proof

Launch a wheel in minutes. The dashboard shows what it added to your bottom line.