Line data Source code
1 : // Copyright 2023 The terCAD team. All rights reserved. 2 : // Use of this source code is governed by a CC BY-NC-ND 4.0 license that can be found in the LICENSE file. 3 : 4 : import 'dart:async'; 5 : 6 : import 'package:in_app_purchase/in_app_purchase.dart'; 7 : 8 : class PurchaseController { 9 : static const pCoffee = 'fin_consumable_coffee'; 10 : static const pDinner = 'fin_consumable_dinner'; 11 : static const pInitial = 'fin_consumable_init'; 12 : // static const pSubApple = 'fin_subscription_tiny'; Restricted without extended functionality 13 : // static const pSubGoogle = 'fin-subscription-tiny'; 14 : 15 0 : static InAppPurchase iap = InAppPurchase.instance; 16 : late StreamSubscription<List<PurchaseDetails>> _subscription; 17 : Function? callback; 18 : 19 0 : PurchaseController([this.callback]) { 20 0 : final purchaseUpdated = iap.purchaseStream; 21 0 : _subscription = purchaseUpdated.listen( 22 0 : _onUpdate, 23 0 : onDone: dispose, 24 0 : onError: _onError, 25 : ); 26 : } 27 : 28 0 : dispose() { 29 0 : _subscription.cancel(); 30 : } 31 : 32 0 : void _onError(dynamic error) { 33 : // ... trace error 34 : } 35 : 36 0 : Future<void> _onUpdate(List<PurchaseDetails> purchaseDetailsList) async { 37 0 : for (var purchaseDetails in purchaseDetailsList) { 38 0 : if (purchaseDetails.pendingCompletePurchase) { 39 0 : await iap.completePurchase(purchaseDetails); 40 : } 41 : } 42 0 : if (callback != null) { 43 0 : callback!(purchaseDetailsList); 44 : } 45 : } 46 : 47 0 : Future<List<ProductDetails>> load() async { 48 0 : final available = await iap.isAvailable(); 49 : if (!available) { 50 0 : return []; 51 : } 52 0 : final response = await iap.queryProductDetails(<String>{ 53 0 : pCoffee, 54 0 : pDinner, 55 0 : pInitial, 56 : // pSubApple, 57 : // pSubGoogle, 58 : }); 59 0 : iap.restorePurchases(); 60 0 : return response.productDetails; 61 : } 62 : 63 0 : static Future<void> buy(ProductDetails product) async { 64 0 : final purchaseParam = PurchaseParam(productDetails: product); 65 0 : if (product.id.contains('subscription')) { 66 0 : await iap.buyNonConsumable(purchaseParam: purchaseParam); 67 : } else { 68 0 : await iap.buyConsumable(purchaseParam: purchaseParam); 69 : } 70 : } 71 : }