Purchase Testing

Test purchases, restore flows, and entitlement updates.

Purchases require a native development, preview, or store build. Expo Go and web can render the rest of the starter, but they cannot exercise react-native-purchases.

iOS purchases are end-to-end with the shipped webhook. Android can load the RevenueCat SDK when configured, but Google Play webhook events are ignored by the current Supabase mapper. Extend the webhook before treating Android purchase tests as entitlement tests.

Build requirement

Use an EAS development build or a store-distribution build:

eas build --profile development --platform ios
eas build --profile development --platform android

Set the RevenueCat key for the platform you test:

EXPO_PUBLIC_REVENUECAT_IOS_KEY=appl_xxxxxxxxxxxxxxxxx
EXPO_PUBLIC_REVENUECAT_ANDROID_KEY=goog_xxxxxxxxxxxxxxxxx

Restart Metro after env changes. Rebuild after bundle/package ID, signing, or store configuration changes.

Store test accounts

Use a real device whenever possible.

Create a sandbox tester

In App Store Connect, create a sandbox tester under Users and Access → Sandbox Testers. Use an email that is not already an Apple ID.

Install a native build

Install a development build, internal distribution build, or TestFlight build whose bundle identifier matches the products you configured.

Sign into the sandbox account

On the device, sign into the Sandbox Account from App Store or Developer settings, depending on iOS version.

Use a Play-distributed test build when testing Google Play Billing.

Configure license testers

In Play Console, add license testers and make sure the tester can access the internal, closed, or open testing track that contains your build.

Match package and signing

The package name and signing certificate must match the app and products in Play Console. Variant IDs such as expo.soarstarter.com.dev need their own product setup if you test them.

Extend the webhook before entitlement testing

The current RevenueCat Edge mapper ignores PLAY_STORE. Android purchase UI can be tested, but the Supabase entitlement row will not update until that backend path is implemented.

Run an iOS purchase test

Sign into the app

Launch the native build and sign into a Supabase account. RevenueCat identity sync must use that Supabase user UUID before purchase.

Open the paywall

Open Home's license card, Me → Upgrade to Pro, or /paywall. Confirm packages load from the current offering and Annual is selected when present.

Buy a package

Tap Continue and approve the sandbox purchase sheet. The paywall closes on success and entitlement.pollAfterPurchase() starts polling Supabase for the authoritative row.

Verify RevenueCat

In RevenueCat, switch to sandbox data and find the customer whose App User ID is the Supabase user UUID. The pro entitlement should be active.

Verify Supabase

Run a SQL check in Supabase:

select user_id, provider, product_id, product_type, status, period_end
from public.subscriptions
where user_id = 'your-supabase-user-uuid';

For an App Store purchase, expect provider = 'app_store', status of active or trialing, and period_end in the future. Lifetime purchases use product_type = 'one_time'.

Restore test

  1. Reinstall the native build or sign out and back in.
  2. Use the same store sandbox account and the same Supabase account.
  3. Open the paywall or Manage subscription.
  4. Tap Restore purchases.
  5. Confirm RevenueCat returns an active pro entitlement and the app polls the Supabase row.

Restore checks RevenueCat's purchase cache; the actual gate still depends on the subscriptions row.

Common failures

SymptomLikely causeFix
Paywall says purchases are not configuredMissing platform RevenueCat key, web runtime, or Expo GoSet EXPO_PUBLIC_REVENUECAT_IOS_KEY / EXPO_PUBLIC_REVENUECAT_ANDROID_KEY and use a native build
Packages never loadNo current offering, packages missing, product metadata incomplete, or store sync delayActivate the offering, attach packages, complete store metadata, wait for sync
User is asked to sign in before buyingNo Supabase sessionSign in first so the purchase is tied to the account UUID
Bundle/package mismatchTesting expo.soarstarter.com.dev while products were created for production IDConfigure products for the active variant or build the matching variant
RevenueCat entitlement active but Supabase row missingWebhook URL/Authorization wrong, function not deployed, or app_user_id is not a UUIDRecheck REVENUECAT_WEBHOOK_AUTH, function logs, and RevenueCat customer ID
Android purchase does not unlock Supabase entitlementCurrent webhook ignores PLAY_STORE eventsExtend the webhook mapper and database enum before Android entitlement testing
Restore finds nothingDifferent store sandbox account, different Supabase account, or no active purchaseUse the same accounts, or test with a fresh sandbox purchase

On this page