RevenueCat Setup

Configure RevenueCat products, SDK keys, and webhooks.

RevenueCat setup is dashboard work: create store products, attach them to one RevenueCat entitlement, expose them through an offering, add public SDK keys to Expo, and wire the webhook to Supabase.

The app can configure RevenueCat on iOS and Android, but the shipped Supabase webhook currently maps App Store events only. Treat iOS as end-to-end today. Before shipping Google Play purchases, extend providerForStore() and the billing_provider enum to handle PLAY_STORE.

Store prerequisites

In App Store Connect:

Create the app record

Create an iOS app record for the active bundle identifier. By default the variants are:

development: expo.soarstarter.com.dev
preview:     expo.soarstarter.com.preview
production:  expo.soarstarter.com

Only store-capable bundle IDs should get real App Store products. Development and preview IDs are useful for internal builds, but they need matching products if you test purchases against them.

Complete paid-app requirements

Finish paid-app agreements, tax, and banking. Products often fail to load until these are complete.

Create products

Create a subscription group with monthly and yearly auto-renewable subscriptions, plus an optional non-consumable lifetime product. Product IDs are yours to choose; the app reads products from the RevenueCat offering and does not require hard-coded IDs.

In Google Play Console:

Create the app and package

Use the Android package from app.config.ts. The default variants are:

development: expo.soarstarter.com.dev
preview:     expo.soarstarter.com.preview
production:  expo.soarstarter.com

Match the package name and signing key used by the build you test.

Configure monetization

Finish merchant account setup, create subscription products for monthly/yearly plans, and create an in-app product if you want a lifetime purchase equivalent.

Plan the backend extension

The client can use EXPO_PUBLIC_REVENUECAT_ANDROID_KEY, but the current revenuecat-webhook ignores PLAY_STORE events. Extend and test that mapper before relying on Android purchases for Supabase entitlement.

RevenueCat project

Add platform apps

In RevenueCat, create a project with an App Store app and, if you plan Android, a Google Play app. Copy the public app-specific SDK keys:

EXPO_PUBLIC_REVENUECAT_IOS_KEY=appl_xxxxxxxxxxxxxxxxx
EXPO_PUBLIC_REVENUECAT_ANDROID_KEY=goog_xxxxxxxxxxxxxxxxx

These are public SDK keys and belong in .env.local or EAS environment values.

Add products

Create RevenueCat products that point at the store product IDs. The Expo app does not read product IDs from env; RevenueCat's product catalog is the source.

Create the entitlement

Create one entitlement with identifier:

pro

Attach monthly, yearly, and lifetime products to that same entitlement. The identifier must match PRO_ENTITLEMENT_ID in lib/purchases.tsx.

Create the offering

Create or activate the current offering and add packages:

Package type: Monthly
Package type: Annual
Package type: Lifetime

The paywall reads offerings.current. If no current offering exists, the app shows the "Couldn't load subscription options" state.

Wire the Supabase webhook

Deploy revenuecat-webhook and set REVENUECAT_WEBHOOK_AUTH from Supabase Setup. Then in RevenueCat Project settings → Integrations → Webhooks, add:

FieldValue
URLhttps://your-project-ref.supabase.co/functions/v1/revenuecat-webhook
AuthorizationThe same value as REVENUECAT_WEBHOOK_AUTH

The function has verify_jwt = false because RevenueCat is not a signed-in Supabase user. It verifies the static Authorization header, then uses the service role to upsert subscriptions.

Sandbox events are processed the same way as production events and only touch the row whose user_id matches the RevenueCat app_user_id.

Expected end state

Expo env        -> RevenueCat public SDK key for each native platform
RevenueCat app  -> iOS app configured; Android app optional until webhook support is extended
Entitlement     -> identifier "pro"
Offering        -> current offering with Monthly / Annual / Lifetime packages
Supabase        -> revenuecat-webhook deployed with REVENUECAT_WEBHOOK_AUTH

On this page