~/stepanic
All posts
RevenueCatIn-App PurchasesFlutterClaude CodeAI-native

Three years of RevenueCat, from docs-in-a-second-tab to an agent shipping the whole paywall

I've shipped RevenueCat to production across three Flutter apps since 2023. The SDK barely changed; the way I integrate it changed completely — from reading every doc by hand to an agent wiring the entire monetization layer.

I've shipped RevenueCat to production for three years across three Flutter apps. The interesting part isn't the SDK — it's how the way I integrate it changed: from reading every doc by hand in 2023, to an agent wiring the entire monetization layer in 2026. purchases_flutter itself climbed 8.10 → 9.9 → 10.x across the three, but that's the least interesting number here.

2023 — the manual era (The Birth Deck)

My first RevenueCat commit is literally named "Setup RevenueCat", dated 15 February 2023, in The Birth Deck — a FlutterFlow app I built for a consulting client. Back then "integration" meant a hand-written wrapper around purchases_flutter (8.10.1), products configured by clicking around the dashboard, and the docs open in a second tab.

The paywall started granular — individual cards, videos, a birth packing list, two bundles — and over three years collapsed to a single monthly subscription. The last edit (March 2026) is the only hand-written commit among ~40 FlutterFlow codegen syncs on those files. That long, messy evolution is the honest shape of a real subscription product: you don't get the catalogue right on day one.

2025 — cross-platform, 100% agent-built (smpltsk)

smpltsk is a task app I built end-to-end as the sole engineer for a consulting client — and 83% of its commits (447 of 536) are co-authored by Claude Code. RevenueCat is the system of record: a ~400-line service over purchases_flutter (9.9.0), a single premium_access entitlement, monthly / annual / a capped lifetime tier, live on Google Play and the App Store through the full review gauntlet. The parts I'm proud of are the seams:

  • One paywall, two billing systems. Mobile (iOS / Android / macOS) goes through RevenueCat; web and desktop fall back to Stripe in the same service, with a Cloud Functions webhook reconciling subscription state into Firestore. The app never has to care which rail a user came in on.
  • Provisioning as code. A single config.json is the source of truth, and Node scripts drive App Store Connect (API key), Google Play (service account) and RevenueCat's REST API v2 to create the products — plus a TestStore setup so the whole flow is testable without waiting on store review.

2026 — the agentic era (Perfect Training)

The most recent integration — Perfect Training, a sports-training app — went in over a two-day Claude Code sprint. As I write this it's in review on both stores (Apple came back with a few details to fix; the Android build has been pending production review for nine days — that part is never fast), so there are no live numbers yet — but the architecture is the most interesting of the three. RevenueCat identity is linked to Firebase Auth (including already-signed-in sessions), and a RevenueCat webhook writes entitlement state into Firestore.

The detail I like most is a security one: the webhook validates the incoming app_user_id against a strict UID regex before it ever touches a Firestore path — so a malicious client can't smuggle a crafted user id to write into someone else's document. It also deep-merges only the subscription fields the server owns, deliberately leaving admin-owned fields (like a manual override) untouched, and gates SANDBOX vs PRODUCTION events. Webhooks act on the real world; the blast radius has to be bounded.

The thing that closes the arc

This week I installed RevenueCat's own AI Toolkit — their Claude Code plugin plus a hosted MCP server — and went through it skill by skill. It configures the RevenueCat side (apps, products, entitlements, offerings) and reads store product state, but creating the actual products in App Store Connect, Play Console and Stripe still lands on a human. That's the same boundary I hit doing it by hand: the agent reaches a long way, and then there's a seam where the stores don't expose an API and a person steps in.

One security nuance worth knowing if you ship RevenueCat: the publishable SDK key in your app binary is public by design — anyone can pull it out of an APK. It identifies the app; it does not authorize reading the app's revenue. That's why features like Verified Metrics are explicitly opt-in: identity is not authorization. A good principle to carry into anything agent-facing.

Three apps, three years, one direction of travel: from me reading the docs to an agent writing the integration — with the human still owning the seams the machine can't reach yet.

Sources