Cryptocurrency Tracker docs
v2.0.0
Live demoConsole demo Get help
● Monetise · Store products

Pro and purchases
verified on the server.

Sell Pro (monthly, yearly or lifetime), Remove ads and an AI report pack through Google Play and the App Store. Every purchase is checked with the store by the backend before anything is granted.

Off by defaultGoogle Play Developer APIApp Store Server API

01Products

ProductDefault product idStore typeWhat the user gets
Pro monthlypro_monthlyAuto-renewable subscriptionPro until the subscription's expiry
Pro yearlypro_yearlyAuto-renewable subscriptionPro until the subscription's expiry
Pro lifetimepro_lifetimeOne-time (non-consumable)Pro for good
Remove adsremove_adsOne-time (non-consumable)No ads
AI report packai_pack_10ConsumableAI credits (10 per pack by default, 1–1000), one per AI coin report

You can change every product id in the console; use the same ids in both stores. You set the prices in Play Console and App Store Connect; they are not in the code.

What Pro gives

LimitFree (default)Pro (default)
Portfolios120
Active price alerts (enforced by the server)3100
Tracked wallets120
AI coin reports per day (with AI on)0 free, 1 by rewarded ad20
AdsAs configuredNone

The perks list on the Pro screen is editable (Console → Pro and purchases → Perks). Only list what Pro really gives.

02Switch it on

  1. Create the products in both storesWith the product ids above (or your own). Subscriptions in Play Console need a base plan; in App Store Connect put them in one subscription group.
  2. Set up verificationGoogle Play and Apple, below. Without it the API answers 503 iap_unconfigured and grants nothing.
  3. Fill in the consoleConsole → Pro and purchases: product ids, AI pack size, then turn on Offer Pro and Sell in-app purchases.
  4. TestWith a Play license tester and an App Store sandbox account (set App Store environment to Sandbox for TestFlight, back to Production for release).

03Google Play verification

The backend calls the Google Play Developer API (purchases.subscriptionsv2 and purchases.products) and reads the order for the price.

  1. Package nameConsole → Pro and purchases → Android package name (your application id, owner only).
  2. Credentials, option A: service account JSONIn Google Cloud, create a service account in your project and a JSON key. In Play Console → Users and permissions, invite the service account's e-mail with access to the app and the permission View financial data (the permission the code comment in firebase/functions/src/iap.ts names). Paste the whole JSON into Google Play service account (JSON) (write-only; the test checks only the file's shape).
  3. Credentials, option B: no JSONLeave the JSON empty and invite the Cloud Functions runtime service account (shown in Google Cloud → IAM) in Play Console the same way.

New Play permissions can take a while to apply. If verification fails right after setup, wait and try again.

04App Store verification

The backend calls the App Store Server API with an In-App Purchase key and decodes the signed transaction from Apple.

  1. Create the keyApp Store Connect → Users and Access → Integrations → In-App Purchase → generate a key. Download the .p8 file (only once) and note the Key ID and the Issuer ID.
  2. Enter themConsole → Pro and purchases: iOS bundle id, App Store Connect issuer id, In-app purchase key id, and paste the whole .p8 file including the BEGIN/END lines (write-only; the test only checks that it parses).
  3. EnvironmentSandbox for TestFlight and sandbox testers, Production for the App Store.

05How a purchase is granted

  • The app buys through Flutter's official in_app_purchase plugin and sends the purchase to POST /v1/purchases/verify. The app never grants anything itself.
  • The backend verifies with the store, then grants Pro, Remove ads or AI credits. Each order is recorded once (purchases/{platform}_{orderId}), so a repeated request never grants twice and a pack is never credited twice.
  • Restore purchases (on the paywall and in Settings) sends the store's restored purchases through the same check.
  • A subscription grants Pro until the expiry the store reports. A newer verified expiry extends it. There are no server-to-server store notifications in 2.0.0: a renewal is picked up when the app sends the renewed purchase again, for example after Restore purchases.
  • You can also grant Pro (until a date or for life), Remove ads or AI credits by hand on the console's Users page, with a reason. Console grants are separate from store grants.

Source: firebase/functions/src/api/commerce.ts, firebase/functions/src/iap.ts, app/lib/iap/purchase_service.dart.

06Revenue records

When the store reports the price of a new verified order, the backend writes a revenue event with the amount and currency exactly as reported (source store). It is shown in the Revenue centre. A subscription is recorded once, with its first verified order; renewals extend Pro but are not added as new revenue events. Store fees and taxes are not deducted. Your store payout reports remain the authoritative figures.

07In the web demo

Purchases are simulated and labelled "Demo — no charge". Nothing is bought or charged.