Why I dropped RevenueCat for native billing
The studio verifies purchases with StoreKit 2 and Play Billing directly, through one shared Cloud Function, with no third party billing middleman. Here is the tradeoff and why it wins at this scale.
Third party billing tools are a great default. They take a real problem, receipt verification and subscription state, and make it a few lines. I used one, then moved every app off it to native billing. Here is why, honestly, because it is a tradeoff, not a free win.
The setup
The client wraps the platform APIs directly: StoreKit 2 on iOS, Play Billing on Android, through one shared billing client package. A Cloud Function verifies each purchase against the App Store Server API and the Play Developer API, then writes the entitlement to Firestore. Store webhooks, Apple server notifications and Google real time developer notifications, hit the same function so renewals, cancels, refunds, and grace periods stay in sync. The app gates features by streaming the entitlement in real time.
No middleman sits between the app and the money. The verification logic is a shared codebase deployed into each app's own Firebase project.
Why move off the middleman
- One less dependency in the money path. Billing is the most important flow in a paid app. Owning the verification means no outage, pricing change, or policy shift from a third party can touch revenue.
- Cost. A revenue share or per tracked user fee is fine early and expensive later. Native billing is just the platform fees plus a trivial Cloud Function.
- It is shared once. The hard part, correct server side verification and webhook handling, is written once and reused across every app. The marginal cost of native billing on the next app is close to zero, which removes the usual reason to reach for the shortcut.
The honest cost
Native billing is more code than dropping in an SDK. Server notifications and the store server APIs have real edge cases: grace periods, billing retry, refunds, upgrades mid cycle. You have to handle them. The reason it is worth it here is the same reason the whole studio works: solve it once in the shared layer, then it is done for every app.
If you ship one app and never a second, use the middleman. If you are building a portfolio, own the money path. Write it once, reuse it forever.
One operator, idea to live product. Web and mobile, designed and shipped end to end.
Work with meFrequently asked
- Why not use a billing SDK like RevenueCat?
- For a single app it is a fine default. For a portfolio, owning verification removes a dependency in the money path and cuts per user fees, and the work is reused across every app.
- How are purchases verified?
- A Cloud Function checks each purchase against the App Store Server API and the Play Developer API, then writes the entitlement to Firestore. Store webhooks keep renewals and refunds in sync.
- Is native billing more work?
- Yes, up front. The edge cases are real. But it is written once in a shared layer, so the marginal cost on the next app is near zero.
Related
How I ship a production app in a week, solo
The studio pipeline that turns an idea into a live iOS and Android app: a shared product engine, a rebrand starter, and native billing wired once and reused everywhere.
ReadAn AI-native product studio, one operator
The thesis behind Principle Socials: an agentic pipeline that ships at small team quality and speed, run by a single operator, selling outcomes rather than hours.
ReadOne landing template for every app
Instead of hand building a marketing site per product, the studio runs one config driven Next.js landing template. Two presets, one brand file, and a new site is a clone.
Read