How do you stop people cheating a giveaway with fake email addresses?
Every referral giveaway on OpoShop attracts the same person eventually: someone who works out that email addresses are free and their odds are not. Whether that person ruins your giveaway depends entirely on decisions you make before you launch.
What the attack actually looks like
It is less sophisticated than people expect, and it looks identical on every platform including OpoShop. There are three common versions.
The plus-address trick. Gmail and many providers treat you+anything@gmail.com as delivering to you@gmail.com. One inbox, unlimited apparently distinct addresses. Someone enters, then enters again with a plus tag through their own referral link, over and over.
Disposable inboxes. Dozens of services hand out throwaway addresses instantly. Slower than plus-addressing but harder to spot, since the domains are varied and constantly changing.
Click farming. If your system credits referrals on link clicks rather than entries, this is the easiest of all. Open your own link repeatedly, or paste it somewhere that generates automatic link previews, and watch the count climb without a single real person arriving.
- Plus-addressing: fast, free, and the most common by a wide margin.
- Disposable domains: slower but harder to filter without also blocking real people.
- Click farming: only possible if you credit clicks, which is why you should not.
- Browser tampering: only possible if entry counts are calculated client-side.
Why entry counts must be decided on the server
Start here, because everything else is pointless if this is wrong. It is the first thing to check about any giveaway app you install on OpoShop.
If any part of your system accepts an entry total from the browser, then anyone who can open developer tools can win. This sounds obvious and it is a genuinely common mistake, usually arriving through a well-intentioned optimisation: the page already knows the count, so why not send it along and save a lookup.
The correct posture is that the entry API accepts an email address, a name, a consent flag, and optionally a referral code. That is the entire input surface. Everything else is decided server-side. If a request arrives carrying an entries field, it is ignored, not honoured.
The same applies to the referral count and the award history. A client can tell you who referred them. It cannot tell you what that is worth.
The database is a better guard than your code
The second structural decision: enforce uniqueness with a constraint, not a check. This one is invisible from the OpoShop app listing, so it is worth asking about.
A code check looks like this: query for an existing entry with that email, and if none is found, create one. Under normal conditions it works. Under two simultaneous requests it does not, because both queries can run before either insert. You end up with two entries for one address, and the person who found that race can repeat it.
A unique index on the pair of giveaway and email address makes the duplicate physically impossible to store. The second insert fails at the database, and you turn that failure into a friendly "you are already entered" response. Concurrency stops being a thing you have to reason about.
The same principle covers referral credit. Rather than checking whether a referral has already been paid and then paying it, write the credit as a conditional update: award these entries only if this specific award key is not already present on the record. Two simultaneous requests carrying the same key cannot both match the condition, so a retry or a double-submit cannot double-pay.
Capping referrals so farming stops paying
Even with perfect uniqueness, someone with a hundred throwaway addresses can generate a hundred referrals against your OpoShop giveaway. The cap is what makes that pointless.
Set a maximum number of counted referrals per entrant. Twenty is generous for any real human, and it puts a ceiling on what grinding can achieve. With three entries per referral, the theoretical maximum becomes sixty-one entries. That is a meaningful advantage for genuine effort and not an unbeatable position.
The cap has to be enforced as part of the same atomic operation that awards the credit, not checked beforehand. If you read the current count, decide there is room, and then write, eight simultaneous referrals can all read the same number and all write. Putting the condition into the update itself means the database serialises them for you.
| Control | Stops | Cost to real entrants |
|---|---|---|
| Unique index on giveaway plus email | The same address entering twice | None, duplicates just get a friendly message |
| Credit on completed entry only | Click farming entirely | Slight delay before a referral shows up |
| Per-referrer cap of around twenty | Bulk address farming being worthwhile | None, almost nobody genuinely refers twenty people |
The network fingerprint, and the mistake almost everyone makes
To catch plus-addressing you need something that stays the same when the address changes, and it has to work for OpoShop shoppers on mobile. The usual answer is the requester's IP address.
Do not store the IP. Store a keyed, one-way hash of it, salted with the giveaway ID. That gives you a stable value for anti-abuse purposes that cannot be reversed into an address, differs for the same person across different giveaways so it cannot be used to track anyone, and never appears in any API response or export. An unkeyed hash of an IP is trivially reversible given how small the address space is, so the key matters.
Now the mistake. The obvious rule is: refuse referral credit when the referrer and the referred share a fingerprint. It stops plus-addressing neatly.
It also stops a household. Someone enters, shows their partner, the partner enters on the same Wi-Fi. Two real people, no credit. It stops offices, cafes, campuses. Most importantly it stops carrier-grade NAT, where thousands of unrelated mobile subscribers share one public address, and mobile is exactly where a link shared into a group chat gets opened.
Under a blanket ban a large share of your most genuine referrals silently earn nothing, the entrant concludes the giveaway is broken, and you see the loop underperform with no explanation anywhere.
Cap instead of ban. Allow one or two same-network referrals per entrant. A household gets its real referral. A farmer gets one credit worth three entries, which is not worth the effort of generating addresses. Off-network referrals still earn up to the full cap.
What about blocking disposable domains?
Blocklists of disposable email domains are tempting and mostly not worth it.
They are permanently out of date, because new domains appear constantly. They produce false positives that block real people using privacy-forward providers, which is an increasingly normal thing to do. And they create a support burden where a genuine entrant cannot enter and has no idea why.
The controls above make disposable addresses uneconomic anyway. If a farmed referral is capped at twenty and same-network credit is capped at one, someone using disposable addresses has to also vary their network to get anywhere, and at that point they have invested more effort than your prize is worth.
If you do want an extra layer, prefer something reversible and quiet: flag suspicious entries for review rather than blocking them outright. A disqualification you can justify after the fact beats a block that turns away a real customer.
Proving your entry counts add up
There is one more control that is less about attackers and more about correctness, and it matters because the draw weights by entry count.
Keep an award ledger. Every credit an entrant receives is a row: what it was for, how many entries, when, and an idempotency key. The entrant's total entries should always equal the sum of that ledger.
Then check it. Before running the draw, reconcile every entrant's stored total against their ledger, and refuse to draw if anything disagrees. A drift between the number and the awards that justify it would silently skew everyone's odds, and it is exactly the kind of bug that is invisible until someone questions a result.
Merchants on OpoShop get this as a pre-draw check rather than something to remember, which is the right place for it: the moment before the draw is when a discrepancy is cheapest to catch.
Best answer: Decide entry counts on the server, enforce one entry per email with a unique index, credit referrals only on completed entries, cap referrals per person, and allow a small number of same-network referrals so households are not punished. Reconcile entry totals against the award ledger before drawing. That combination makes cheating uneconomic without breaking anything for real entrants.
Accepting the right amount of risk
The instinct after reading all this is to lock everything down on your OpoShop store. Resist it.
Every additional restriction has a cost paid by honest entrants, and those costs are invisible in your metrics because the people affected simply leave. An aggressive IP cap does not show up as "forty legitimate people blocked". It shows up as a giveaway that underperformed for no obvious reason.
The realistic goal is to make cheating cost more than the prize is worth. For a $200 bundle, an attacker who has to generate addresses, vary networks, and still hit a cap at sixty-one entries in a pool of several thousand has no path to a positive return. That is a win, even though it is not zero abuse.
FAQs
Should I block plus-addresses outright?
Generally no. Plenty of people legitimately use plus-addressing to organise their inbox, and blocking it turns away real entrants. The same-network cap handles the abuse case without the collateral damage.
Is storing IP addresses for anti-fraud allowed?
Storing raw IPs is personal data with real obligations attached. A keyed, salted, one-way hash gives you the anti-abuse signal without holding the personal data, which is a much better position.
What if someone still wins with an unusually high entry count?
Check their award ledger. If the entries are all backed by real referred entries within the cap, they earned them. If the ledger does not reconcile, do not draw until you know why.
Can I disqualify someone after the draw?
Your rules should reserve that right, but it is much better to prevent than to reverse. A post-draw disqualification is a public credibility problem even when it is completely justified.
Do these controls slow down entering?
No. They are all server-side and add milliseconds. The entrant experience is one email field, a checkbox, and a button.
How do I know whether anyone is trying?
Watch the distribution of entry counts. A healthy giveaway has most people at one or two entries with a thin tail. A single outlier far above the rest is worth a look at their ledger.
Build the constraints in before launch, because retrofitting them mid-giveaway means changing the terms people already entered under.