### Android Setup Guide Link Source: https://flutter-inapp-purchase.hyo.dev/docs/6.3/getting-started/android-setup Provides a link to the official Android Setup Guide for Flutter In-App Purchase. This guide covers essential steps like Google Play Console configuration, app bundle setup, signing, testing, and troubleshooting. ```Markdown 👉 **Android Setup Guide - openiap.dev** ``` -------------------------------- ### Get Started with flutter_inapp_purchase Source: https://flutter-inapp-purchase.hyo.dev/docs/guides/faq Provides a basic implementation guide for flutter_inapp_purchase, covering package import, connection initialization, listener setup for purchase updates and errors, loading products, and requesting a purchase. ```Dart // 1. Import the package import'package:flutter_inapp_purchase/flutter_inapp_purchase.dart'; import'package:flutter_inapp_purchase/types.dart'as iap_types; // 2. Initialize connection awaitFlutterInappPurchase.instance.initConnection(); // 3. Set up listeners with null checks FlutterInappPurchase.purchaseUpdated.listen((purchase){ if(purchase !=null){ // Handle successful purchase _handlePurchaseSuccess(purchase); } }); FlutterInappPurchase.purchaseError.listen((error){ if(error !=null){ // Handle purchase error _handlePurchaseError(error); } }); // 4. Load products final products =awaitFlutterInappPurchase.instance.getProducts([ 'product_id_1', 'product_id_2', ]); // 5. Request purchase awaitFlutterInappPurchase.instance.requestPurchase( request:RequestPurchase( ios:RequestPurchaseIOS(sku:'product_id', quantity:1), android:RequestPurchaseAndroid(skus:['product_id']), ), type:PurchaseType.inapp, ); ``` -------------------------------- ### iOS Setup Guide Reference Source: https://flutter-inapp-purchase.hyo.dev/docs/6.3/getting-started/ios-setup This section references an external guide for detailed iOS setup instructions for Flutter In-App Purchase. It outlines the key areas covered in the guide, such as App Store Connect configuration, Xcode project setup, sandbox testing, and troubleshooting. ```Markdown For complete iOS setup instructions including App Store Connect configuration, Xcode setup, and testing guidelines, please visit: 👉 **iOS Setup Guide - openiap.dev** The guide covers: * App Store Connect configuration * Xcode project setup * Sandbox testing * Common troubleshooting steps ``` -------------------------------- ### Android Setup Guide Link Source: https://flutter-inapp-purchase.hyo.dev/docs/getting-started/android-setup Provides a link to the external Android Setup Guide for detailed instructions on configuring Google Play Console, app setup, signing, and testing for in-app purchases. ```markdown 👉 **Android Setup Guide - openiap.dev** ``` -------------------------------- ### iOS Setup Guide Link Source: https://flutter-inapp-purchase.hyo.dev/docs/getting-started/ios-setup Provides a link to the official external guide for detailed iOS setup instructions for Flutter in-app purchases. This includes App Store Connect configuration, Xcode project setup, and sandbox testing. ```Markdown 👉 **iOS Setup Guide - openiap.dev** ``` -------------------------------- ### Flutter In-App Purchase UI Example Source: https://flutter-inapp-purchase.hyo.dev/docs/getting-started/quickstart A Flutter widget demonstrating the UI for displaying products, subscriptions, and active purchases. It includes buttons to initiate purchases and displays purchase status. ```dart // TODO: Deliver the product to user print('Delivering product: ${item.productId}'); } // UI Helper methods void_showError(String message){ ScaffoldMessenger.of(context).showSnackBar( SnackBar(content:Text(message), backgroundColor:Colors.red), ); } void_showSuccess(String message){ ScaffoldMessenger.of(context).showSnackBar( SnackBar(content:Text(message), backgroundColor:Colors.green), ); } @override Widgetbuild(BuildContext context){ returnScaffold( appBar:AppBar( title:Text('In-App Purchase Example'), actions:[ IconButton( icon:Icon(Icons.restore), onPressed: _restorePurchases, tooltip:'Restore Purchases', ), ], ), body:SingleChildScrollView( padding:EdgeInsets.all(16), child:Column( crossAxisAlignment:CrossAxisAlignment.start, children:[ // Products Section Text('Products', style:Theme.of(context).textTheme.headline6), SizedBox(height:8), ..._products.map((product)=>Card( child:ListTile( title:Text(product.title ?? product.productId ??''), subtitle:Text(product.description ??''), trailing:TextButton( child:Text(product.localizedPrice ??''), onPressed:()=>_requestPurchase(product.productId!), ), ), )), SizedBox(height:24), // Subscriptions Section Text('Subscriptions', style:Theme.of(context).textTheme.headline6), SizedBox(height:8), ..._subscriptions.map((subscription)=>Card( child:ListTile( title:Text(subscription.title ?? subscription.productId ??''), subtitle:Text(subscription.description ??''), trailing:TextButton( child:Text(subscription.localizedPrice ??''), onPressed:()=>_requestSubscription(subscription.productId!), ), leading:_isPurchased(subscription.productId!) ?Icon(Icons.check_circle, color:Colors.green) :null, ), )), SizedBox(height:24), // Active Purchases Section Text('Active Purchases', style:Theme.of(context).textTheme.headline6), SizedBox(height:8), if(_purchases.isEmpty) Text('No active purchases'), ..._purchases.map((purchase)=>Card( child:ListTile( title:Text(purchase.productId ??'Unknown'), subtitle:Text('Purchased: ${DateTime.fromMillisecondsSinceEpoch( purchase.transactionDate ??0 )}'), ), )), ], ), ), ); } bool _isPurchased(String productId){ return _purchases.any((purchase)=> purchase.productId == productId); } } ``` -------------------------------- ### Get Packages after pubspec.yaml Update Source: https://flutter-inapp-purchase.hyo.dev/docs/getting-started/installation Fetches the project's dependencies, including the newly added flutter_inapp_purchase, after updating `pubspec.yaml`. ```bash flutter pub get ``` -------------------------------- ### Add flutter_inapp_purchase via Flutter CLI Source: https://flutter-inapp-purchase.hyo.dev/docs/getting-started/installation Installs the flutter_inapp_purchase plugin into your Flutter project using the Flutter command-line interface. ```bash flutter pub add flutter_inapp_purchase ``` -------------------------------- ### Load Products and Subscriptions Source: https://flutter-inapp-purchase.hyo.dev/docs/getting-started/quickstart Fetches product details and pricing information from the store using their respective IDs. Supports both in-app purchases and subscriptions. ```dart // Regular products List products =await FlutterInappPurchase.instance .requestProducts(productIds:['product_id_1','product_id_2'], type:PurchaseType.inapp); // Subscriptions List subscriptions =await FlutterInappPurchase.instance .requestProducts(productIds:['subscription_id_1','subscription_id_2'], type:PurchaseType.subs); ``` -------------------------------- ### Initialize IAP Connection - Singleton Instance Source: https://flutter-inapp-purchase.hyo.dev/docs/getting-started/installation Shows how to initialize the `flutter_inapp_purchase` connection using the plugin's singleton instance, providing a simpler way to access the IAP functionality. ```dart class _MyAppState extends State { final iap = FlutterInappPurchase.instance; Future _initializeIAP() async { await iap.initConnection(); } } ``` -------------------------------- ### Update Initialization (Step 3) Source: https://flutter-inapp-purchase.hyo.dev/docs/6.3/migration/from-v5 Compares the initialization code for the In-App Purchase connection. The 'Before' example uses PlatformException for error handling, while the 'After' example uses a general catch block. ```dart FutureinitPlatformState()async{ try{ awaitFlutterInappPurchase.instance.initConnection(); print('IAP connection initialized'); }catch(e){ print('Failed to initialize IAP: $e'); } } ``` ```dart FutureinitPlatformState()async{ try{ awaitFlutterInappPurchase.instance.initConnection(); print('IAP connection initialized'); }onPlatformExceptioncatch(e){ print('Failed to initialize connection: $e'); } } ``` -------------------------------- ### Troubleshoot Package Installation Source: https://flutter-inapp-purchase.hyo.dev/docs/troubleshooting Commands to resolve dependency conflicts and issues during package installation using Flutter. This includes clearing the pub cache, cleaning the project, and upgrading dependencies. ```bash flutter pub cache repair flutter clean flutter pub get flutter pub deps flutter pub upgrade ``` -------------------------------- ### Initialize IAP Connection - Custom Instance Source: https://flutter-inapp-purchase.hyo.dev/docs/getting-started/installation Demonstrates how to initialize the `flutter_inapp_purchase` connection by creating a custom instance of `FlutterInappPurchase` within a StatefulWidget and managing its lifecycle. ```dart import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart'; class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State { final FlutterInappPurchase iap = FlutterInappPurchase(); @override void initState() { super.initState(); _initializeIAP(); } Future _initializeIAP() async { try { await iap.initConnection(); print('IAP connection initialized successfully'); } catch (e) { print('Failed to initialize IAP connection: $e'); } } @override void dispose() { iap.endConnection(); super.dispose(); } @override Widget build(BuildContext context) { return MaterialApp( home: MyHomePage(), ); } } ``` -------------------------------- ### Initialize Flutter In-App Purchase Connection Source: https://flutter-inapp-purchase.hyo.dev/docs/getting-started/quickstart Establishes the connection to the in-app purchase services. This must be called before any other methods are used. ```dart await FlutterInappPurchase.instance.initConnection(); ``` -------------------------------- ### Troubleshoot Package Installation Failures Source: https://flutter-inapp-purchase.hyo.dev/docs/6.3/troubleshooting Steps to resolve dependency conflicts during `flutter pub get`. This includes clearing the pub cache, cleaning the project, and attempting to upgrade dependencies. ```bash flutter pub cache repair flutter clean flutter pub get flutter pub deps flutter pub upgrade ``` -------------------------------- ### Complete Flutter In-App Purchase Migration Example (v5.x to v6.x) Source: https://flutter-inapp-purchase.hyo.dev/docs/migration/from-v5 Provides a comprehensive before-and-after comparison of a Flutter In-App Purchase implementation, highlighting changes in initialization, stream subscriptions, purchase requests, product fetching, and transaction completion. ```dart class _MyAppState extendsState{ StreamSubscription? _purchaseUpdatedSubscription; StreamSubscription? _purchaseErrorSubscription; List _items =[]; List _purchases =[]; @override voidinitState(){ super.initState(); initPlatformState(); } FutureinitPlatformState()async{ try{ await FlutterInappPurchase.instance.initConnection(); print('IAP connection initialized'); }catch(e){ print('Failed to initialize: $e'); } _purchaseUpdatedSubscription = FlutterInappPurchase .purchaseUpdated.listen((productItem){ if(productItem !=null){ print('purchase-updated: ${productItem.productId}'); setState((){ _purchases.add(productItem); }); // Finish the transaction _finishTransaction(productItem); } }); _purchaseErrorSubscription = FlutterInappPurchase .purchaseError.listen((productItem){ print('purchase-error: ${productItem?.productId}'); // Handle error }); _getProduct(); } void_requestPurchase(IapItem item)async{ try{ await FlutterInappPurchase.instance.requestPurchase(item.productId!); }catch(e){ print('Purchase request failed: $e'); } } Future_finishTransaction(PurchasedItem item)async{ try{ await FlutterInappPurchase.instance.finishTransaction(item); }catch(e){ print('Failed to finish transaction: $e'); } } Future_getProduct()async{ try{ List items =await FlutterInappPurchase .instance .getProducts(_kProductIds); setState((){ _items = items; }); }catch(e){ print('Failed to get products: $e'); } } @override voiddispose(){ _purchaseUpdatedSubscription?.cancel(); _purchaseErrorSubscription?.cancel(); super.dispose(); } } ``` -------------------------------- ### Add flutter_inapp_purchase Dependency Source: https://flutter-inapp-purchase.hyo.dev/docs/6.3/getting-started/installation Installs the flutter_inapp_purchase package using the Flutter CLI. This is the recommended way to add the dependency to your project. ```bash flutter pub add flutter_inapp_purchase ``` -------------------------------- ### Initialize IAP Connection (Singleton Instance) Source: https://flutter-inapp-purchase.hyo.dev/docs/6.3/getting-started/installation Shows how to initialize the In-App Purchase connection using the singleton instance provided by the plugin. This is a more concise way to access the IAP functionality. ```dart class _MyAppState extends State { final iap = FlutterInappPurchase.instance; Future _initializeIAP() async { await iap.initConnection(); } } ``` -------------------------------- ### Handle Purchase Flow and Updates Source: https://flutter-inapp-purchase.hyo.dev/docs/getting-started/quickstart Manages the purchase process by listening for successful purchases and errors. It includes requesting a purchase and handling the response, which involves verification, content delivery, and transaction finalization. ```dart // Listen to successful purchases FlutterInappPurchase.purchaseUpdated.listen((productItem){ // 1. Verify purchase // 2. Deliver content // 3. Finish transaction }); // Listen to purchase errors FlutterInappPurchase.purchaseError.listen((error){ // Handle error }); // Request a purchase await FlutterInappPurchase.instance.requestPurchase( request:RequestPurchase( ios:RequestPurchaseIOS(sku:'product_id'), android:RequestPurchaseAndroid(skus:['product_id']), ), type:PurchaseType.inapp,// or PurchaseType.subs for subscriptions ); ``` -------------------------------- ### Initialize and Manage In-App Purchases in Flutter Source: https://flutter-inapp-purchase.hyo.dev/docs/getting-started/quickstart This snippet shows how to initialize the flutter_inapp_purchase plugin, set up listeners for purchase updates and errors, and manage the purchase lifecycle. It includes methods for fetching products, handling purchases, and finishing transactions. ```dart import 'package:flutter/material.dart'; import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart'; import 'dart:async'; import 'dart:io'; class SimpleStore extends StatefulWidget { @override _SimpleStoreState createState() => _SimpleStoreState(); } class _SimpleStoreState extends State { StreamSubscription? _purchaseUpdatedSubscription; StreamSubscription? _purchaseErrorSubscription; List _products = []; List _subscriptions = []; List _purchases = []; final List _productIds = [ 'com.example.coins_100', 'com.example.coins_500', ]; final List _subscriptionIds = [ 'com.example.premium_monthly', 'com.example.premium_yearly', ]; @override void initState() { super.initState(); initIAP(); } @override void dispose() { _purchaseUpdatedSubscription?.cancel(); _purchaseErrorSubscription?.cancel(); super.dispose(); } Future initIAP() async { final iap = FlutterInappPurchase(); await iap.initConnection(); print('IAP connection initialized'); _purchaseUpdatedSubscription = iap.purchaseUpdated.listen((productItem) { print('Purchase updated: ${productItem?.productId}'); _handlePurchaseUpdate(productItem!); }); _purchaseErrorSubscription = iap.purchaseError.listen((purchaseError) { print('Purchase error: $purchaseError'); _showError('Purchase failed: ${purchaseError.message}'); }); await _getProducts(); await _getPurchases(); } Future _getProducts() async { try { List products = await FlutterInappPurchase.instance.requestProducts( productIds: _productIds, type: PurchaseType.inapp, ); List subscriptions = await FlutterInappPurchase.instance.requestProducts( productIds: _subscriptionIds, type: PurchaseType.subs, ); setState(() { _products = products; _subscriptions = subscriptions; }); } catch (e) { _showError('Failed to load products: $e'); } } Future _getPurchases() async { try { List? purchases = await FlutterInappPurchase.instance.getAvailablePurchases(); setState(() { _purchases = purchases ?? []; }); } catch (e) { _showError('Failed to load purchases: $e'); } } void _handlePurchaseUpdate(PurchasedItem productItem) async { bool isValid = await _verifyPurchase(productItem); if (isValid) { await _deliverProduct(productItem); if (Platform.isIOS) { await FlutterInappPurchase.instance.finishTransaction(productItem); } else if (productItem.isConsumableAndroid ?? false) { await FlutterInappPurchase.instance.consumePurchase( purchaseToken: productItem.purchaseToken!, ); } else { await FlutterInappPurchase.instance.acknowledgePurchase( purchaseToken: productItem.purchaseToken!, ); } await _getPurchases(); _showSuccess('Purchase successful!'); } } Future _requestPurchase(String productId) async { try { await FlutterInappPurchase.instance.requestPurchase( request: RequestPurchase( ios: RequestPurchaseIOS(sku: productId), android: RequestPurchaseAndroid(skus: [productId]), ), type: PurchaseType.inapp, ); } catch (e) { _showError('Purchase failed: $e'); } } Future _requestSubscription(String productId) async { try { await FlutterInappPurchase.instance.requestPurchase( request: RequestPurchase( ios: RequestPurchaseIOS(sku: productId), android: RequestPurchaseAndroid(skus: [productId]), ), type: PurchaseType.subs, ); } catch (e) { _showError('Subscription failed: $e'); } } Future _restorePurchases() async { try { await FlutterInappPurchase.instance.getAvailablePurchases(); _showSuccess('Purchases restored!'); } catch (e) { _showError('Restore failed: $e'); } } Future _verifyPurchase(PurchasedItem item) async { // TODO: Implement server-side verification return true; } Future _deliverProduct(PurchasedItem item) async { // TODO: Implement product delivery logic } void _showError(String message) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(message), backgroundColor: Colors.red), ); } void _showSuccess(String message) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(message), backgroundColor: Colors.green), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Simple Store')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('Products:'), ..._products.map((p) => TextButton( onPressed: () => _requestPurchase(p.productId), child: Text('${p.title} - ${p.price}'), )).toList(), SizedBox(height: 20), Text('Subscriptions:'), ..._subscriptions.map((s) => TextButton( onPressed: () => _requestSubscription(s.productId), child: Text('${s.title} - ${s.price}'), )).toList(), SizedBox(height: 20), ElevatedButton(onPressed: _restorePurchases, child: Text('Restore Purchases')), SizedBox(height: 20), Text('Purchases:'), ..._purchases.map((purchase) => Text('ID: ${purchase.productId}, Date: ${purchase.purchaseDate}')).toList(), ], ), ), ); } } ``` -------------------------------- ### Android build.gradle Minimum SDK Configuration Source: https://flutter-inapp-purchase.hyo.dev/docs/6.3/getting-started/installation Ensures the Android build.gradle file meets the minimum SDK version requirement for the flutter_inapp_purchase plugin. This is crucial for compatibility. ```gradle android { compileSdkVersion 34 defaultConfig { minSdkVersion 21 targetSdkVersion 34 } } ``` -------------------------------- ### iOS Info.plist Configuration for App Queries Source: https://flutter-inapp-purchase.hyo.dev/docs/getting-started/installation Configures the `Info.plist` file on iOS to include `itms-apps` in `LSApplicationQueriesSchemes`, which is necessary for certain app interactions, particularly on iOS 14 and later. ```xml LSApplicationQueriesSchemes itms-apps ``` -------------------------------- ### Initialize IAP Connection - Flutter Hooks Source: https://flutter-inapp-purchase.hyo.dev/docs/getting-started/installation Illustrates initializing and managing the `flutter_inapp_purchase` connection within a Flutter widget using the `flutter_hooks` package, providing a declarative approach to state management. ```dart import 'package:flutter_hooks/flutter_hooks.dart'; class MyWidget extends HookWidget { @override Widget build(BuildContext context) { final iapState = useIAP(); return Text('Connected: ${iapState.connected}'); } } ``` -------------------------------- ### Add flutter_inapp_purchase to pubspec.yaml Source: https://flutter-inapp-purchase.hyo.dev/docs/getting-started/installation Manually adds the flutter_inapp_purchase plugin as a dependency in your project's `pubspec.yaml` file. ```yaml dependencies: flutter_inapp_purchase: ^6.4.0 ``` -------------------------------- ### Complete Flutter In-App Purchase Migration Example (v5.x vs v6.x) Source: https://flutter-inapp-purchase.hyo.dev/docs/6.3/migration/from-v5 Provides a comprehensive before-and-after comparison of a Flutter application's state management for in-app purchases, highlighting changes in initialization, stream subscriptions, product requests, and transaction handling. ```dart class _MyAppState extendsState{ StreamSubscription? _purchaseUpdatedSubscription; StreamSubscription? _purchaseErrorSubscription; List _items =[]; List _purchases =[]; @override voidinitState(){ super.initState(); initPlatformState(); } FutureinitPlatformState()async{ try{ await FlutterInappPurchase.instance.initConnection(); print('IAP connection initialized'); }catch(e){ print('Failed to initialize: $e'); } _purchaseUpdatedSubscription = FlutterInappPurchase .purchaseUpdated.listen((productItem){ if(productItem !=null){ print('purchase-updated: ${productItem.productId}'); setState((){ _purchases.add(productItem); }); // Finish the transaction _finishTransaction(productItem); } }); _purchaseErrorSubscription = FlutterInappPurchase .purchaseError.listen((productItem){ print('purchase-error: ${productItem?.productId}'); // Handle error }); _getProduct(); } void_requestPurchase(IapItem item)async{ try{ await FlutterInappPurchase.instance.requestPurchase(item.productId!); }catch(e){ print('Purchase request failed: $e'); } } Future_finishTransaction(PurchasedItem item)async{ try{ await FlutterInappPurchase.instance.finishTransaction(item); }catch(e){ print('Failed to finish transaction: $e'); } } Future_getProduct()async{ try{ List items =await FlutterInappPurchase .instance .getProducts(_kProductIds); setState((){ _items = items; }); }catch(e){ print('Failed to get products: $e'); } } @override voiddispose(){ _purchaseUpdatedSubscription?.cancel(); _purchaseErrorSubscription?.cancel(); super.dispose(); } } ``` -------------------------------- ### Android ProGuard Rules for In-App Purchase Source: https://flutter-inapp-purchase.hyo.dev/docs/6.3/getting-started/installation Includes ProGuard rules for the flutter_inapp_purchase plugin to prevent code stripping and ensure proper functionality when code obfuscation is enabled. ```proguard # In-App Purchase -keep class com.amazon.** {*;} -keep class dev.hyo.** { *; } -keep class com.android.vending.billing.** -dontwarn com.amazon.** -keepattributes *Annotation* ``` -------------------------------- ### Flutter In-App Purchase Package Configuration Source: https://flutter-inapp-purchase.hyo.dev/docs/6.3/guides/troubleshooting Provides the necessary configuration steps for using the flutter_inapp_purchase package. This includes adding the dependency to `pubspec.yaml`, running `flutter pub get`, and setting minimum SDK versions in `build.gradle` and `project.pbxproj`. ```yaml # pubspec.yaml dependencies: flutter_inapp_purchase: ^6.0.0 ``` ```bash flutter pub get ``` ```gradle # android/app/build.gradle android { compileSdkVersion 34 defaultConfig { minSdkVersion 21 targetSdkVersion 34 } } ``` ```objective-c # ios/Runner.xcodeproj/project.pbxproj IPHONEOS_DEPLOYMENT_TARGET = 12.0; ``` -------------------------------- ### Get Product Details (Android) Source: https://flutter-inapp-purchase.hyo.dev/docs/6.3/getting-started/android-setup Fetches detailed information for a list of Android product IDs. It prints various details including title, description, price, currency, and Android-specific information like product type and offers. ```dart // Get detailed product information FuturegetProductDetails()async{ try{ final products =awaitFlutterInappPurchase.instance.getProducts(androidProductIds); for(var product in products){ print('Product ID: ${product.productId}'); print('Title: ${product.title}'); print('Description: ${product.description}'); print('Price: ${product.localizedPrice}'); print('Currency: ${product.currency}'); // Android-specific details if(product.productDetailsAndroid !=null){ final details = product.productDetailsAndroid!; print('Product type: ${details.productType}'); print('One-time purchase offer: ${details.oneTimePurchaseOfferDetails}'); } } }catch(error){ print('Failed to get product details: $error'); } } ``` -------------------------------- ### Android build.gradle Minimum SDK Configuration Source: https://flutter-inapp-purchase.hyo.dev/docs/getting-started/installation Sets the minimum and target SDK versions for an Android application within the `build.gradle` file. The `flutter_inapp_purchase` plugin requires a minimum SDK version of 21. ```gradle android { compileSdkVersion 34 defaultConfig { minSdkVersion 21 # Required minimum targetSdkVersion 34 } } ``` -------------------------------- ### Setup iOS Testing Environment Source: https://flutter-inapp-purchase.hyo.dev/docs/guides/purchases Provides guidance on setting up the iOS testing environment for in-app purchases. It emphasizes using a test Apple ID in the sandbox environment and ensuring products are correctly configured in App Store Connect. It also suggests testing with different sandbox user accounts. ```dart // For iOS testing in sandbox environment voidsetupIOSTesting(){ debugPrint('Testing on iOS Sandbox'); // Use test Apple ID for sandbox testing // Products must be configured in App Store Connect // Test with different sandbox user accounts } ``` -------------------------------- ### Initialize IAP Connection (Create Own Instance) Source: https://flutter-inapp-purchase.hyo.dev/docs/6.3/getting-started/installation Demonstrates how to initialize the In-App Purchase connection by creating a custom instance of FlutterInappPurchase. This involves calling `initConnection` in `initState` and `endConnection` in `dispose`. ```dart import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart'; class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State { final FlutterInappPurchase iap = FlutterInappPurchase(); @override void initState() { super.initState(); _initializeIAP(); } Future _initializeIAP() async { try { await iap.initConnection(); print('IAP connection initialized successfully'); } catch (e) { print('Failed to initialize IAP connection: $e'); } } @override void dispose() { iap.endConnection(); super.dispose(); } @override Widget build(BuildContext context) { return MaterialApp( home: MyHomePage(), ); } } ``` -------------------------------- ### Get Product Details (Android) Source: https://flutter-inapp-purchase.hyo.dev/docs/getting-started/android-setup Fetches detailed information for a list of Android product IDs. It prints various details including title, description, price, currency, and Android-specific information like product type and offers. ```dart // Get detailed product information FuturegetProductDetails()async{ try{ final products =awaitFlutterInappPurchase.instance.getProducts(androidProductIds); for(var product in products){ print('Product ID: ${product.productId}'); print('Title: ${product.title}'); print('Description: ${product.description}'); print('Price: ${product.localizedPrice}'); print('Currency: ${product.currency}'); // Android-specific details if(product.productDetailsAndroid !=null){ final details = product.productDetailsAndroid!; print('Product type: ${details.productType}'); print('One-time purchase offer: ${details.oneTimePurchaseOfferDetails}'); } } }catch(error){ print('Failed to get product details: $error'); } } ``` -------------------------------- ### Setup Android Testing Environment Source: https://flutter-inapp-purchase.hyo.dev/docs/guides/purchases Details the setup for testing Android in-app purchases using predefined test product IDs. It lists common test IDs like 'android.test.purchased', 'android.test.canceled', 'android.test.refunded', and 'android.test.item_unavailable'. The example specifically includes 'android.test.purchased' and 'android.test.canceled' for demonstration. ```dart // For Android testing with test purchases voidsetupAndroidTesting(){ debugPrint('Testing on Android'); // Use test product IDs like: // - android.test.purchased // - android.test.canceled // - android.test.refunded // - android.test.item_unavailable final testProductIds =[ 'android.test.purchased',// Always succeeds 'android.test.canceled',// Always cancelled ]; } ``` -------------------------------- ### Add flutter_inapp_purchase to pubspec.yaml Source: https://flutter-inapp-purchase.hyo.dev/docs/6.3/getting-started/installation Manually adds the flutter_inapp_purchase dependency to your project's pubspec.yaml file. After editing, run `flutter pub get` to fetch the package. ```yaml dependencies: flutter_inapp_purchase: ^6.4.0 ``` -------------------------------- ### Basic Implementation Steps Source: https://flutter-inapp-purchase.hyo.dev/docs/6.3/guides/faq Provides a step-by-step guide for integrating flutter_inapp_purchase, including initialization, setting up listeners for purchase updates and errors, loading products, and requesting a purchase. ```Dart // 1. Import the package import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart'; import 'package:flutter_inapp_purchase/types.dart' as iap_types; // 2. Initialize connection await FlutterInappPurchase.instance.initConnection(); // 3. Set up listeners with null checks FlutterInappPurchase.purchaseUpdated.listen((purchase){ if(purchase !=null){ // Handle successful purchase _handlePurchaseSuccess(purchase); } }); FlutterInappPurchase.purchaseError.listen((error){ if(error !=null){ // Handle purchase error _handlePurchaseError(error); } }); // 4. Load products final products =await FlutterInappPurchase.instance.getProducts([ 'product_id_1', 'product_id_2', ]); // 5. Request purchase await FlutterInappPurchase.instance.requestPurchase( request:RequestPurchase( ios:RequestPurchaseIOS(sku:'product_id', quantity:1), android:RequestPurchaseAndroid(skus:['product_id']), ), type:PurchaseType.inapp, ); ``` -------------------------------- ### Setup Android Testing Environment Source: https://flutter-inapp-purchase.hyo.dev/docs/6.3/guides/purchases Details the setup for testing Android in-app purchases using predefined test product IDs. It lists common test IDs like 'android.test.purchased', 'android.test.canceled', 'android.test.refunded', and 'android.test.item_unavailable'. The example specifically includes 'android.test.purchased' and 'android.test.canceled' for demonstration. ```dart // For Android testing with test purchases voidsetupAndroidTesting(){ debugPrint('Testing on Android'); // Use test product IDs like: // - android.test.purchased // - android.test.canceled // - android.test.refunded // - android.test.item_unavailable final testProductIds =[ 'android.test.purchased',// Always succeeds 'android.test.canceled',// Always cancelled ]; } ``` -------------------------------- ### Subscription Example (Dart) Source: https://flutter-inapp-purchase.hyo.dev/docs/api/types/product-type Provides an example of creating a `Subscription` object for a monthly plan, including details like `productId`, `price`, `platform`, and introductory pricing information. ```dart Subscription monthlyPlan =Subscription( productId:'com.example.monthly', price:'4.99', currency:'USD', localizedPrice:'$4.99', title:'Monthly Subscription', description:'Access all features for a month', platform:IAPPlatform.ios, subscriptionPeriodUnitIOS:'MONTH', subscriptionPeriodNumberIOS:1, introductoryPrice:'0.99', introductoryPriceNumberOfPeriodsIOS:1, ); ``` -------------------------------- ### Flutter In-App Purchase UI Example Source: https://flutter-inapp-purchase.hyo.dev/docs/6.3/getting-started/quickstart A Flutter widget demonstrating the UI for in-app purchases. It displays products and subscriptions, allows users to initiate purchases, and shows active purchases. Includes helper methods for displaying snackbar messages for errors and success. ```dart print('Delivering product: ${item.productId}'); } // UI Helper methods void_showError(String message){ ScaffoldMessenger.of(context).showSnackBar( SnackBar(content:Text(message), backgroundColor:Colors.red), ); } void_showSuccess(String message){ ScaffoldMessenger.of(context).showSnackBar( SnackBar(content:Text(message), backgroundColor:Colors.green), ); } @override Widgetbuild(BuildContext context){ returnScaffold( appBar:AppBar( title:Text('In-App Purchase Example'), actions:[ IconButton( icon:Icon(Icons.restore), onPressed: _restorePurchases, tooltip:'Restore Purchases', ), ], ), body:SingleChildScrollView( padding:EdgeInsets.all(16), child:Column( crossAxisAlignment:CrossAxisAlignment.start, children:[ // Products Section Text('Products', style:Theme.of(context).textTheme.headline6), SizedBox(height:8), ..._products.map((product)=>Card( child:ListTile( title:Text(product.title ?? product.productId ??''), subtitle:Text(product.description ??''), trailing:TextButton( child:Text(product.localizedPrice ??''), onPressed:()=>_requestPurchase(product.productId!), ), ), )), SizedBox(height:24), // Subscriptions Section Text('Subscriptions', style:Theme.of(context).textTheme.headline6), SizedBox(height:8), ..._subscriptions.map((subscription)=>Card( child:ListTile( title:Text(subscription.title ?? subscription.productId ??''), subtitle:Text(subscription.description ??''), trailing:TextButton( child:Text(subscription.localizedPrice ??''), onPressed:()=>_requestSubscription(subscription.productId!), ), leading:_isPurchased(subscription.productId!) ?Icon(Icons.check_circle, color:Colors.green) :null, ), )), SizedBox(height:24), // Active Purchases Section Text('Active Purchases', style:Theme.of(context).textTheme.headline6), SizedBox(height:8), if(_purchases.isEmpty) Text('No active purchases'), ..._purchases.map((purchase)=>Card( child:ListTile( title:Text(purchase.productId ??'Unknown'), subtitle:Text('Purchased: ${DateTime.fromMillisecondsSinceEpoch( purchase.transactionDate ??0 )}'), ), )), ], ), ), ); } bool _isPurchased(String productId){ return _purchases.any((purchase)=> purchase.productId == productId); } } ``` -------------------------------- ### Product Example (Dart) Source: https://flutter-inapp-purchase.hyo.dev/docs/api/types/product-type Provides an example of how to instantiate the `Product` class for a premium feature, setting all necessary properties including `productId`, `price`, `platform`, and `isFamilyShareable`. ```dart Product premiumFeature =Product( productId:'com.example.premium', price:'9.99', currency:'USD', localizedPrice:'$9.99', title:'Premium Features', description:'Unlock all premium features', platform:IAPPlatform.ios, isFamilyShareable:true, ); ``` -------------------------------- ### Basic Purchase Flow Example Source: https://flutter-inapp-purchase.hyo.dev/docs/6.3/api/overview Demonstrates the fundamental steps for implementing a basic in-app purchase flow in Flutter. It covers initialization, setting up listeners, loading products, requesting a purchase, and handling the purchase in the listener. ```dart // 1. Initialize awaitFlutterInappPurchase.instance.initialize(); // 2. Set up listeners FlutterInappPurchase.instance.purchaseUpdatedListener.listen(handlePurchase); // 3. Load products var products =awaitFlutterInappPurchase.instance.requestProducts( skus: productIds, type:PurchaseType.inapp ); // 4. Request purchase awaitFlutterInappPurchase.instance.requestPurchase(productId); // 5. Handle in listener voidhandlePurchase(Purchase purchase){ // Verify, deliver, and finish } ``` -------------------------------- ### Get Available Purchases Example Source: https://flutter-inapp-purchase.hyo.dev/docs/api/overview Retrieves a list of all available purchases, including pending and non-consumed items, using the `getAvailablePurchases` method. ```dart Future?>getAvailablePurchases()async Retrieves all available purchases (including pending and non-consumed). **Returns** : List of purchases or null ``` -------------------------------- ### Initialize Connection Example Source: https://flutter-inapp-purchase.hyo.dev/docs/api/overview Demonstrates how to establish a connection to the store using the `initialize` method. This must be called before any other IAP operations. ```dart Futureinitialize()async Establishes connection to the store. Must be called before any other methods. **Returns** : Connection result message or error **Example** : String? result =awaitFlutterInappPurchase.instance.initialize(); if(result =='Billing is unavailable'){ // Handle unavailable billing } ``` -------------------------------- ### Check Platform Features Source: https://flutter-inapp-purchase.hyo.dev/docs/6.3/guides/purchases Identifies the current platform (iOS or Android) and provides examples of platform-specific features that can be utilized within the in-app purchase flow. ```dart voidcheckPlatformFeatures(){ if(Platform.isIOS){ // iOS-specific features debugPrint('iOS platform detected'); // Can use iOS-specific methods like: // - presentCodeRedemptionSheet() // - showManageSubscriptions() // - isEligibleForIntroOfferIOS() }elseif(Platform.isAndroid){ // Android-specific features debugPrint('Android platform detected'); // Can use Android-specific methods like: // - consumePurchaseAndroid() // - deepLinkToSubscriptionsAndroid() // - getConnectionStateAndroid() } } ``` -------------------------------- ### Request Products Example Source: https://flutter-inapp-purchase.hyo.dev/docs/api/overview Shows how to fetch product or subscription details for a given list of SKUs using the `requestProducts` method. ```dart Future>requestProducts({ required List skus, PurchaseType type =PurchaseType.inapp, })async Fetches product or subscription information for the given SKUs. **Parameters** : * `skus`: List of product identifiers * `type`: Product type - `PurchaseType.inapp` (regular) or `PurchaseType.subs` (subscriptions) **Returns** : List of available products or subscriptions **Examples** : // Get regular products (consumables and non-consumables) List products =awaitFlutterInappPurchase.instance .requestProducts(skus:['coin_pack_100','remove_ads'], type:PurchaseType.inapp); // Get subscriptions List subscriptions =awaitFlutterInappPurchase.instance .requestProducts(skus:['premium_monthly','premium_yearly'], type:PurchaseType.subs); ```