flutter_iap_plus 1.0.0
flutter_iap_plus: ^1.0.0 copied to clipboard
Flutter package for in-app purchase with 5 ready-made subscription UI templates. Handles product loading, purchase, restore, and premium state out of the box for iOS and Android.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter_iap_plus/flutter_iap_plus.dart';
import 'package:flutter_svg/svg.dart';
import 'gen/assets.gen.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
// Single-product setup. For multiple products use:
// productIds: {'com.app.weekly', 'com.app.monthly', 'com.app.yearly'},
await PurchasesManager.instance.init(productId: 'com.app.weekly');
// Optional: subscribe to a unified event stream instead of using the
// legacy onPurchaseX callbacks.
PurchasesManager.instance.purchaseEvents.listen((event) {
debugPrint('Purchase event: $event');
});
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'flutter_iap_plus example',
home: const _HomePage(),
builder: (context, child) {
// Configure the purchase screen UI here so it has access to the
// app's BuildContext (for l10n, theme, etc.).
_configIap(context);
return LoadingWidget(child: child!);
},
);
}
void _configIap(BuildContext context) {
PurchasesManager.instance.config(
templateData: TemplateDataModel(
iconPath: Assets.images.logo.path,
title: 'Unlock <highlight>Premium</highlight>',
subtitle: 'Enjoy every feature, ad-free',
features: [
FeatureDataModel(
text: 'Ultra-fast connection',
icon: SvgPicture.asset(Assets.images.flash),
),
FeatureDataModel(
text: 'Enjoy an ad-free experience',
icon: SvgPicture.asset(Assets.images.removeAds),
),
],
buttonText: 'Start 3-Day Free Trial',
termOfUseText: 'Terms of Use',
privacyPolicyText: 'Privacy Policy',
restorePurchaseText: 'Restore Purchases',
termsOfUseUrl: 'https://example.com/terms',
privacyPolicyUrl: 'https://example.com/privacy',
enableMarqueeText: true,
gradient: const LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Color(0xFFBAF36C), Color(0xFF74AA47)],
),
errorData: ErrorDataModel(
itemAlreadyOwnedText: 'You already own this item.',
unknownErrorText: 'Something went wrong, please try again.',
buttonText: 'OK',
),
additionCloseButtonConfig: CloseButtonConfig(
alignment: Alignment.topRight,
closeButtonWidget: GestureDetector(
onTap: PurchasesManager.instance.closePurchaseScreen,
child: const Padding(
padding: EdgeInsets.all(12),
child: Text(
'Continue with ads',
style: TextStyle(color: Colors.white70),
),
),
),
),
),
);
}
}
class _HomePage extends StatelessWidget {
const _HomePage();
@override
Widget build(BuildContext context) {
return IAPBuilder(
builder: (context, state, isPremium) {
return Scaffold(
appBar: AppBar(
title: const Text('flutter_iap_plus example'),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
isPremium ? 'Premium User' : 'Free User',
style: Theme.of(context).textTheme.headlineMedium,
),
const SizedBox(height: 24),
if (isPremium)
FilledButton.icon(
onPressed: PurchasesManager.instance.manageSubscription,
icon: const Icon(Icons.workspace_premium),
label: const Text('Manage Subscription'),
)
else
...List.generate(5, (index) {
final tpl = index + 1;
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: FilledButton(
onPressed: () =>
PurchasesManager.instance.openPurchaseScreen(
context: context,
templateIndex: tpl,
),
child: Text('Open Template $tpl'),
),
);
}),
],
),
),
);
},
);
}
}