How to block fraud at signup, offer click and cashout
Scoring fraud is only half the job. The money is saved when your site acts on the answer. This guide shows the four places to act, what to do at each one and the few lines of code it takes.
Short answer
Act at four points: signup, offer click, conversion (postback) and cashout. Use cheap, reversible actions (hold, review) early and permanent ones (ban, deny) only at the end after a person has looked; start in shadow mode and fail open if the check is unreachable.
- Signup, block
- Refuse the account or keep it suspended.
- Offer click, block
- Show "offer not available", so the install is never recorded.
- Conversion, block
- Credit on hold, no balance.
- Cashout, block
- Hold, usually deny after review.
- Rollout
- Shadow mode first, enforce on cashouts on day 4, blocked signups and offers by day 6 to 7.
The four places to act
Fraud on a rewards site follows the same path every time: open accounts, complete offers, collect the conversions, cash out. Each step is a chance to stop it, and each one costs less than the next.
- Signup. Refusing a farm account here costs nothing. It never earns, never clicks and never reaches your advertisers.
- Offer click. If the account is already flagged, do not open the offer. The fraud never reaches the offerwall or the advertiser, so there is nothing to reverse later.
- Conversion (postback). Credit the reward, but on hold. The points exist, the user cannot spend them, and you decide after a look.
- Cashout. The last moment the money is still yours. Hold the withdrawal and review it before paying.
What to do with each answer
CashoutGuard answers every event with allow, review or block, plus the reasons. This is a sensible starting policy:
| Where | block | review | allow |
|---|---|---|---|
| Signup | Refuse the account or keep it suspended | Accept, watch the first cashout | Accept |
| Offer click | Show "offer not available" | Open the offer | Open the offer |
| Conversion | Credit on hold, no balance | Credit normally, flag for the cashout review | Credit normally |
| Cashout | Hold, usually deny after review | Hold for a quick review | Pay |
Keep a suspended account instead of deleting it. If it was a false alarm, one click brings the user back with their history intact.
The code
The browser script gives each visitor a request_id. Send it with the form to your server, then ask CashoutGuard from the server with your secret key. The examples use the PHP SDK from the docs; the Node.js and Python SDKs look the same.
Signup
$cg = new \CashoutGuard\Client(getenv('CASHOUTGUARD_SECRET'));
$user = createUser($request); // your own signup
$r = $cg->evaluate([
'event' => 'signup',
'account_id' => (string) $user->id,
'request_id' => $request->input('cg_request_id'),
'ip' => $request->ip(),
'email' => $user->email,
]);
if ($r->isBlocked()) {
$user->suspend(); // keep it, so a false alarm is one click away
return back()->withErrors(['email' => 'We could not create your account.']);
}Offer click
$r = $cg->evaluate(['event' => 'offer_click', 'account_id' => (string) $user->id,
'request_id' => $request->input('cg_request_id'), 'offer_id' => $offer->id, 'click_id' => $clickId]);
if ($r->isBlocked()) {
return response()->view('offer-unavailable', [], 403);
}
return redirect()->away($offer->trackingUrl($user, $clickId));Conversion (postback)
// Ask BEFORE crediting, so a blocked conversion never touches the balance.
$r = $cg->evaluate(['event' => 'conversion', 'account_id' => (string) $userId,
'offer_id' => $offerId, 'transaction_id' => $transId, 'amount' => $payoutUsd, 'currency' => 'USD']);
$status = $r->isBlocked() ? 'hold' : 'approved';
creditReward($userId, $points, $status); // 'hold' = recorded, not spendableCashout
$r = $cg->evaluate(['event' => 'cashout', 'account_id' => (string) $user->id,
'request_id' => $request->input('cg_request_id'), 'amount' => $usd, 'currency' => 'USD',
'payout_method' => $method, 'payout_address' => $address]);
$withdrawal->status = $r->isBlocked() ? 'hold' : ($r->needsReview() ? 'review' : 'pending');
$withdrawal->save();Staying safe: shadow mode and fail-open
Two settings keep honest users safe while you roll this out.
- Shadow mode first. A new site answers allow to everything while still recording what it would have done. Run your code in shadow mode for a few days, look at the accounts it would have blocked, then switch the site to enforce. Your code does not change.
- Fail-open. The SDK waits at most two seconds and answers allow if CashoutGuard is slow or unreachable. A network problem never blocks a signup or a payout.
Which signals deserve a block
Not every reason is equally strong. A good policy blocks on evidence that is hard to explain innocently and only reviews the rest. These are the signals that most often justify a block on their own:
- A payout address already paid for another account. One PayPal email or wallet collecting for several accounts is one person.
- A device shared with accounts you already blocked. The same browser or phone coming back under a new name is the classic farm pattern.
- An emulator, a virtual machine or an automation tool. Real users do not complete offers from a headless browser or an Android emulator.
- Tor or a datacenter IP on geo-targeted offers. The advertiser paid for a country the user was never in, so the conversion will be reversed.
- An address on your own blocklist. Every confirmed ring gives you devices, IPs and addresses that should never earn again.
Other signals are better as reasons to look than reasons to block: a VPN on its own, a timezone that does not match the IP, a brand new account or a fast offer. Two or three of them together on the same account usually add up to a block score anyway, and that is the point of scoring: one weak signal rarely decides, several strong ones always do.
Choosing your thresholds
Each site has two numbers: the score from which an event goes to review and the score from which it is blocked. The defaults work for most rewards sites, but your traffic is not the same as everybody else's.
- Run in shadow mode for three to seven days so you have real traffic scored.
- Open the accounts that would have been blocked and check twenty of them by hand. If almost all are clearly fraud, the block threshold is right or could even go down a little.
- Do the same with twenty review accounts. If most of them are honest, raise the review threshold so your team only looks at cases that matter.
- Repeat after big changes: a new offerwall, a new country or a new payout method changes who shows up.
Rules help where one signal matters more on your site than on others. A site that only pays in crypto may want every shared wallet blocked; a survey site may care most about speed. Rules change the weight of a reason without touching your code.
When an honest user gets blocked
It will happen. A family sharing one laptop, a traveller on hotel wifi or a user behind a mobile carrier that rotates IPs can all look unusual. What matters is how quickly you can undo it.
- Keep the account, suspend it. Deleting it throws away the history you need to decide.
- Give a way back. A neutral message with a support link is enough. Farms rarely write in; honest users do.
- Allowlist after checking. Once you are sure, allowlist the account so the same signals do not block it again next week.
- Release held money quickly. A held conversion or cashout that turns out fine should be paid the same day. That is what makes a hold acceptable to honest users.
A one-week rollout plan
| Day | Step | Why |
|---|---|---|
| 1 | Install the script and send cashouts and postbacks, site in shadow mode | Real traffic gets scored with zero risk |
| 2-3 | Review a sample of would-be blocks and reviews | Check the thresholds against your own users |
| 4 | Switch to enforce and act on cashouts only | Protects the money with the least impact |
| 5 | Hold blocked conversions in the postback handler | Balances stop growing on flagged accounts |
| 6-7 | Refuse blocked signups and keep blocked offers closed | Farms stop at the door and never reach your advertisers |
Measuring the result
Three numbers tell you whether blocking works. Look at them weekly for the first month.
- Reversal rate from your networks. The share of conversions reversed weeks later should fall as blocked accounts stop earning.
- Money held and money released. If you release most of what you hold, your thresholds are too strict. If you almost never release anything, they may be too loose.
- Support tickets about blocks. A handful a week is normal. A sudden jump usually means one signal is too strong for your audience.
Next steps
Start with the cashout: it is one call and protects the money directly. Add the postback next, then the signup and the offer click. The cashout checklist covers what to look at during the review, and the pricing page includes a 14-day Growth trial.