Subscriptions
📱 Mobile Subscriptions
In app Subscriptions are the best way to get a recurring revenue from your app.
They are managed by the app store and the play store.
Apple and Google will handle all tax and payment methods for you.
In exchange, they will take a 30% cut on your revenue. (15% before getting 1M revenue but you have to apply for this program).
You cannot use Stripe or any other payment method to handle subscriptions in your app. Apple and Google could reject your app or even ban your account.
Integrating with RevenueCat for subscriptions and in-app purchases
We use RevenueCat to manage subscriptions.
This is a great solution to manage subscriptions in your app and handling permissions, trials, etc.
You must first create an account on RevenueCat.
Then create a new app and follow the instructions.
Why do we use a subscription manager?
Apple store and play store are great to manage subscriptions but they are not perfect.
- You don't have a regular webhook every time a subscription period has renewed.
- You can't access all stats from one page
- You can't manage trials, permissions, etc
Here is the RevenueCat documentation.
Their pricing model is based on your revenue. If you don't have any revenue, you don't have to pay anything.
How to setup it with our template?
You must have an account and an app created on RevenueCat. After that create the subscriptions on the Apple Store and Google Play Store.
You don't have to install anything. ApparenceKit is already configured to work with RevenueCat.
- Setup your stores like described in the documentation Do only the 1,2,3 steps as we have already done the 4th step for you.
- Get your API key in the settings > API keys Copy the Android API key and the iOS API key and paste them in your environment for the 'revenueCatAndroidApiKey', 'revenueCatIOSApiKey' fields or set the 'RC_ANDROID_API_KEY','RC_IOS_API_KEY' environment variables in your CI/CD. (See the setup your environment doc)
- Configure Apple app store notifications : this is how RevenueCat will know when a subscription has been renewed, etc.
- Configure Google Real-Time Developer Notifications: this is how RevenueCat will know when a subscription has been renewed, etc.
🤝 Congratulations.
You have now a working subscription system in your app.
Integrating webhooks
RevenueCat provides a webhook system to handle subscription events.
By default the template is configured to fetch the subscription state from your backend.
But you can also fetch it directly from RevenueCat.
You can change this behavior in the lib/modules/subscription/repositories/subscription_repository.dart
file.
The method get contains a call to the backend to fetch the subscription state.
Future<Subscription> get(String userId) async { ... }
But it also contains a call to RevenueCat to fetch the subscription state.
This code has been commented out, but you can use it if you want to fetch the subscription state directly from RevenueCat.
Using our backend for fetching the subscription state allows you to handle more complex use cases like a free lifetime subscription for a specific user, etc...
Configure the webhook
🔥 The webhook code is already available in the Firebase functions boilerplate
Follow this documentation to setup the webhook in the RevenueCat dashboard.
Testing subscriptions
Apparencekit - Subscription module
We provides a subscription module to handle subscriptions in your app. This module includes
- A subscription page to subscribe to an offer
- An active subscription page to manage your subscription
- A recover button to restore your subscription from another device
- A Subscription state to handle subscription state in your app (see UserStateNotifier in lib/core/states/user_state.dart)
This module will check if the user has an active subscription and will show the right page.
If you want to customize those pages
lib/modules/subscriptions/ui/component/active_premium_content.dart
for the active subscription pagelib/modules/subscriptions/ui/component/premium_content.dart
for the subscription page
Check the user subscription state
To listen to subscription state changes you can use the UserStateNotifier wherever you want in your app.
// ref comes from riverpod package
// if you don't understand how to use riverpod, check the documentation here: https://riverpod.dev/
final userState = ref.watch<UserStateNotifier>();
_userState.subscription.map(
active: (state) => print('active'),
inactive: (state) => print('inactive'),
loading: () => print('loading'),
);
Customize the subscription state
- You will find the user state in the lib/core/states/user_state.dart file.
- The user_state_notifier.dart file is used to handle user state changes.
- The user subscription is in the User class in the lib/core/models/user.dart file.
- The user_repository will fetch the user subscription state from the backend with the user informations.
The user_state_notifier will be initiated at the start of the app and will listen to subscription state changes. Check this file to customize the subscription state with your own logic.
Solution 2 - Handling subscriptions in your backend
You must first install the in app purchase plugin. This plugin supports in-app purchases (IAP) through an underlying store, which can be the App Store (on iOS and macOS) or Google Play (on Android). (You can uninstall RevenueCat plugin from pubspec.yaml).
As I really don't encourage you to use this solution, I will not explain how to use it. Apple and Google API are really different and have many use cases. Those Subscriptions solutions like RevenueCat are here to help you to handle all those use cases.