💳 Payments with RevenueCat
Shipnative integrates with RevenueCat to simplify in-app purchases and subscriptions across iOS, Android, and Web. RevenueCat handles the complexities of platform-specific billing APIs, allowing you to manage all your subscriptions from a single dashboard.RevenueCat Project Setup
1. Create Your RevenueCat Account
If you don’t have one, create a free account on RevenueCat:- Go to https://app.revenuecat.com/.
- Sign up and create a new project.
2. Configure Your Apps
Connect your mobile app stores and enable web billing:- iOS: Link your App Store Connect app.
- Android: Link your Google Play Console app.
- Web: Enable Web Billing in your RevenueCat project settings. This typically involves connecting to a payment gateway like Stripe.
3. Obtain API Keys
Retrieve your public API keys from RevenueCat:- In your RevenueCat project dashboard, navigate to Project Settings > API Keys.
- Copy the Public SDK keys for each platform: iOS, Android, and Web. The Web Public SDK key is separate from the mobile keys.
4. Configure Environment Variables
During theyarn setup process, you were prompted to enter these keys. If you skipped this or need to update them, you can manually add them to your apps/app/.env file:
5. Create Products and Entitlements
⚠️ Do this AFTER adding API keys to your.env file.
Define your in-app purchase products and entitlements in RevenueCat:
- Entitlements: Create an entitlement (e.g., “pro”) that represents access to your premium features.
- Products: Create your subscription products (e.g., “monthly_pro”, “annual_pro”) and link them to the corresponding entitlement.
- For iOS and Android, these products are configured in App Store Connect and Google Play Console, then linked in RevenueCat.
- For Web, products are created directly within RevenueCat’s Web Billing dashboard.
- Offerings: Add your products to an Offering (typically named “default”) so they can be fetched by the app.
Why the order matters: When you add API keys before creating products, RevenueCat will log expected errors about missing products. These errors are normal and will disappear once you create products in the dashboard. The app handles these gracefully and shows a helpful setup message instead of error stack traces.
Architecture Overview
Shipnative’s payment architecture is designed for cross-platform consistency.Platform Detection
The app automatically detects the platform and uses the appropriate RevenueCat SDK:- iOS/Android: Uses the native RevenueCat SDK.
- Web: Uses the RevenueCat Web SDK (Web Billing). When the web key is missing in development, it falls back to the mock RevenueCat client so you can still test the flow.
Unified Subscription Store
TheuseSubscriptionStore (found in apps/app/app/stores/subscriptionStore.ts) provides a consistent API for managing subscriptions across all platforms:
Usage Examples
Displaying a Paywall
Shipnative includes aPaywallScreen component that automatically handles platform detection and displays the appropriate UI for available packages.
- Provide
EXPO_PUBLIC_REVENUECAT_WEB_KEYand a Web Billing offering in RevenueCat to enable real checkout. - If the web key is absent in development, the paywall will render using mock offerings so you can validate the UX without payments.
- If no web offering exists in RevenueCat, the paywall will surface a “No web offering found” message.
Gating Features
Use theisPro status from useSubscriptionStore to gate access to premium features:
Custom Pricing UI
If you need a custom pricing display, you can fetch packages and handle purchases manually:Testing Your Integration
Mock Mode Testing
- Ensure RevenueCat API keys are not set in your
apps/app/.envfile. - Run your app (
yarn iosoryarn android). - Navigate to your paywall screen.
- Initiate a “purchase” – it will simulate success after a short delay.
- Verify that the app recognizes the “pro” status.
- Restart the app; the “pro” status should persist (in mock mode).
Testing with Real Services
- iOS:
- Add your
EXPO_PUBLIC_REVENUECAT_IOS_KEYtoapps/app/.env. - Configure a sandbox tester account in App Store Connect.
- Run
yarn iosand test purchases using the sandbox account.
- Add your
- Android:
- Add your
EXPO_PUBLIC_REVENUECAT_ANDROID_KEYtoapps/app/.env. - Configure a test account in Google Play Console.
- Run
yarn androidand test purchases using the test account.
- Add your
- Web:
- Add your
EXPO_PUBLIC_REVENUECAT_WEB_KEYtoapps/app/.env. - Create a Web Billing offering in the RevenueCat dashboard.
- Run your Expo web build (
yarn app:web) and complete checkout via RevenueCat Web Billing (Stripe test mode works if your connected gateway is in test).
- Add your
Webhooks (Advanced)
For production environments, setting up webhooks is crucial for real-time synchronization of subscription statuses.RevenueCat Webhooks
RevenueCat provides robust webhook support:- In your RevenueCat project dashboard, go to Project Settings > Integrations > Webhooks.
- Add your webhook URL.
- RevenueCat will automatically send events for mobile and web purchases, allowing your backend to update user subscription statuses in real-time.
Troubleshooting
RevenueCat errors about “no products registered” or “offerings”
Problem: You see errors in the console like:"Error fetching offerings - The operation couldn't be completed""There are no products registered in the RevenueCat dashboard""RevenueCat SDK Configuration is not valid"
- This is EXPECTED and NORMAL when you’ve added API keys but haven’t created products yet.
- These errors will automatically disappear once you:
- Create products in RevenueCat (see step 5 in setup)
- Add products to an Offering
- Restart your app
- The app handles these errors gracefully and shows a helpful setup message instead of error stack traces.
- You can safely ignore these errors if you’re not using subscriptions yet.
”Mock mode” warning in production
Problem: Your app shows a mock mode warning for RevenueCat even with API keys configured. Solution:- Verify that your
apps/app/.envfile exists and is correctly configured withEXPO_PUBLIC_REVENUECAT_IOS_KEY,EXPO_PUBLIC_REVENUECAT_ANDROID_KEY, andEXPO_PUBLIC_REVENUECAT_WEB_KEY. - Ensure your environment variables are prefixed with
EXPO_PUBLIC_. - Restart your Metro bundler with
yarn app:start --clearto ensure environment variables are reloaded.
Packages not loading
Problem: Your paywall shows no available packages. Solution:- Double-check that your RevenueCat API keys are correct.
- Verify that you have created and linked products and entitlements in RevenueCat.
- For web, ensure Web Billing is enabled and web products are created in RevenueCat.
- Check your console for any error messages from RevenueCat.
- Try calling
fetchPackages()manually in your code to debug.
Purchase not completing
Problem: A purchase flow starts but doesn’t complete successfully. Solution:- Check the browser console (for web) or device logs (for mobile) for errors.
- Verify that your payment gateway (e.g., Stripe for web) is correctly connected and configured in RevenueCat.
- Ensure the user is logged in before attempting a purchase.
Subscription status not persisting
Problem: A user’s subscription status resets after app restart or backgrounding. Solution:- Verify that the underlying storage mechanism (e.g., MMKV) is working correctly.
- Check for any errors during the initialization of the
useSubscriptionStore. - Ensure
restorePurchases()is called appropriately (e.g., on app launch).