Ecommerce & retail
Preventing coupon QR code fraud
Assume any static coupon QR code will be screenshotted and shared: a code is copied in one tap and forwarded to thousands. Either cap the exposure so spreading is acceptable, or issue single-use server-validated tokens that burn on redemption. Expiry windows and location checks close the remaining gaps.
The economics of a screenshot
Start from the attacker's cost, because it explains everything: copying a QR coupon is one screenshot and one forward. A "20% off" code printed on a flyer reaches a coupon- sharing group chat, a deals forum or a voucher site within hours of someone deciding it should, and from there redemption is limited only by your till process. This is not hypothetical malice: most spreading is customers being helpful to each other. The design question is never "will it spread" but "what happens when it does".
Two coherent answers exist. Everything else is wishful printing.
Answer one: make spreading acceptable
A static code: same payload on every flyer, generated once with the coupon tool, is fine when the maths survives worst-case spread:
- The discount is one you would happily give any customer ("10% off your first visit").
- Redemption requires a purchase whose margin absorbs the discount.
- The till applies it once per transaction and staff can decline obvious abuse.
Here the "fraud" is just distribution you did not pay for, and plenty of businesses treat a leaked coupon as accidental marketing. The mistake is using a static code for an offer that cannot absorb spread (a free product, a high-value voucher, a new-customer-only discount), and being surprised.
Answer two: single-use tokens
For anything with real value, the coupon becomes a server-validated token:
example.com/c/8h2n4v7q → server checks: issued? unredeemed? in window? → burn
Each customer receives a unique code: issued on screen, by email, into a
wallet pass, and redemption marks the
token spent atomically, so the race of two tills redeeming the same screenshot resolves
to one winner. Generate unique codes at scale with the bulk generator or
POST /api/v1/qr/batch (up to 1,000 per request). Tokens must be random and
sparse (8+ characters from a large alphabet), never sequential, or attackers simply
enumerate your voucher space. The same opaque-serial logic underpins
product authentication.
Layer the cheap additional checks where the offer justifies them:
- Expiry windows, short validity caps how long a leaked token circulates.
- Geo or till checks: redeemable only at the issuing branch, or only on a POS session, defeating remote redemption of shared screenshots.
- Identity binding, token tied to the loyalty account that received it. Strongest, most friction.
- Signed payloads stop forged coupons offline: see signed QR codes, though not shared genuine ones.
The fraud-versus-friction table
Every control taxes the honest customer. Choose deliberately:
| Control | Fraud stopped | Friction added | Use when |
|---|---|---|---|
| Static code, capped offer | None, by design | None | Offer survives infinite spread |
| Expiry window | Long-tail circulation | Low | Always: it is nearly free |
| Single-use token | Screenshot sharing | Low (unique delivery needed) | Any real-value offer |
| Branch/till binding | Remote redemption | Medium | Local offers, franchises |
| Account binding | Nearly all sharing | High, requires sign-in | High-value, member offers |
The classic failure is mismatching column one and column four: account-binding a 10% coupon (killing redemption for nothing), or static-coding a free-product voucher (a giveaway to the internet). Match the control to the value at risk, and verify redemption flows end-to-end (including the double-redemption race), before printing anything.
FAQ
How do people abuse coupon QR codes?
Mostly by sharing screenshots, a static code forwarded to group chats or deal sites redeems unlimited times unless the server or till stops it. Sequential voucher codes also get enumerated. Deliberate forgery is rarer than simple over-sharing.
What is a single-use QR coupon?
A unique random token per customer, checked and atomically marked spent by your server at redemption. A shared screenshot then fails for everyone after the first use. Tokens must be random and sparse so valid ones cannot be guessed.
Can I just use one static discount code for a campaign?
Yes, if the offer survives worst-case spread, a modest percentage requiring a purchase, applied once per transaction. Never use a static code for free products or high-value vouchers, because it will circulate.
Do expiry dates actually reduce coupon fraud?
Yes, cheaply. A short redemption window caps how long a leaked code stays valuable and shrinks the audience a shared screenshot can reach in time. Combine expiry with single-use tokens for offers with real value.
Try it: free, no signup
Related
- QR codes for loyalty programmes, Enrolment in one scan, wallet passes instead of apps, and POS-scannable member codes: the honest behavioural case against app-based loyalty.
- QR codes for referral programmes, Referral links as printed codes: unique code per customer for attribution, double-sided incentives, and the placements that reach an advocate's friends.
- QR codes for product authentication: what works and what doesn't, Anti-counterfeit QR tiers compared (shared codes, unique per-unit codes, signed codes), and the honest limits: a copied code copies the authentic page.
- Signed QR codes and authenticity, How signed QR codes prove who issued a code and that it was not altered: the JWS pattern, the EU Digital COVID Certificate, SQRC, and a build sketch.