apple_pay.dart 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import 'dart:async';
  2. import 'package:electronic_assistant/sdk/pay/applepay/apple_pay_info.dart';
  3. import 'package:in_app_purchase/in_app_purchase.dart';
  4. import '../assist/agile_pay_state_info.dart';
  5. import '../assist/product_type.dart';
  6. import '../code/agile_pay_code.dart';
  7. import '../listener/i_agile_pay.dart';
  8. class ApplePay extends AgilePayStateInfo implements IAgilePay {
  9. final ApplePayInfo _payInfo;
  10. late final StreamSubscription<List<PurchaseDetails>>
  11. _purchaseUpdatedSubscription;
  12. late final InAppPurchase _iap;
  13. final Duration timeout = const Duration(seconds: 15);
  14. ApplePay(this._payInfo) {
  15. _iap = InAppPurchase.instance;
  16. _purchaseUpdatedSubscription =
  17. _iap.purchaseStream.listen((purchaseDetailsList) {
  18. _listenToPurchaseUpdated(purchaseDetailsList);
  19. }, onDone: () {
  20. _purchaseUpdatedSubscription.cancel();
  21. }, onError: (error) {});
  22. }
  23. void _listenToPurchaseUpdated(List<PurchaseDetails> purchaseDetailsList) {
  24. for (var purchaseDetails in purchaseDetailsList) {
  25. if (purchaseDetails.status == PurchaseStatus.pending) {
  26. } else if (purchaseDetails.status == PurchaseStatus.error) {
  27. _verifyErrorPurchase(purchaseDetails);
  28. } else if (purchaseDetails.status == PurchaseStatus.purchased) {
  29. _verifySuccessPurchase(purchaseDetails);
  30. }
  31. }
  32. }
  33. void _verifyErrorPurchase(PurchaseDetails purchaseDetails) {
  34. if (purchaseDetails.error?.code == 'store_kit_network_error') {
  35. sendError(AgilePayCode.payCodeNetError,
  36. AgilePayCode.getMessageByCode(AgilePayCode.payCodeNetError));
  37. } else if (purchaseDetails.error?.code == 'store_kit_payment_cancelled') {
  38. sendError(AgilePayCode.payCodeCancelError,
  39. AgilePayCode.getMessageByCode(AgilePayCode.payCodeCancelError));
  40. } else {
  41. sendError(AgilePayCode.payCodeOtherError,
  42. AgilePayCode.getMessageByCode(AgilePayCode.payCodeOtherError));
  43. }
  44. }
  45. void _verifySuccessPurchase(PurchaseDetails purchaseDetails) {
  46. sendPaySuccess(purchaseDetails.purchaseID);
  47. }
  48. @override
  49. void pay() async {
  50. sendPayBefore();
  51. try {
  52. final bool isAvailable = await _iap.isAvailable().timeout(timeout);
  53. if (!isAvailable) {
  54. sendError(AgilePayCode.payCodeNotConnectStore,
  55. AgilePayCode.getMessageByCode(AgilePayCode.payCodeNotConnectStore));
  56. return;
  57. }
  58. final ProductDetailsResponse response = await InAppPurchase.instance
  59. .queryProductDetails({_payInfo.productId});
  60. if (response.notFoundIDs.isNotEmpty || response.productDetails.isEmpty) {
  61. sendError(
  62. AgilePayCode.payCodeProductNotFindStore,
  63. AgilePayCode.getMessageByCode(
  64. AgilePayCode.payCodeProductNotFindStore));
  65. return;
  66. }
  67. List<ProductDetails> products = response.productDetails;
  68. for (var element in products) {
  69. bool isSend;
  70. if (_payInfo.type == ProductType.consumable) {
  71. isSend = await _iap.buyConsumable(
  72. purchaseParam: PurchaseParam(productDetails: element));
  73. } else {
  74. isSend = await _iap.buyNonConsumable(
  75. purchaseParam: PurchaseParam(productDetails: element));
  76. }
  77. if (!isSend) {
  78. sendError(
  79. AgilePayCode.payCodeRequestSendError,
  80. AgilePayCode.getMessageByCode(
  81. AgilePayCode.payCodeRequestSendError));
  82. return;
  83. }
  84. return;
  85. }
  86. } catch (e) {
  87. if (e is TimeoutException) {
  88. sendError(AgilePayCode.payCodeNotConnectStore,
  89. AgilePayCode.getMessageByCode(AgilePayCode.payCodeNotConnectStore));
  90. return;
  91. }
  92. sendError(AgilePayCode.payCodeOtherError,
  93. AgilePayCode.getMessageByCode(AgilePayCode.payCodeOtherError));
  94. return;
  95. }
  96. }
  97. @override
  98. void dispose() {
  99. _purchaseUpdatedSubscription.cancel();
  100. }
  101. }