In App Purchase
cashlinkml2021
plain_text
2 years ago
9.5 kB
14
Indexable
class InAppProductsScreen extends StatefulWidget { @override State<InAppProductsScreen> createState() => _InAppProductsScreenState(); } class _InAppProductsScreenState extends State<InAppProductsScreen> { List<String> _kProductIds = []; final bool _kAutoConsume = Platform.isIOS || true; final InAppPurchase _inAppPurchase = InAppPurchase.instance; List<ProductDetails> _products = <ProductDetails>[]; bool _isAvailable = false; bool _loading = true; StreamSubscription<List<PurchaseDetails>>? _subscription; bool isProcessing = false; bool pendingOrder = false; String orderID = 'Test Order ID = GPA-ABCD-1234-XYZ-09876'; int quantity = 1; User? currentUser = FirebaseAuth.instance.currentUser; @override void initState() { getProductIdsFromFirestore(); _subscription = InAppPurchase.instance.purchaseStream.listen((List<PurchaseDetails> purchaseDetailsList) { _listenToPurchaseUpdated(purchaseDetailsList); }); super.initState(); } void getProductIdsFromFirestore() async { final CollectionReference productsCollection = FirebaseFirestore.instance.collection('InAppProduct'); QuerySnapshot querySnapshot = await productsCollection.get(); List<String> productIds = []; for (DocumentSnapshot documentSnapshot in querySnapshot.docs) { String productId = documentSnapshot['ID']; productIds.add(productId); } _kProductIds.addAll(productIds); initStoreInfo(); } Future<void> initStoreInfo() async { final bool isAvailable = await _inAppPurchase.isAvailable(); final ProductDetailsResponse productDetailResponse = await _inAppPurchase.queryProductDetails(_kProductIds.toSet()); setState(() { _isAvailable = isAvailable; _products = productDetailResponse.productDetails; _loading = false; }); } void _listenToPurchaseUpdated(List<PurchaseDetails> purchaseDetailsList) async{ purchaseDetailsList.forEach((PurchaseDetails purchaseDetails) async { if (purchaseDetails.status == PurchaseStatus.pending) { await _inAppPurchase.completePurchase(purchaseDetails); setState(() { isProcessing = false; quantity = 1; pendingOrder = true; orderID = purchaseDetails.purchaseID!; }); print('Pending'); } else if (purchaseDetails.status == PurchaseStatus.error) { // Handle purchase error here setState(() { isProcessing = false; quantity = 1; }); VxToast.show(context, msg: 'Purchase Error',bgColor: kPrimaryLightColors); print('Error'); }else if (purchaseDetails.status == PurchaseStatus.canceled){ setState(() { isProcessing = false; quantity = 1; }); VxToast.show(context, msg: 'Purchase Canceled',bgColor: kPrimaryLightColors); print('Cancel'); } if (purchaseDetails.pendingCompletePurchase) { await _inAppPurchase.completePurchase(purchaseDetails); var product = await FirebaseFirestore.instance.collection('InAppProduct').doc(purchaseDetails.productID).get(); FirebaseFirestore.instance.collection('About-Info').doc('TotalBalance').update({ 'Balance' : FieldValue.increment(product['Price'] * quantity), }); setState(() { isProcessing = false; quantity = 1; }); VxToast.show(context, msg: 'Purchase Successfull ${product['Price'] * quantity}',bgColor: kPrimaryLightColors); } }); } @override void dispose() { _subscription?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { Size size = MediaQuery.of(context).size; return Scaffold( appBar: AppBar( title: Text('Products',style: TextStyle( color: Colors.white ),), backgroundColor: kPrimaryColors, elevation: 0, ), body: ListView( children: <Widget>[ _buildProductList(), ], ), ); } Card _buildProductList() { if (_loading) { return const Card( child: ListTile( leading: CircularProgressIndicator(color: kPrimaryColors,), title: Text('Fetching products...'))); } _products.sort((a, b) => a.rawPrice.compareTo(b.rawPrice)); final List<ListTile> productList = <ListTile>[]; productList.addAll(_products.map( (ProductDetails productDetails) { return ListTile( title: Text('Purchase ${productDetails.price}',style: TextStyle( fontSize: MediaQuery.of(context).size.width * 0.045, color: Colors.black54 ) ), subtitle: Text( productDetails.description,style: TextStyle( fontSize: MediaQuery.of(context).size.width * 0.04, color: Colors.black54 ) ), trailing: TextButton( style: TextButton.styleFrom( backgroundColor: Colors.green[800], primary: Colors.white, ), onPressed: () async { late PurchaseParam purchaseParam; purchaseParam = GooglePlayPurchaseParam(productDetails: productDetails, changeSubscriptionParam: null); _inAppPurchase.buyConsumable( purchaseParam: purchaseParam, autoConsume: _kAutoConsume, ); setState(() { isProcessing = true; }); }, child: Text(productDetails.price), ), ); }, )); return Card( child:Column( children: <Widget>[ if(isProcessing)...[ Divider(), Container( margin: EdgeInsets.symmetric( horizontal: MediaQuery.of(context).size.width * 0.2 ), child: Row( children: [ CircularProgressIndicator(), SizedBox(width: 10,), Text('Processing... ',style: TextStyle( fontSize: MediaQuery.of(context).size.width * 0.05, color: Colors.green )), ], ), ), SizedBox(height: 5,), Divider(), ], if(pendingOrder)...[ Divider(), Text(orderID,style: TextStyle( fontSize: MediaQuery.of(context).size.width * 0.04, color: Colors.black54 ),), Text('আপনার অর্ডারটি Pending হয়ে গেছে\nস্ক্রিনশর্ট নিন এবং আপনার এডমিন কে জমা দিন',style: TextStyle( fontSize: MediaQuery.of(context).size.width * 0.04, color: Colors.red )), SizedBox(height: 5,), GestureDetector( onTap: (){ setState(() { pendingOrder = false; orderID = ''; }); }, child: Container( width: double.infinity, color: Colors.lightGreen[100], padding: EdgeInsets.symmetric( vertical: MediaQuery.of(context).size.width * 0.01 ), child: Center(child: Text('Close',style: TextStyle( color: Colors.black54, fontSize: MediaQuery.of(context).size.width * 0.04 ),)), ), ), Divider(), ], Container( margin: EdgeInsets.symmetric( horizontal: MediaQuery.of(context).size.width * 0.047 ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ IconButton( onPressed: (){ setState(() { quantity = quantity - 1; }); }, icon: Icon(Icons.remove) ), Text('Qt ${quantity}',style: TextStyle( fontWeight: FontWeight.bold ),), IconButton( onPressed: (){ setState(() { quantity = quantity + 1; }); }, icon: Icon(Icons.add) ), //Restore Purchase ShortButton( text: 'Restore Purchase', press: (){ _inAppPurchase.restorePurchases(); VxToast.show(context, msg: 'Restore Success',bgColor: kPrimaryLightColors); // Navigator.push(context, MaterialPageRoute(builder: (context)=>ShowCustomAlert())); }, fontSize: 0.04, ) ], ), ) ] + productList, ), ); } }
Editor is loading...
Leave a Comment