Donate to support freedom.
Get the same

In-App Purchases & Subscriptions

StoreKit and Google Play Billing setup for subscription tiers, trials, paywalls, server-side receipt validation, and entitlement sync across devices.

In-App Purchases & Subscriptions

A subscription can look finished in a demo and fall apart in production. The purchase sheet appears, a test card approves, and everyone moves on. Then a user reinstalls the app, the paywall returns, and support gets an email about a charge they already paid.

Apple and Google each run their own billing system, and both expect your server to confirm every purchase and renewal. Most of the work is deciding what a paying user is entitled to, where that is stored, and what the app does when a store notification, a flaky network, or a declined card gets in the way.

What the work covers

Product and subscription setup in App Store Connect and Google Play Console: subscription groups, tiers, monthly and yearly durations, trials, introductory offers, and win-back offers where supported. Consumables for one-off items such as credit packs.

Paywall and purchase screen design: where the offer appears, what the free tier keeps, which plan the screen leads with, and how the price reads in each storefront.

Validation, entitlement storage, restore across devices, and the event stream for renewals, cancellations, billing retries and refunds. Reporting covers trial to paid conversion, renewal rate by plan, and billing-issue churn against voluntary churn. Store events land in the same table as your product analytics, which our mobile analytics and crash reporting service sets up.

Who this is for

Apps that sell digital content, premium features or credits inside the app.

Free apps adding a subscription, including apps that currently live on ads.

Teams with web billing through Stripe or similar who need mobile plans kept in step with the website.

Where the project starts

A plain idea. We set up the store products, the plan structure and the entitlement model before code exists, so the first build ships with a purchase path tested through sandbox and review.

An existing conventional codebase. We add billing to an app that already has accounts, a backend and a release history. The work is fitting it to the existing user model and serving entitlements to both platforms from one source, and if the app predates StoreKit 2 and the current Play Billing library, that upgrade is part of the job.

An AI or vibe-coded prototype. These usually contain a paywall that reads a local boolean, receipt checks that run on the device, and a product list hardcoded in the app. We keep the screens and the idea, move validation to the server, and add the renewal, restore and refund handling the prototype did not need before it had paying users.

What we deliver

Product and plan configuration in both consoles, including trials, introductory offers and tier upgrade paths.

Paywall and purchase screens matching your design, with restore and manage subscription entry points.

A validation service that verifies Apple and Google transactions server-side and stores entitlements against your accounts, or the store transaction for account-free apps.

App Store Server Notifications and Google Real-time Developer Notifications wired to that service and processed idempotently.

Cross-device restore and a reconciliation job that rechecks entitlements near expiry.

Cancellation, refund and billing retry handling, including revocation after a refund.

Test accounts, sandbox guidance and a runbook for your team.

How entitlements are validated

The app never decides whether someone has paid. When a purchase completes, StoreKit or Google Play Billing returns a signed transaction: a JWS signed by Apple, or a purchase token from Google. The app sends that payload to our backend with the account it belongs to.

The backend verifies it against the store and trusts nothing in the payload on its own. For Apple we call the App Store Server API and confirm the signature chain, bundle ID, product ID and expiry. For Google we call the Play Developer API with the purchase token and check the package name, product ID, purchase state, acknowledgement state and expiry. The outcome lands in an entitlement row holding the product, status, expiry, store environment and last check time. The client reads entitlements on launch and after any purchase, and holds a short-lived signed token so a brief outage does not cut access. Renewals arrive as App Store Server Notifications V2 and Google Real-time Developer Notifications over Pub/Sub, each with an idempotency key, so a duplicate delivery changes nothing.

When validation does not succeed:

A transaction that fails verification is rejected and logged with its raw payload. The app shows the purchase as pending and points the user to support. Access stays closed until the record checks out.

A store API timeout, or an outage on our side, is handled differently. The user keeps access through a bounded grace window measured from the last verified expiry, and the reconciliation job rechecks once the store responds. Locking out a paying subscriber because an external API is slow costs more than a short window of unverified access.

Refund, revocation and chargeback events mark the entitlement expired immediately, while a cancellation keeps access until the paid period ends.

A restore on another device runs the same validation path, so Apple's sync call and Google's purchase query both become server-checked.

How the engagement runs

We start with the store accounts and the plan design, because product IDs, tiers and offer rules are hard to change once real subscribers are on them. That step ends with a written plan structure and a policy check on how purchases will be presented.

Then the validation service and entitlement model, tested against sandbox purchases, TestFlight builds and Play testing tracks. After that come the paywall, notifications, reconciliation, refund handling and reporting, then release and the first renewal cycle, where the useful billing bugs tend to appear.

What it costs

Work is quoted at our flat rate of $39 per hour or as a fixed scope once we have seen the plans and stores involved. On a full app build, the purchase path belongs in the first release, so it falls inside the mobile MVP typical order on the pricing page: $4,800 to $8,500 across four to six weeks.

Adding a subscription layer to an app that already exists is a smaller piece of work, usually a few weeks. Scope depends on the number of stores and plans, how many offer types you want live, whether a web billing system has to stay in sync with mobile, whether older receipts need migrating, and how much churn reporting you want. We quote those in phases, and you get a single figure before work starts.

Proof

Voice VPN is our in-house Flutter VPN app, monetized through credits: users watch ads for them, buy them directly, or earn them through referrals, while the tunnel stays at full speed. It shows we have shipped purchase and reward logic inside a live mobile product and made deliberate calls about what stays free.

Easy VPN Free is our open-source Android VPN app with no accounts, no logs and no monetization. It covers the other end of that decision: we know when a paid tier would break a product and will say so before adding billing.

SmartAIChats is our AI chat platform, sold through a pricing path that lets a business start small and expand as usage grows. It covers plan-based access and the update rules behind a recurring product, the entitlement logic a mobile subscription depends on.

Related services

Next step

If you have a paywall that has never been through a store review, or plans to launch subscriptions on iOS and Android, send us your product IDs and the free tier you have in mind. We will say what the entitlement model needs before the first charge.

Contact us with a link to your app or store listing, or run your scope through the Vasilkoff.info estimator for a first cost and timeline range.