I shipped my first Flutter app with exactly zero monetization strategy. It got 15,000 downloads in its first month and I earned... nothing. Not a single rupee. Turns out, building a great app and making money from it are two completely separate skills. I've spent the last three years figuring out the second part, and this guide covers everything I've learned — including the expensive mistakes.
There's no single "right" way to monetize a Flutter app. Ads work brilliantly for utility apps with high session counts. Subscriptions dominate for content and productivity apps. In-app purchases shine for games and creative tools. Most successful apps in 2026 use some combination of all three. The key is matching your monetization strategy to your app's usage patterns and your users' willingness to pay.
The Flutter Monetization Landscape in 2026
Flutter's monetization ecosystem has matured significantly. You're no longer fighting with janky native
interop just to show a banner ad. The official google_mobile_ads package handles AdMob
integration cleanly. The in_app_purchase package (maintained by the Flutter team) wraps both
StoreKit 2 and Google Play Billing Library. And RevenueCat's purchases_flutter SDK makes
subscription management almost embarrassingly simple.
Here's what the revenue landscape actually looks like based on published benchmarks:
- Ad-supported apps earn $1-5 per 1,000 daily active users (varies wildly by geography and ad format)
- Subscription apps convert 2-5% of free users to paid, with median monthly ARPU of $7-12 for successful apps
- In-app purchase apps see 1-3% purchase rates, but whales (top 1% of spenders) often drive 30-50% of total revenue
- Hybrid models (ads + subscriptions) typically outperform single-strategy approaches by 40-60%
The bottom line? Don't lock yourself into one approach. Build your architecture to support multiple revenue streams from day one — it's way harder to bolt on subscriptions after your app's been live for six months.
Google AdMob: Banner, Interstitial, and Rewarded Ads
AdMob remains the go-to ad network for Flutter apps. The google_mobile_ads package gives you
access to four ad formats, and each serves a different purpose in your revenue strategy.
Setting Up google_mobile_ads
Add the dependency to your pubspec.yaml:
dependencies:
google_mobile_ads: ^5.3.0
Initialize the SDK in your main.dart before runApp():
import 'package:google_mobile_ads/google_mobile_ads.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await MobileAds.instance.initialize();
runApp(const MyApp());
}
Banner Ads — The Reliable Baseline
Banner ads won't make you rich, but they provide a steady baseline income. Place them at the bottom of content screens — never on your app's primary interaction screens. A banner ad that interrupts a user's core workflow does more damage to retention than the $0.002 it earns is worth.
class BannerAdWidget extends StatefulWidget {
const BannerAdWidget({super.key});
@override
State<BannerAdWidget> createState() => _BannerAdWidgetState();
}
class _BannerAdWidgetState extends State<BannerAdWidget> {
BannerAd? _bannerAd;
bool _isLoaded = false;
@override
void initState() {
super.initState();
_bannerAd = BannerAd(
adUnitId: 'ca-app-pub-xxxxx/xxxxx', // Replace with your ad unit ID
size: AdSize.banner,
request: const AdRequest(),
listener: BannerAdListener(
onAdLoaded: (ad) => setState(() => _isLoaded = true),
onAdFailedToLoad: (ad, error) {
ad.dispose();
debugPrint('Banner failed: ${error.message}');
},
),
)..load();
}
@override
void dispose() {
_bannerAd?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
if (!_isLoaded || _bannerAd == null) return const SizedBox.shrink();
return SizedBox(
width: _bannerAd!.size.width.toDouble(),
height: _bannerAd!.size.height.toDouble(),
child: AdWidget(ad: _bannerAd!),
);
}
}
Interstitial Ads — Use Sparingly
Interstitial ads (full-screen) pay 3-5x more than banners, but overusing them is the fastest way to tank your app's rating. Show them at natural transition points: after completing a level, when navigating between major sections, or after finishing a task. Never show more than one interstitial every 3-5 minutes. I've seen apps lose 40% of their daily active users within a week of aggressive interstitial placement.
Rewarded Ads — The User-Friendly Revenue Machine
Rewarded video ads are the sweet spot. Users choose to watch a 15-30 second video in exchange for something valuable: extra lives in a game, premium content unlock for 24 hours, ad-free mode for an hour, or bonus credits. Completion rates for rewarded ads average 80-90% because users opt in voluntarily. And they pay the best — $10-30 eCPM in Tier 1 countries.
Future<void> showRewardedAd({
required VoidCallback onRewarded,
}) async {
await RewardedAd.load(
adUnitId: 'ca-app-pub-xxxxx/xxxxx',
request: const AdRequest(),
rewardedAdLoadCallback: RewardedAdLoadCallback(
onAdLoaded: (ad) {
ad.fullScreenContentCallback = FullScreenContentCallback(
onAdDismissedFullScreenContent: (ad) => ad.dispose(),
);
ad.show(
onUserEarnedReward: (ad, reward) => onRewarded(),
);
},
onAdFailedToLoad: (error) {
debugPrint('Rewarded ad failed: ${error.message}');
},
),
);
}
💡 Pro Tip: Pre-load Your Ads
Don't load interstitial or rewarded ads when the user triggers them — there's a 1-3 second delay that feels terrible. Pre-load them during idle moments (after a screen renders, during data fetches) so they're ready instantly when you need them. Keep a simple ad manager service that maintains one pre-loaded interstitial and one rewarded ad at all times.
In-App Purchases: One-Time and Consumable Products
In-app purchases (IAP) let users buy things directly inside your app. There are three types that matter:
- Consumables: Virtual currency, credits, extra lives — things users can buy repeatedly. Popular in games and creative apps.
- Non-consumables: One-time unlocks like "remove ads forever," premium themes, or a specific feature pack. Users buy once, own forever.
- Subscriptions: Recurring payments for ongoing access. We'll cover these in the next section since they deserve their own deep-dive.
The official in_app_purchase package handles both iOS and Android from a single Dart API:
dependencies:
in_app_purchase: ^3.2.0
Setting Up Product Listings
Before writing any code, configure your products in both stores:
- Google Play Console: Go to Monetize → Products → In-app products. Create each product
with a product ID (e.g.,
remove_ads,premium_pack), price, and description. - App Store Connect: Go to your app → In-App Purchases → Create. Use the same product IDs across both platforms — it simplifies your Flutter code significantly.
Querying Available Products
import 'package:in_app_purchase/in_app_purchase.dart';
class PurchaseService {
final InAppPurchase _iap = InAppPurchase.instance;
static const Set<String> _productIds = {
'remove_ads',
'premium_pack',
'coin_bundle_500',
};
Future<List<ProductDetails>> fetchProducts() async {
final available = await _iap.isAvailable();
if (!available) return [];
final response = await _iap.queryProductDetails(_productIds);
if (response.error != null) {
debugPrint('Query error: ${response.error!.message}');
}
return response.productDetails;
}
Future<void> buyProduct(ProductDetails product) async {
final purchaseParam = PurchaseParam(productDetails: product);
// Use buyConsumable for consumables, buyNonConsumable for one-time
await _iap.buyNonConsumable(purchaseParam: purchaseParam);
}
}
🔐 Critical: Server-Side Receipt Validation
Never trust the client. After a purchase completes, send the receipt token to your backend server and validate it against Apple's App Store Server API or Google's Play Developer API before granting the entitlement. Client-side-only validation is trivially bypassable. If you're using Firebase, Cloud Functions work great for this. RevenueCat handles validation automatically if you're using their SDK.
Subscription Models with RevenueCat
Subscriptions are where the real money is. A user who pays $4.99/month is worth $60/year — that's the equivalent of 20,000-60,000 banner ad impressions from a single user. But subscription management is genuinely complex: renewals, cancellations, grace periods, billing retries, family sharing, promotional offers, cross-platform entitlements... implementing all of this correctly against both store APIs is a multi-month project.
That's why RevenueCat exists. Their purchases_flutter SDK wraps both stores into a single API,
handles receipt validation server-side, and provides a dashboard for analytics. It's free up to $2,500/month
in tracked revenue.
RevenueCat Setup
dependencies:
purchases_flutter: ^8.1.0
import 'package:purchases_flutter/purchases_flutter.dart';
Future<void> initRevenueCat() async {
await Purchases.configure(
PurchasesConfiguration('your_revenuecat_api_key'),
);
}
Future<bool> checkPremiumStatus() async {
final customerInfo = await Purchases.getCustomerInfo();
return customerInfo.entitlements.all['premium']?.isActive ?? false;
}
Future<void> purchaseSubscription() async {
final offerings = await Purchases.getOfferings();
final package = offerings.current?.monthly;
if (package != null) {
await Purchases.purchasePackage(package);
}
}
Future<void> restorePurchases() async {
await Purchases.restorePurchases();
}
That's the entire subscription flow. RevenueCat handles renewal tracking, receipt validation, and
cross-platform sync behind the scenes. You check customerInfo.entitlements to gate features —
if the premium entitlement is active, the user has an active subscription.
Choosing Your Subscription Tiers
Most successful apps use a two-or three-tier model:
- Free tier: Core functionality with ads. Users get value, you get ad revenue. This is your funnel.
- Pro tier ($3-6/month): Ad-free, plus 2-3 premium features. Typically your highest-converting tier.
- Premium tier ($8-15/month): Everything in Pro, plus power-user features like cloud sync, advanced analytics, or priority support. Lower conversion, higher ARPU.
Offer both monthly and annual plans. Annual plans should offer a 30-40% discount over monthly pricing — it improves lifetime value because annual subscribers churn at roughly half the rate of monthly ones.
The Hybrid Strategy: Ads + Subscriptions Together
The most effective monetization model I've seen in Flutter apps combines ads with subscriptions. Here's how it works in practice:
- Free users see banner ads on secondary screens and interstitial ads at natural transitions
- Free users can watch rewarded ads to unlock premium features temporarily (24-hour access)
- Subscribers skip all ads and get permanent premium access
- The rewarded ad becomes your best conversion tool — users experience premium mode, realize it's worth paying for, and subscribe
Implementing this in Flutter means wrapping your ad widgets and feature gates in a single service:
class MonetizationService {
final RevenueCatService _rc;
final AdService _ads;
bool get isPremium => _rc.isPremiumActive;
Widget buildAdWidget() {
if (isPremium) return const SizedBox.shrink();
return const BannerAdWidget();
}
Future<bool> gateFeature(String feature) async {
if (isPremium) return true;
// Offer rewarded ad as temporary unlock
final watched = await _ads.showRewardedAd();
if (watched) {
await _grantTemporaryAccess(feature, duration: 24.hours);
return true;
}
// Show paywall
return _showPaywall();
}
}
This pattern converts well because users self-select. People who can't afford a subscription still generate ad revenue. People who hate ads pay to remove them. And the rewarded ad bridge gives users a taste of premium before asking for their credit card.
Designing Paywalls That Convert Without Being Annoying
A paywall is the screen where free users see what they're missing and decide whether to subscribe. Bad paywalls feel like a hostage negotiation. Good ones feel like a genuine offer.
Rules I've learned from shipping paywalls across six apps:
- Show the paywall after the user gets value, not before. If someone opens your app for the first time and immediately hits a paywall, they'll uninstall — they haven't experienced enough to know what they'd be paying for.
- Lead with benefits, not features. "Save 2 hours every week" beats "Unlimited exports" every time.
- Always include a "Restore Purchases" button. Apple will reject your app without one. And it builds trust — users know you're not trying to double-charge them.
- Show social proof. "Join 12,000+ professionals" or "Rated 4.8 stars" makes the decision easier.
- Offer a free trial. 7-day trials convert 2-3x better than hard paywalls. Users who trial and cancel are still more likely to subscribe later than users who never tried at all.
- Test aggressively. Your first paywall design will almost certainly not be your best. RevenueCat's paywall SDK lets you A/B test different designs without app updates.
Analytics, A/B Testing, and Revenue Optimization
You can't optimize what you don't measure. Set up these analytics events from day one:
// Key monetization events to track
analytics.logEvent('paywall_shown', {
'trigger': 'feature_gate',
'feature': 'advanced_export',
});
analytics.logEvent('purchase_started', {
'product_id': 'premium_monthly',
'price': product.price,
});
analytics.logEvent('purchase_completed', {
'product_id': 'premium_monthly',
'revenue': product.rawPrice,
'currency': product.currencyCode,
});
analytics.logEvent('ad_rewarded_watched', {
'feature_unlocked': 'premium_24h',
'placement': 'feature_gate',
});
Key metrics to monitor weekly:
- Trial-to-paid conversion rate: Industry average is 15-25%. Below 10% means your trial experience isn't demonstrating enough value.
- Monthly churn rate: Aim for under 8% for monthly subscribers, under 3% for annual. High churn means users aren't getting ongoing value.
- ARPDAU (Average Revenue Per Daily Active User): Combines ad revenue + subscription revenue. Track this as your single north-star metric.
- Paywall conversion rate: What percentage of users who see the paywall start a trial or purchase? Industry average is 5-8%.
📊 A/B Test Everything
RevenueCat's Experiments feature lets you test different pricing, trial lengths, and paywall layouts without shipping a new app version. Start by testing annual vs. monthly pricing emphasis — most apps see a 15-25% revenue increase just by making the annual plan more prominent. Then test pricing: a $1/month increase on a 5% conversion base adds up fast at scale.
Common Monetization Mistakes to Avoid
I've made most of these. Learn from my pain:
- Monetizing too late. "I'll add monetization after I get users" is how you end up with 50,000 free users who revolt when you introduce a paywall. Build it in from version 1.0.
- Relying solely on ads. Ads alone won't sustain anything except the highest-traffic apps. A utility app with 5,000 DAU and only banner ads might earn $5-15/month. That's not a business — it's a rounding error.
- Aggressive interstitials on first session. New users who get hit with a full-screen ad within 30 seconds of opening your app will uninstall immediately. Show zero ads in the first session. Zero.
- Not testing your purchase flow on real devices. Sandbox testing doesn't catch everything. Google Play's billing library and Apple's StoreKit have subtle behavioral differences that only surface on production builds with real payment methods.
- Forgetting to handle pending purchases. Users can start a purchase and then lose connection, switch apps, or have their payment declined and retried later. Listen to the purchase stream on every app launch and fulfill any pending transactions.
- Hardcoding prices. Prices vary by country, currency, and store. Always use the price
string returned by
ProductDetails.pricefrom the store's API, never a hardcoded "$4.99". - Ignoring Android's billing integration requirements. Google Play's policy requires that digital goods are purchased through Google Play Billing Library — not through Stripe, PayPal, or any external payment system. Violations get your app removed.
📚 Related Guides
🔗 Official Resources
Frequently Asked Questions
What's the best monetization strategy for a new Flutter app?
Start with a freemium model: offer core features free, then gate premium features behind a subscription or one-time purchase. Ads work as a secondary revenue stream for free-tier users, but avoid making ads the only plan. Apps with subscriptions generate 4-5x more revenue per user than ad-only apps, according to RevenueCat's 2025 benchmarks. Test your pricing early — most developers wait too long and lose months of potential revenue.
How much can I earn from AdMob ads in a Flutter app?
AdMob earnings depend heavily on your audience geography and ad format. Banner ads in Tier 1 countries (US, UK, Canada) earn $1-3 eCPM. Interstitial ads range from $4-12 eCPM. Rewarded video ads pay the most at $10-30 eCPM. For South Asian audiences, expect roughly 20-40% of those rates. A utility app with 10,000 daily active users showing 3 interstitials per session might earn $200-600/month in a mixed-geography audience.
Should I use RevenueCat or implement in-app purchases directly?
If your app has subscriptions, use RevenueCat. Period. Managing subscription lifecycle (renewals, cancellations, grace periods, billing retries, cross-platform receipt validation) directly through StoreKit 2 and Google Play Billing Library is genuinely painful and error-prone. RevenueCat abstracts all of that into a single SDK, provides analytics dashboards, and handles receipt validation server-side. It's free up to $2,500/month in tracked revenue, which covers most indie apps comfortably.
What's the Apple and Google commission on in-app purchases?
Both Apple and Google charge a 30% commission on in-app purchases and subscriptions for the first year. After a subscriber stays for 12 consecutive months, the rate drops to 15%. Small developers earning under $1M annually qualify for reduced rates: Apple's Small Business Program and Google's reduced service fee both cut the commission to 15% from day one. Always factor these commissions into your pricing — if you charge $9.99/month, you'll net roughly $7 after the store cut.
Can I use both ads and subscriptions in the same Flutter app?
Absolutely — it's actually one of the most effective monetization strategies. Show ads to free users and remove them for subscribers. This gives you two revenue streams: ad revenue from the ~95% of users who never pay, and subscription revenue from the ~5% who do. Spotify, YouTube, and Duolingo all use this hybrid model. In Flutter, conditionally show ad widgets based on a subscription status check through RevenueCat or your own entitlement system.
How do I handle different pricing across iOS and Android?
You don't set prices directly — you configure price tiers in App Store Connect and Google Play
Console separately. Both stores handle currency conversion for international markets. In your
Flutter code, always fetch the localized price from the store at runtime using the
in_app_purchase package's ProductDetails.price field. Never hardcode
prices. This ensures users see the correct price in their local currency, and you stay compliant
with store policies.
What Flutter packages do I need for monetization?
For ads: google_mobile_ads (the official AdMob package). For in-app purchases:
in_app_purchase (official Flutter team package) or purchases_flutter
(RevenueCat's SDK, recommended for subscriptions). For paywalls and A/B testing: RevenueCat's
Paywalls SDK works with Flutter out of the box. For analytics: firebase_analytics to
track conversion funnels. That's the core stack — avoid adding packages for things you can build
with these four.