In-app purchases
VIP and remove-ads.
An optional VIP subscription (monthly and yearly) and a one-time remove-ads purchase through Google Play and the App Store. Off by default. Every purchase is verified on the server before anything is granted.
01What the buyer of a purchase gets
| Product | Default product id | Store type | Effect |
|---|---|---|---|
| VIP monthly | vip_monthly | Auto-renewing subscription | Sets vipUntil. While active: points multiplier (economy.vipMultiplier, default 1.5) on ad, spin, scratch, quiz and task credits, no interstitials or banners, and the vip badge. |
| VIP yearly | vip_yearly | Auto-renewing subscription | Same as monthly. |
| Remove ads | remove_ads | Non-consumable (one-time) | Sets adsRemoved: no interstitials or banners. Rewarded videos stay available. |
The app never grants itself anything. It sends the store token to the callable verifyPurchase (firebase/functions/src/iap.ts), which checks it with the Google Play Developer API or the App Store Server API and then sets vipUntil or adsRemoved. The app then completes the purchase with the store (app/lib/iap/purchase_service.dart).
The purchase flow is covered by an emulator integration test with a stand-in store (firebase/functions/test/integration/callables.test.ts), but it was not run against a live Play or App Store account when these docs were written. Test the full flow with Play's license testers and Apple's Sandbox (TestFlight) before release.
02Create the products in the stores
- Google Play ConsoleMonetize → Products. Create the subscriptions
vip_monthlyandvip_yearlyand the in-app productremove_ads. You need to upload a build that contains the billing library first (any internal-testing build of this app does). - App Store ConnectYour app → Monetization. Create two auto-renewable subscriptions in one group and one non-consumable with the same ids.
- Different ids?Enter yours in the console: VIP monthly product id, VIP yearly product id, Remove-ads product id.
03Let the server verify Google Play purchases
- Find the Functions service account
PROJECT_ID@appspot.gserviceaccount.com, or the compute default service account shown in Cloud Console → Functions → your function → Details. - Invite it to Play ConsoleUsers and permissions → Invite new users → that e-mail, with View financial data for your app.
- ConsoleSubscriptions and purchases → Android package name = your application id.
04Let the server verify App Store purchases
- Create an In-App Purchase keyApp Store Connect → Users and Access → Integrations → In-App Purchase. Download the
.p8file (only once possible). - ConsoleSubscriptions and purchases: iOS bundle id, App Store Connect issuer id, In-app purchase key id, and paste the whole
.p8file including the BEGIN/END lines into In-app purchase key (write-only, owner only). - EnvironmentApp Store environment = Sandbox (TestFlight) while testing, Production after release.
05Switch it on
Console → Subscriptions and purchases → Sell VIP and remove-ads. The app then shows the VIP screen with the products and their prices as the stores return them. Apple requires a working "Restore purchases"; test it in Sandbox.
Digital features such as VIP and ad removal must be sold through the store's in-app purchase system (Apple App Review Guideline 3.1.1, Google Play Payments policy). Do not add an external payment link for them. See Policy and compliance.