TechnicalApril 2026 · 12 min read

In-App Purchases for Expo: RevenueCat Setup from Zero

Subscriptions are how most 2026 mobile apps make money — and the plumbing to accept them is where first-time founders lose weeks. This guide walks through setting up RevenueCat in an Expo app from a clean install to a working paywall, including the App Store Connect and Play Console setup most tutorials skip.

Quick path

Install react-native-purchases, configure a dev build via EAS, create products in App Store Connect and Play Console, link them in RevenueCat, add a paywall component, and test in sandbox. Expect 2–3 hours end-to-end on a clean project.

Why RevenueCat (and not DIY)

You can call StoreKit and Play Billing directly. You probably should not. RevenueCat abstracts away the parts that burn time and cause production bugs:

  • Receipt validation (server-side, already hardened)
  • Unified entitlements across iOS and Android (one user, one subscription state)
  • Free trials, intro offers, and promotional codes out of the box
  • Webhooks for granting access on your backend
  • Analytics that matter — MRR, churn, LTV — without you wiring them

The free tier covers tracked revenue up to $10k/month. You pay 1% above that. For almost every indie app, the time saved is worth more than the percentage.

Prerequisites

  • An Apple Developer account ($99/year) and a paid tax/banking profile in App Store Connect
  • A Google Play Developer account ($25 one-time) with merchant account set up
  • An Expo project using EAS Build (Expo Go does not support in-app purchases)
  • A RevenueCat account (free to sign up)
  • At least one sandbox test account per platform

Step 1: Install and configure the SDK

npx expo install react-native-purchases

# Add to app.json plugins:
# "plugins": ["react-native-purchases"]

# Build a dev client:
eas build --profile development --platform ios
eas build --profile development --platform android

Install the dev client on your device. From now on, run npx expo start --dev-client instead of Expo Go.

Step 2: Create products in App Store Connect and Play Console

Do this before touching any code. For a standard subscription app:

  • App Store Connect: Features → In-App Purchases → Create subscription group → Add products (monthly, annual). Set prices, localize for each region.
  • Play Console: Monetize → Subscriptions → Create base plan for each SKU. Match the product IDs you used on iOS.
  • Keep product IDs identical across platforms: e.g., pro_monthly and pro_annual.

Step 3: Wire products into RevenueCat

In the RevenueCat dashboard:

  1. Create a project, add both iOS and Android apps with bundle IDs.
  2. Upload your App Store Connect API key and Play Service Account JSON for receipt validation.
  3. Import products using the same IDs you created in both stores.
  4. Create an Offering (e.g., default) with two Packages: monthly and annual.
  5. Create one Entitlement (e.g., pro) and attach both products to it.

Step 4: Initialize and render a paywall

import Purchases from 'react-native-purchases';

// In your app entry (e.g., _layout.tsx):
Purchases.configure({
  apiKey: Platform.OS === 'ios' ? IOS_KEY : ANDROID_KEY,
});

// Check if user has entitlement:
const info = await Purchases.getCustomerInfo();
const isPro = info.entitlements.active.pro !== undefined;

// Show paywall:
const offerings = await Purchases.getOfferings();
const pkg = offerings.current.monthly;
await Purchases.purchasePackage(pkg);

For a ready-made UI, RevenueCat ships react-native-purchases-ui — paywall components you configure in the dashboard and render with a single component. This is the fastest path for most apps.

Step 5: Test in sandbox

Test before you ship — subscription bugs are the most expensive bugs.

  • iOS: App Store Connect → Users and Access → Sandbox Testers → create a fresh tester. On device, sign out of real Apple ID first. Do not sign into sandbox manually — let the app prompt you.
  • Android: Play Console → Setup → License testing → add your Gmail. Ship an internal testing build and purchase as the tester account.
  • Sandbox time-scaled renewals: iOS renews a monthly subscription every 5 minutes in sandbox. Useful for testing renewal logic quickly.

Common gotchas

  • Bundle ID mismatch: The bundle ID in App Store Connect must match your Expo app exactly. A one-character typo sinks every build.
  • Pending transactions on resume: Always call Purchases.getCustomerInfo() on app resume. Users sometimes complete purchases outside your app flow.
  • Restore Purchases button: Apple requires it. Add a visible Restore Purchases option in settings — a review rejection trigger if missing.
  • Trials cancel without refunding: Apple deducts the trial from paid time if the user subscribes after canceling. Explain this clearly in your paywall copy.

Generating a paywall-ready app faster

If you generate your app with ShipNative, a paywall screen and RevenueCat integration can be scaffolded in the initial prompt — just describe your monetization model in the description. You still do the App Store Connect and Play Console work yourself, but the in-app plumbing arrives wired.

Frequently Asked Questions

Does RevenueCat work with Expo managed workflow?

Yes. RevenueCat ships a Config Plugin (react-native-purchases) that works with EAS Build. You cannot test in-app purchases inside Expo Go — you need a development build or a TestFlight / internal testing build.

Should I use RevenueCat or roll my own with StoreKit and Play Billing?

Use RevenueCat unless you have a specific reason not to. Rolling your own means handling receipt validation, subscription state, trials, refunds, promotional offers, and cross-platform entitlements yourself. RevenueCat does all of it for a small cut (1% of tracked revenue on the free tier, zero below $10k/month in 2026 pricing).

How do I test in-app purchases without real money?

On iOS: use a Sandbox tester in App Store Connect. On Android: add your test account in Play Console and use internal testing. Both platforms let you test subscriptions, trials, and renewals without charging real cards.

Why do users see "This Apple ID has not been used with iTunes"?

This is the most common sandbox testing error. The user needs to sign out of their real Apple ID, then sign into sandbox when prompted by the app. Do not sign in via Settings — wait for the app to prompt.

Can RevenueCat handle web-based subscriptions too?

Yes. RevenueCat added Stripe web billing in 2024. You can run a unified subscription system across iOS, Android, and web — useful if you have a companion website or cross-platform access.

React Native Authentication 2026

Auth is the other foundational block before monetization.

Read guide →

Expo EAS Submission Checklist

Everything else to verify before App Store review.

See checklist →

Ship a real React Native app today

Describe, preview, and export Expo code — free to start.

Build with ShipNative →