|
|
@@ -1,16 +1,111 @@
|
|
|
+import 'dart:async';
|
|
|
+
|
|
|
import 'package:electronic_assistant/sdk/pay/applepay/apple_pay_info.dart';
|
|
|
+import 'package:in_app_purchase/in_app_purchase.dart';
|
|
|
|
|
|
import '../assist/agile_pay_state_info.dart';
|
|
|
+import '../assist/product_type.dart';
|
|
|
+import '../code/agile_pay_code.dart';
|
|
|
import '../listener/i_agile_pay.dart';
|
|
|
|
|
|
class ApplePay extends AgilePayStateInfo implements IAgilePay {
|
|
|
final ApplePayInfo _payInfo;
|
|
|
+ late final StreamSubscription<List<PurchaseDetails>>
|
|
|
+ _purchaseUpdatedSubscription;
|
|
|
+ late final InAppPurchase _iap;
|
|
|
+
|
|
|
+ final Duration timeout = const Duration(seconds: 15);
|
|
|
+
|
|
|
+ ApplePay(this._payInfo) {
|
|
|
+ _iap = InAppPurchase.instance;
|
|
|
+ _purchaseUpdatedSubscription =
|
|
|
+ _iap.purchaseStream.listen((purchaseDetailsList) {
|
|
|
+ _listenToPurchaseUpdated(purchaseDetailsList);
|
|
|
+ }, onDone: () {
|
|
|
+ _purchaseUpdatedSubscription.cancel();
|
|
|
+ }, onError: (error) {});
|
|
|
+ }
|
|
|
+
|
|
|
+ void _listenToPurchaseUpdated(List<PurchaseDetails> purchaseDetailsList) {
|
|
|
+ for (var purchaseDetails in purchaseDetailsList) {
|
|
|
+ if (purchaseDetails.status == PurchaseStatus.pending) {
|
|
|
+ } else if (purchaseDetails.status == PurchaseStatus.error) {
|
|
|
+ _verifyErrorPurchase(purchaseDetails);
|
|
|
+ } else if (purchaseDetails.status == PurchaseStatus.purchased) {
|
|
|
+ _verifySuccessPurchase(purchaseDetails);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void _verifyErrorPurchase(PurchaseDetails purchaseDetails) {
|
|
|
+ if (purchaseDetails.error?.code == 'store_kit_network_error') {
|
|
|
+ sendError(AgilePayCode.payCodeNetError,
|
|
|
+ AgilePayCode.getMessageByCode(AgilePayCode.payCodeNetError));
|
|
|
+ } else if (purchaseDetails.error?.code == 'store_kit_payment_cancelled') {
|
|
|
+ sendError(AgilePayCode.payCodeCancelError,
|
|
|
+ AgilePayCode.getMessageByCode(AgilePayCode.payCodeCancelError));
|
|
|
+ } else {
|
|
|
+ sendError(AgilePayCode.payCodeOtherError,
|
|
|
+ AgilePayCode.getMessageByCode(AgilePayCode.payCodeOtherError));
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- ApplePay(this._payInfo);
|
|
|
+ void _verifySuccessPurchase(PurchaseDetails purchaseDetails) {
|
|
|
+ sendPaySuccess(purchaseDetails.purchaseID);
|
|
|
+ }
|
|
|
|
|
|
@override
|
|
|
- void pay() {}
|
|
|
+ void pay() async {
|
|
|
+ sendPayBefore();
|
|
|
+ try {
|
|
|
+ final bool isAvailable = await _iap.isAvailable().timeout(timeout);
|
|
|
+ if (!isAvailable) {
|
|
|
+ sendError(AgilePayCode.payCodeNotConnectStore,
|
|
|
+ AgilePayCode.getMessageByCode(AgilePayCode.payCodeNotConnectStore));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ final ProductDetailsResponse response = await InAppPurchase.instance
|
|
|
+ .queryProductDetails({_payInfo.productId});
|
|
|
+ if (response.notFoundIDs.isNotEmpty || response.productDetails.isEmpty) {
|
|
|
+ sendError(
|
|
|
+ AgilePayCode.payCodeProductNotFindStore,
|
|
|
+ AgilePayCode.getMessageByCode(
|
|
|
+ AgilePayCode.payCodeProductNotFindStore));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ List<ProductDetails> products = response.productDetails;
|
|
|
+ for (var element in products) {
|
|
|
+ bool isSend;
|
|
|
+ if (_payInfo.type == ProductType.consumable) {
|
|
|
+ isSend = await _iap.buyConsumable(
|
|
|
+ purchaseParam: PurchaseParam(productDetails: element));
|
|
|
+ } else {
|
|
|
+ isSend = await _iap.buyNonConsumable(
|
|
|
+ purchaseParam: PurchaseParam(productDetails: element));
|
|
|
+ }
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
@override
|
|
|
- void dispose() {}
|
|
|
+ void dispose() {
|
|
|
+ _purchaseUpdatedSubscription.cancel();
|
|
|
+ }
|
|
|
}
|