CashoutGuard: fraud prevention for rewards, GPT, faucet, PTC and offerwall sites.

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.

  1. Signup. Refusing a farm account here costs nothing. It never earns, never clicks and never reaches your advertisers.
  2. 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.
  3. Conversion (postback). Credit the reward, but on hold. The points exist, the user cannot spend them, and you decide after a look.
  4. 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:

Whereblockreviewallow
SignupRefuse the account or keep it suspendedAccept, watch the first cashoutAccept
Offer clickShow "offer not available"Open the offerOpen the offer
ConversionCredit on hold, no balanceCredit normally, flag for the cashout reviewCredit normally
CashoutHold, usually deny after reviewHold for a quick reviewPay

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 spendable

Cashout

$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.

  1. Run in shadow mode for three to seven days so you have real traffic scored.
  2. 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.
  3. 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.
  4. 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

DayStepWhy
1Install the script and send cashouts and postbacks, site in shadow modeReal traffic gets scored with zero risk
2-3Review a sample of would-be blocks and reviewsCheck the thresholds against your own users
4Switch to enforce and act on cashouts onlyProtects the money with the least impact
5Hold blocked conversions in the postback handlerBalances stop growing on flagged accounts
6-7Refuse blocked signups and keep blocked offers closedFarms 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.

Frequently asked questions

Should I block at signup or at cashout?

Both, but for different reasons. The signup stops farms before they cost anything; the cashout is the final safety net for accounts that looked clean at first.

Does blocking the offer click really help?

Yes. If the offer never opens, the offerwall never records the install, so the advertiser does not receive fraud from your site and there is nothing to reverse weeks later.

What if CashoutGuard is down?

The SDKs fail open: after two seconds they answer allow, and your site keeps working as if the check were not there.

Can I block only at cashout and just watch the rest?

Yes. Your code decides which answers to act on. Many sites start by holding blocked cashouts and only later refuse signups.

Keep reading