| name | monetization |
| description | Set up in-app purchases, subscriptions, and payment processing for Flutter apps using RevenueCat or Lemon Squeezy. Use this skill when the user asks about monetization, subscriptions, in-app purchases, paywalls, entitlements, offerings, RevenueCat setup, Lemon Squeezy integration, pricing models, or payment processing for mobile apps. Also triggers on: 'add subscriptions', 'paywall', 'premium features', 'free trial', 'freemium model', or 'how to charge users'. |
Monetization: Subscriptions & In-App Purchases
This skill covers payment integration for Flutter apps, from choosing a provider to implementing paywalls and managing entitlements.
Provider Decision
| Feature | RevenueCat | Lemon Squeezy |
|---|
| Best for | Mobile-first subscriptions | Web + mobile hybrid products |
| Platforms | iOS, Android, Amazon, Web | Web-first, mobile via webhooks |
| Flutter SDK | Official (purchases_flutter) | No Flutter SDK (REST API + webhooks) |
| Paywall UI | Built-in (purchases_ui_flutter) | Build your own |
| Store compliance | Handles StoreKit + Play Billing | You handle store integration |
| Pricing | Free tier (up to $2.5k MTR), then 1-2.5% | 5% + 50c per transaction |
| Merchant of record | No (you handle taxes) | Yes (they handle taxes globally) |
| Ideal use case | App Store/Play Store subscriptions | Digital products, SaaS, one-time purchases |
Quick decision:
- Selling subscriptions through App Store / Play Store → RevenueCat
- Selling digital products, licenses, or SaaS outside stores → Lemon Squeezy
- Both → RevenueCat for mobile + Lemon Squeezy for web/backend
RevenueCat Setup
Read references/revenuecat.md for complete implementation guide.
Architecture Overview
Flutter App
└─ purchases_flutter SDK
└─ RevenueCat Backend
├─ Apple StoreKit (iOS subscriptions)
├─ Google Play Billing (Android subscriptions)
└─ Amazon Appstore (optional)
RevenueCat acts as a single source of truth for subscription state across platforms. It handles:
- Receipt validation
- Subscription status tracking
- Cross-platform purchase syncing
- Webhook delivery to your backend
- Analytics and churn metrics
Quick Start
- Create RevenueCat account at app.revenuecat.com
- Create project, add app (iOS + Android)
- Configure store credentials:
- iOS: App Store Connect Shared Secret + In-App Purchase Key
- Android: Google Play service account JSON
- Create Products in each store (App Store Connect + Google Play Console)
- Create Entitlements in RevenueCat (e.g., "premium")
- Create Offerings with Packages (monthly, annual, lifetime)
- Integrate SDK in Flutter app
Essential Code
Initialize SDK (call once at app start):
import 'package:purchases_flutter/purchases_flutter.dart';
Future<void> initRevenueCat() async {
await Purchases.setLogLevel(LogLevel.debug); // Remove in production
final config = PurchasesConfiguration('your_revenuecat_api_key')
..appUserID = null; // Anonymous until user logs in
await Purchases.configure(config);
}
Check subscription status:
Future<bool> isPremium() async {
final customerInfo = await Purchases.getCustomerInfo();
return customerInfo.entitlements.active.containsKey('premium');
}
Show paywall (using RevenueCat UI):
import 'package:purchases_ui_flutter/purchases_ui_flutter.dart';
Future<void> showPaywall() async {
final result = await RevenueCatUI.presentPaywall(
displayCloseButton: true,
);
if (result == PaywallResult.purchased) {
// Grant access
}
}
Purchase a package:
Future<void> purchase(Package package) async {
try {
final result = await Purchases.purchase(
PurchaseParams.package(package),
);
if (result.customerInfo.entitlements.active.containsKey('premium')) {
// Success
}
} on PlatformException catch (e) {
final code = PurchasesErrorHelper.getErrorCode(e);
if (code == PurchasesErrorCode.purchaseCancelledError) {
// User cancelled, don't show error
}
}
}
Lemon Squeezy Integration
Read references/lemonsqueezy.md for API details.
Architecture Overview
Flutter App
└─ WebView or deep link to checkout
└─ Lemon Squeezy (handles payment + taxes)
└─ Webhook to your backend
└─ Backend updates user entitlements
└─ Flutter app checks entitlements
Lemon Squeezy is a merchant of record — they handle global tax compliance, invoicing, and payment processing. You receive payouts minus their fee.
When to Use Lemon Squeezy Over RevenueCat
- Selling access to APIs, web dashboards, or digital content
- Need global tax compliance without handling it yourself
- Want a checkout experience outside of App Store/Play Store
- Selling one-time purchases (not just subscriptions)
- Apple/Google's 30% commission is too high for your margins
Integration Pattern
Since there's no Flutter SDK, integrate via:
- Checkout URL — open in WebView or external browser
- Webhooks — receive payment events on your backend
- License validation — verify purchase in your app via API
// Open Lemon Squeezy checkout
import 'package:url_launcher/url_launcher.dart';
Future<void> openCheckout(String productId) async {
final url = 'https://your-store.lemonsqueezy.com/checkout/buy/$productId'
'?checkout[custom][user_id]=user_123';
await launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication);
}
Pricing Strategy
Common Mobile Pricing Models
| Model | Example | Revenue pattern |
|---|
| Freemium | Free core + premium features | Recurring (subscriptions) |
| Free trial | 7-day trial → paid | High conversion if value is clear |
| One-time purchase | Unlock all features | Spiky, no recurring |
| Consumable | Credits, tokens | Variable, engagement-dependent |
| Tiered | Basic / Pro / Enterprise | Segmented by usage |
Pricing Best Practices for Stores
- Offer annual plans — higher LTV, lower churn. Typical discount: 15-30% vs monthly
- Free trial > freemium for subscription apps (Apple and Google both support trial periods natively)
- Price anchoring — show annual price first, monthly price looks expensive by comparison
- Localized pricing — adjust prices by market purchasing power
- Introductory offers — Apple and Google support discounted first periods
Store Commission
| Store | Commission | Reduced rate |
|---|
| Apple App Store | 30% | 15% (< $1M/year revenue via Small Business Program) |
| Google Play Store | 30% | 15% (first $1M/year) |
| Amazon Appstore | 30% | 20% (some categories) |
Entitlement Architecture
Design entitlements to be platform-agnostic and forward-compatible:
// Good: abstract entitlement
enum AppEntitlement { premium, proPlan, teamPlan }
// Bad: tied to specific product
enum AppEntitlement { monthlySubscription, annualSubscription }
A user with "premium" entitlement might have:
- Monthly subscription via Google Play
- Annual subscription via App Store
- Lifetime purchase via promotion
- Free access via team plan
RevenueCat maps all of these to the same entitlement. Your app only checks entitlements.active.containsKey('premium').