Watch And Earn docs
v4.0.0
Live demoConsole demo Get help
● Cash wallet · Overview 4.0

Wallet and payouts
two balances, never mixed.

Version 4.0 adds an optional cash wallet next to the points. Cash comes only from verified partner offers and surveys, and users cash it out by PayPal, crypto, bank transfer or gift cards after you review the request. Everything about money ships switched off.

Off by defaultPoints never become cashAndroid on, iOS and web off

01Two balances

From docs/CONTRACT-4.0.md §0 in the package.

Points (since 3.0)Cash wallet (new in 4.0)
Earned fromRewarded ads, rewarded interstitials, streak, check-in, wheel, scratch cards, quizzes, mini-games, tasks, season, achievements, events, promo codes, partner offers (console → Offers), referral pointsOfferwall offers, surveys and playtime offers (S2S-verified provider payouts), the referral commission on those, and cash you grant by hand in the console (for example a contest prize)
Spent onRewards store cosmetics, boosters, mystery box, operator rewardsPayouts: PayPal, crypto, bank transfer, gift cards
Cash valueNone. A non-transferable in-app scoreReal money you owe the user

In the app both balances sit side by side on Home. The cash side only appears where the wallet is on for that platform (below).

02The hard rule: points never become cash

No conversion, no exchange rate, no "cash out points"

There is no code path from points to the cash wallet. Rewarded ads, games, streaks, check-ins and every other points source credit points only, and no console setting can change that (docs/CONTRACT-4.0.md §0). Do not add such a path in your own changes.

Why. Google AdMob's policies for ad units that offer rewards do not allow direct monetary items, such as cash, cryptocurrency or gift cards, as a reward for an ad view, under any circumstance. Points that could later be turned into money would make every rewarded video a cash reward. Read the current policy yourself: AdMob policies for ad units that offer rewards. Other ad networks have similar rules in their publisher policies.

Cash in this app is a share of what an offerwall or survey provider pays you for a completed offer or survey. The user does a task for that provider, and the provider confirms it server-to-server. No ad view is paid in cash.

Tests enforce the rule, so a change that breaks it fails the build:

  • firebase/functions/test/unit/wallet.test.ts, block "HARD RULE": only the wallet code, offerwall/core.ts and the function entry points reference wallet code; points sources never mention it; wallet code never credits or debits points; no config key converts points to cash.
  • firebase/functions/test/integration/wallet.test.ts: rewarded ads, the wheel, the check-in and a 4.0 game in cash mode leave no wallet.
  • app/test/no_cash_out_test.dart: no code, comment or string in the app offers points for cash in any language; the backend interface has no method that takes points and returns cash; in the demo, ads, games, streaks, spins and quizzes leave the wallet at 0.

03What ships switched off

SwitchDefaultWhere
Cash wallet and payouts (wallet.enabled)offConsole → Wallet & payouts
Every payout method (the enabled switch of each entry in wallet → methods)offConsole → Payout methods
Auto-approve small requests (wallet.autoApprove)offConsole → Wallet & payouts
Offerwall and survey rewards are paid as (economy.offerwallRewardMode)points (3.1 behaviour)Console → Offerwalls and surveys
PayPal Payouts API credentialsempty = manual payoutsConsole → PayPal Payouts (owner)

With these defaults 4.0 behaves like 3.1 for money: offerwalls and surveys credit points, and the app shows no wallet. The console writes a switch that cannot work as off and says why on the Status page: cash rewards while the wallet is off, crypto without a valid asset, gift cards with an empty catalog (admin/README.md).

04Pending, available, locked

Every wallet amount is a whole number of minor units (cents) of the wallet currency, never a decimal (docs/CONTRACT-4.0.md §1). Each wallet has three buckets (wallets/{uid}):

BucketWhat is in itMoves to
PendingNew cash from an offer, survey or referral commission, during the hold (wallet.holdDays, default 14)Available, by the hourly job releaseWallet once the hold has passed. A provider reversal inside the hold removes it.
AvailableCash the user can request. Grants you type in the console land here at once.Locked, when the user requests a payout
LockedThe amount of every open payout requestPaid (leaves the wallet), or back to available when a request is rejected, cancelled or fails

The wallet also keeps lifetime earned (net of reversals) and lifetime paid. Every change is one ledger entry in wallets/{uid}/entries written in the same transaction, with the balances after it. Entry types: offer, survey, referral, grant, reversal, payout, payout_refund, release (and playtime, reserved; playtime offers from the walls are credited as offer, firebase/functions/src/offerwall/core.ts).

A negative available balance is possible

If a provider reverses an offer after the cash was released or paid out, the available balance can go below 0. The user cannot request payouts until new earnings bring it back above 0. The console highlights such wallets (Reversals).

05Currency

wallet.currency is an ISO code, default USD. Providers pay in USD. For another currency set wallet.usdRate ("1 USD = … wallet currency", a decimal you type, for example 0.92). The backend converts with integer math, rounding half down, and stores both amounts (firebase/functions/src/wallet/money.ts).

Choose the currency before the first credit

Balances are never converted. Changing the currency later leaves old amounts in the old currency's units. The console help says the same.

06Platforms

wallet.platforms and offerwalls.platforms default to Android on, iOS off, web off. Where the wallet is off, the app shows no cash balance and the Wallet tab becomes the Rewards store; where offerwalls are off, the walls are hidden. The server also refuses payout requests from a platform that is off (reason platform). Why iOS is off: Platform rules.

07What users see

  • Home: both balances (points and cash) and a "next payout" progress bar towards the smallest method minimum.
  • Wallet tab: pending, available and locked with a short explanation each, a "How cash works" sheet stating the two-balance rule, the payout methods you enabled with their minimum, fee and processing time, the request flow (amount → destination → review fee and net → confirm), and the history with a status for every request. A pending request can be cancelled.
  • Wallet notice: your text from console → Wallet & payouts → Wallet notice shown in the app (default: "Cash rewards come from completed partner offers and surveys. Points from ads and games have no cash value."). Keep that meaning.
  • Gift cards: once you mark a gift-card request paid, the user reveals the code in the app (revealGiftCode). The inbox message only says the card is ready.
  • Inbox: a message when a request is paid, rejected (with your reason) or failed.

In the web demo (DEMO_MODE=true) the wallet runs on labelled demo cash, "Demo — no real money", credited only by simulated offer completions; demo payout requests stay pending and never leave the device (Quick start).

08Switching the wallet on

Follow this order. Each step links to the details.

  1. Check the legal side firstKYC/AML and tax duties where they apply, PayPal's terms, consumer law, your terms and privacy policy. Your legal duties. Required
  2. Publish your payout termsMinimums, fees, hold period, review, reversals, limits, countries. Link them from your terms (console → Legal).
  3. Have offerwalls or surveys working in points modeAt least one provider verified with a test postback. Offerwalls and surveys.
  4. Set up the walletConsole → Wallet & payouts: currency, user share, VIP share, hold days, referral commission, limits, review threshold, notice. Leave auto-approve off at first. Cash mode.
  5. Enable the payout methods you will really payMinimums, fees, countries; the crypto assets, bank fields or gift-card catalog. Optional: PayPal Payouts API. Payout methods.
  6. Switch the wallet on, then the reward mode to cashConsole → Wallet & payouts → Cash wallet and payouts on; then console → Offerwalls and surveys → Offerwall and survey rewards are paid as → Cash in the wallet.
  7. Test end to end with your own accountA test postback credits pending cash; set the hold to 0 for the test or wait for it; request the smallest payout; approve and pay it (PayPal sandbox, or by hand); check the user's history and the console's Business page.
  8. Fund your payout accountsYour PayPal balance, crypto wallet or bank account must cover what you approve. Watch Owed to users now on the Business page. Business page.
Paid services

Payouts cost money beyond the cash itself: PayPal fees for Payouts, network fees for crypto, bank charges, and the price you pay your gift-card supplier. You also need the Firebase Blaze plan, offerwall and survey publisher accounts, ad network accounts, store developer accounts and hosting for the console (Paid services). Check each provider's current pricing yourself.

09Where the data lives

CollectionWhatWho reads it
wallets/{uid}, wallets/{uid}/entriesBalances and ledgerThe user (own wallet only), the console, Functions. Only Functions write.
payoutRequests/{id}Requests with method, amount, fee, net, destination, status, review flags, provider referencesThe user (own requests), the console. Only Functions write.
payoutDestinations/{sha256}Which accounts used the same destinationFunctions and console only
payoutEvents/{id}One cost event per paid payout (measured cost)Functions and console only
walletOps/{id}Console actions waiting for the backend (approve, reject, mark paid, PayPal send, grant, freeze)Console writes, Functions apply
stats/walletLive totals: what you owe users nowConsole
config/private.walletPayPal credentials and the gift-card encryption keyFunctions and console only, never the app

Account deletion keeps money records. deleteAccount does not delete wallets/{uid} or payoutRequests. Remove them by hand only after you have settled what you owe, and say in your privacy policy how long you keep them (firebase/README.md §13).