apple_or_google_pay.dart 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import 'dart:async';
  2. import 'package:classify_photo/classify_photo.dart';
  3. import 'package:clean/sdk/pay/assist/product_type.dart';
  4. import 'package:flutter/cupertino.dart';
  5. import 'package:in_app_purchase/in_app_purchase.dart';
  6. import '../code/agile_pay_code.dart';
  7. import 'agile_pay_state_info.dart';
  8. import 'apple_or_google_pay_info.dart';
  9. abstract class AppleOrGooglePay extends AgilePayStateInfo {
  10. final AppleOrGooglePayInfo? _payInfo;
  11. late final StreamSubscription<List<PurchaseDetails>>
  12. _purchaseUpdatedSubscription;
  13. late final InAppPurchase _iap;
  14. final Duration timeout = const Duration(seconds: 10);
  15. bool isCheck = false;
  16. bool isRestoring = false;
  17. AppleOrGooglePay([this._payInfo]) {
  18. _iap = InAppPurchase.instance;
  19. _purchaseUpdatedSubscription =
  20. _iap.purchaseStream.listen((purchaseDetailsList) {
  21. listenToPurchaseUpdated(purchaseDetailsList);
  22. }, onDone: () {
  23. dispose();
  24. }, onError: (error) {});
  25. }
  26. Future<void> check() async {
  27. isCheck = true;
  28. }
  29. Future<void> restore() async {
  30. sendPayBefore();
  31. ClassifyPhoto().finishTransaction();
  32. isRestoring = false;
  33. final bool isAe = await isAvailable();
  34. if (!isAe) {
  35. sendError(AgilePayCode.payCodeNotConnectStore,
  36. AgilePayCode.getMessageByCode(AgilePayCode.payCodeNotConnectStore));
  37. return;
  38. }
  39. await InAppPurchase.instance.restorePurchases();
  40. }
  41. void pay() async {
  42. sendPayBefore();
  43. ClassifyPhoto().finishTransaction();
  44. isCheck = false;
  45. try {
  46. final bool isAe = await isAvailable();
  47. if (!isAe) {
  48. sendError(AgilePayCode.payCodeNotConnectStore,
  49. AgilePayCode.getMessageByCode(AgilePayCode.payCodeNotConnectStore));
  50. return;
  51. }
  52. if (_payInfo == null) {
  53. sendError(AgilePayCode.payCodeOrderInfoError,
  54. AgilePayCode.getMessageByCode(AgilePayCode.payCodeOrderInfoError));
  55. return;
  56. }
  57. final ProductDetailsResponse response =
  58. await queryProductDetails({_payInfo.productId});
  59. if (response.notFoundIDs.isNotEmpty || response.productDetails.isEmpty) {
  60. sendError(
  61. AgilePayCode.payCodeProductNotFindStore,
  62. AgilePayCode.getMessageByCode(
  63. AgilePayCode.payCodeProductNotFindStore));
  64. return;
  65. }
  66. List<ProductDetails> products = response.productDetails;
  67. for (var element in products) {
  68. bool isSend;
  69. if (_payInfo.type == ProductType.consumable) {
  70. isSend = await buyConsumable(
  71. purchaseParam: PurchaseParam(
  72. productDetails: element,
  73. applicationUserName: _payInfo.accountToken));
  74. } else {
  75. isSend = await buyNonConsumable(
  76. purchaseParam: PurchaseParam(
  77. productDetails: element,
  78. applicationUserName: _payInfo.accountToken));
  79. }
  80. if (!isSend) {
  81. sendError(
  82. AgilePayCode.payCodeRequestSendError,
  83. AgilePayCode.getMessageByCode(
  84. AgilePayCode.payCodeRequestSendError));
  85. return;
  86. }
  87. return;
  88. }
  89. } catch (e) {
  90. if (e is TimeoutException) {
  91. sendError(AgilePayCode.payCodeNotConnectStore,
  92. AgilePayCode.getMessageByCode(AgilePayCode.payCodeNotConnectStore));
  93. return;
  94. }
  95. sendError(AgilePayCode.payCodeOtherError,
  96. AgilePayCode.getMessageByCode(AgilePayCode.payCodeOtherError));
  97. return;
  98. }
  99. }
  100. Future<bool> isAvailable() {
  101. return _iap.isAvailable().timeout(timeout);
  102. }
  103. Future<ProductDetailsResponse> queryProductDetails(Set<String> identifiers) {
  104. return InAppPurchase.instance.queryProductDetails(identifiers);
  105. }
  106. Future<bool> buyConsumable({required PurchaseParam purchaseParam}) {
  107. return _iap.buyConsumable(purchaseParam: purchaseParam);
  108. }
  109. Future<bool> buyNonConsumable({required PurchaseParam purchaseParam}) {
  110. return _iap.buyNonConsumable(purchaseParam: purchaseParam);
  111. }
  112. void dispose() {
  113. _purchaseUpdatedSubscription.cancel();
  114. }
  115. void listenToPurchaseUpdated(
  116. List<PurchaseDetails> purchaseDetailsList) async {
  117. for (var purchaseDetails in purchaseDetailsList) {
  118. debugPrint(
  119. 'agilePay-purchasePay--PurchaseUpdated-> ${purchaseDetails.toString()}');
  120. if (purchaseDetails.status == PurchaseStatus.pending) {
  121. verifyPendingPurchase(purchaseDetails);
  122. } else {
  123. if (purchaseDetails.status == PurchaseStatus.error) {
  124. verifyErrorPurchase(purchaseDetails);
  125. } else if (purchaseDetails.status == PurchaseStatus.purchased && !isCheck) {
  126. verifySuccessPurchase(purchaseDetails);
  127. } else if (purchaseDetails.status == PurchaseStatus.canceled) {
  128. verifyCancelPurchase(purchaseDetails);
  129. } else if (purchaseDetails.status == PurchaseStatus.restored && !isRestoring) {
  130. print("订阅");
  131. isRestoring = true;
  132. verifyRestorePurchase(purchaseDetails);
  133. }
  134. if (purchaseDetails.pendingCompletePurchase) {
  135. await InAppPurchase.instance.completePurchase(purchaseDetails);
  136. dispose();
  137. }
  138. }
  139. }
  140. }
  141. void verifyPendingPurchase(PurchaseDetails purchaseDetails) {}
  142. void verifyCancelPurchase(PurchaseDetails purchaseDetails) {
  143. sendError(AgilePayCode.payCodeCancelError,
  144. AgilePayCode.getMessageByCode(AgilePayCode.payCodeCancelError));
  145. }
  146. void verifyErrorPurchase(PurchaseDetails purchaseDetails) {
  147. sendError(AgilePayCode.payCodePayError,
  148. AgilePayCode.getMessageByCode(AgilePayCode.payCodePayError));
  149. }
  150. void verifySuccessPurchase(PurchaseDetails purchaseDetails) {
  151. sendPaySuccess(purchaseDetails.verificationData.serverVerificationData);
  152. }
  153. void verifyRestorePurchase(PurchaseDetails purchaseDetails) {
  154. sendRestoreSuccess(purchaseDetails.verificationData.serverVerificationData);
  155. }
  156. }