import 'dart:async'; import 'package:electronic_assistant/sdk/pay/assist/apple_or_google_pay_info.dart'; import 'package:electronic_assistant/sdk/pay/assist/product_type.dart'; import 'package:flutter/cupertino.dart'; import 'package:in_app_purchase/in_app_purchase.dart'; import '../code/agile_pay_code.dart'; import 'agile_pay_state_info.dart'; abstract class AppleOrGooglePay extends AgilePayStateInfo { final AppleOrGooglePayInfo _payInfo; late final StreamSubscription> _purchaseUpdatedSubscription; late final InAppPurchase _iap; final Duration timeout = const Duration(seconds: 10); AppleOrGooglePay(this._payInfo) { _iap = InAppPurchase.instance; _purchaseUpdatedSubscription = _iap.purchaseStream.listen((purchaseDetailsList) { listenToPurchaseUpdated(purchaseDetailsList); }, onDone: () { _purchaseUpdatedSubscription.cancel(); }, onError: (error) {}); } void pay() async { sendPayBefore(); try { final bool isAe = await isAvailable(); if (!isAe) { sendError(AgilePayCode.payCodeNotConnectStore, AgilePayCode.getMessageByCode(AgilePayCode.payCodeNotConnectStore)); return; } final ProductDetailsResponse response = await queryProductDetails({_payInfo.productId}); if (response.notFoundIDs.isNotEmpty || response.productDetails.isEmpty) { sendError( AgilePayCode.payCodeProductNotFindStore, AgilePayCode.getMessageByCode( AgilePayCode.payCodeProductNotFindStore)); return; } List products = response.productDetails; for (var element in products) { bool isSend; if (_payInfo.type == ProductType.consumable) { isSend = await buyConsumable( purchaseParam: PurchaseParam( productDetails: element, applicationUserName: _payInfo.accountToken)); } else { isSend = await buyNonConsumable( purchaseParam: PurchaseParam( productDetails: element, applicationUserName: _payInfo.accountToken)); } if (!isSend) { sendError( AgilePayCode.payCodeRequestSendError, AgilePayCode.getMessageByCode( AgilePayCode.payCodeRequestSendError)); return; } return; } } catch (e) { if (e is TimeoutException) { sendError(AgilePayCode.payCodeNotConnectStore, AgilePayCode.getMessageByCode(AgilePayCode.payCodeNotConnectStore)); return; } sendError(AgilePayCode.payCodeOtherError, AgilePayCode.getMessageByCode(AgilePayCode.payCodeOtherError)); return; } } Future isAvailable() { return _iap.isAvailable().timeout(timeout); } Future queryProductDetails(Set identifiers) { return InAppPurchase.instance.queryProductDetails(identifiers); } Future buyConsumable({required PurchaseParam purchaseParam}) { return _iap.buyConsumable(purchaseParam: purchaseParam); } Future buyNonConsumable({required PurchaseParam purchaseParam}) { return _iap.buyNonConsumable(purchaseParam: purchaseParam); } void dispose() { _purchaseUpdatedSubscription.cancel(); } void listenToPurchaseUpdated(List purchaseDetailsList) { for (var purchaseDetails in purchaseDetailsList) { debugPrint( 'agilePay-purchasePay--PurchaseUpdated-> ${purchaseDetails.toString()}'); if (purchaseDetails.status == PurchaseStatus.pending) { verifyPendingPurchase(purchaseDetails); } else if (purchaseDetails.status == PurchaseStatus.error) { verifyErrorPurchase(purchaseDetails); } else if (purchaseDetails.status == PurchaseStatus.purchased) { verifySuccessPurchase(purchaseDetails); } else if (purchaseDetails.status == PurchaseStatus.canceled) { verifyCancelPurchase(purchaseDetails); } } } void verifyPendingPurchase(PurchaseDetails purchaseDetails) {} void verifyCancelPurchase(PurchaseDetails purchaseDetails) { sendError(AgilePayCode.payCodeCancelError, AgilePayCode.getMessageByCode(AgilePayCode.payCodeCancelError)); } void verifyErrorPurchase(PurchaseDetails purchaseDetails) { sendError(AgilePayCode.payCodePayError, AgilePayCode.getMessageByCode(AgilePayCode.payCodePayError)); } void verifySuccessPurchase(PurchaseDetails purchaseDetails) { sendPaySuccess(purchaseDetails.purchaseID); } }