in_app_purchase application setup
import 'dart:async'; import 'package:Flutter/material.dart'; import 'package:in_app_purchase/in_app_purchase.dart'; import 'dart:io'; import 'package:in_app_purchase_android/in_app_purchase_android.dart'; void main() { runApp( const MaterialApp( home: Purchase() ), ); } const String testID = 'book_test'; class Purchase extends StatefulWidget { const Purchase({Key? key}) : super(key: key); @override _PurchaseState createState() => _PurchaseState(); } class _PurchaseState extends State<Purchase> { // Instantiates inAppPurchase final InAppPurchase _iap = InAppPurchase.instance; // checks if the API is available on this device bool _isAvailable = false; // keeps a list of products queried from Playstore or app store List<ProductDetails> _products = []; // List of users past purchases List<PurchaseDetails> _purchases = []; // subscription that listens to a stream of updates to purchase details late StreamSubscription _subscription; // used to represents consumable credits the user can buy int _coins = 0; Future<void> _initialize() async { // Check availability of InApp Purchases _isAvailable = await _iap.isAvailable(); // perform our async calls only when in-app purchase is available if(_isAvailable){ await _getUserProducts(); await _getPastPurchases(); _verifyPurchases(); // listen to new purchases and rebuild the widget whenever // there is a new purchase after adding the new purchase to our // purchase list _subscription = _iap.purchaseStream.listen((data)=> setState((){ _purchases.addAll(data); _verifyPurchases(); })); } } // Method to retrieve product list Future<void> _getUserProducts() async { Set<String> ids = {testID}; ProductDetailsResponse response = await _iap.queryProductDetails(ids); setState(() { _products = response.productDetails; }); } // Method to retrieve users past purchase Future<void> _getPastPurchases() async { QueryPurchaseDetailsResponse response = await _iap.queryPastPurchases(); for(PurchaseDetails purchase in response.pastPurchases){ if(Platform.isIOS){ _iap.completePurchase(purchase); } } setState(() { _purchases = response.pastPurchases; }); } // checks if a user has purchased a certain product PurchaseDetails _hasUserPurchased(String productID){ return _purchases.firstWhere((purchase) => purchase.productID == productID); } // Method to check if the product has been purchased already or not. void _verifyPurchases(){ PurchaseDetails purchase = _hasUserPurchased(testID); if(purchase.status == PurchaseStatus.purchased){ _coins = 10; } } // Method to purchase a product void _buyProduct(ProductDetails prod){ final PurchaseParam purchaseParam = PurchaseParam(productDetails: prod); _iap.buyConsumable(purchaseParam: purchaseParam, autoConsume: false); } void spendCoins(PurchaseDetails purchase) async { setState(() { _coins--; }); if(_coins == 0 ){ var res = await _iap.consumePurchase(purchase); } } @override void initState() { _initialize(); super.initState(); } @override void dispose() { // cancelling the subscription _subscription.cancel(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(_isAvailable ? 'Product Available': 'No Product Available'), ), body: Center( child: Column( children: [ // Looping over products from app store or Playstore // for each product, determine if the user has a past purchase for it for (var product in _products) // If purchase exists if(_hasUserPurchased(product.id) != null) ...[ Text('$_coins', style: const TextStyle(fontSize: 30),), ElevatedButton( onPressed: ()=> spendCoins(_hasUserPurchased(product.id)), child: const Text('Consume')), ] // If not purchased exist else ...[ Text(product.title,), Text(product.description), Text(product.price), ElevatedButton( onPressed: () => _buyProduct(product), child: const Text('')) ] ], ), ), ); } }