In-app purchases
store setup and verification.
VIP subscriptions (monthly and yearly), a one-time remove-ads purchase and consumable boosters and point packs, through Google Play and the App Store. Off by default. Every purchase is verified on the server before anything is granted. What each product does and the store rules: VIP, boosters and packs.
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), no non-rewarded ads, VIP-only games, the VIP season track and the vip badge (VIP). |
| VIP yearly | vip_yearly | Auto-renewing subscription | Same as monthly. |
| Remove ads | remove_ads | Non-consumable (one-time) | Sets adsRemoved: no app-open, interstitial, banner, native or rewarded-interstitial ads. Rewarded videos stay available. |
| Booster | booster_2x_30m | Consumable | Sets boostUntil and boostMultiplier. Does not stack with VIP (Boosters). |
| Point pack | none by default | Consumable | Adds spendable points, ledger type purchase (Point packs). |
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 applies it. Each order is applied once (purchases/{platform_orderId}). The app then completes the purchase with the store, and consumes boosters and packs (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, plus one in-app product per booster or point pack you sell. 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. Boosters and point packs are consumables.
- Different ids?Enter yours in the console: VIP monthly product id, VIP yearly product id, Remove-ads product id, and the Boosters and Point packs lists.
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. The same permission lets the backend read the order price from the Orders API for the revenue centre. Without it the purchase is still verified, but recorded as "price not reported".
- 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.
Sell boosters (consumable) and Sell point packs (consumable) are separate switches. Read Store policy before you turn them on.
Digital features such as VIP, ad removal, boosters and points 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 Store policy.