payment_status_manager.dart 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import 'package:electronic_assistant/data/repositories/account_repository.dart';
  2. import 'package:electronic_assistant/data/repositories/store_repository.dart';
  3. import 'package:electronic_assistant/utils/async_util.dart';
  4. import 'package:flutter/cupertino.dart';
  5. import 'package:synchronized/synchronized.dart';
  6. import '../../data/bean/payment_way.dart';
  7. import '../../data/bean/store_item.dart';
  8. import '../../utils/cancel_future.dart';
  9. class PaymentStatusManager {
  10. PaymentStatusManager._();
  11. //订单状态
  12. //0-查询失败,继续轮询
  13. //1-未支付,继续轮询
  14. //2-支付成功
  15. //3-支付关闭
  16. //4-已退款
  17. static const int payStatusFail = 0;
  18. static const int payStatusUnpaid = 1;
  19. static const int payStatusSuccess = 2;
  20. static const int payStatusClose = 3;
  21. static const int payStatusRefund = 4;
  22. final Map<String, PaymentStatusCallback> callbackMap = {};
  23. final Map<String, CancelableFuture> pollingSubscriptionMap = {};
  24. final _lock = Lock();
  25. void _startCheckPolling(
  26. String orderNo, PaymentWay paymentWay, StoreItem storeItemBean) async {
  27. await _lock.synchronized(() async {
  28. pollingSubscriptionMap[orderNo]?.cancel();
  29. debugPrint('开始轮询支付状态: orderNo = $orderNo');
  30. CancelableFuture orderFuture = AsyncUtil.retryWithExponentialBackoff(
  31. () {
  32. return storeRepository.orderStatus(orderNo).then((status) {
  33. if (status == payStatusSuccess) {
  34. return true;
  35. } else {
  36. throw PaymentStatusException(status);
  37. }
  38. });
  39. },
  40. 10,
  41. (error) {
  42. if (error is PaymentStatusException) {
  43. return error.status == payStatusFail ||
  44. error.status == payStatusUnpaid;
  45. }
  46. return true;
  47. });
  48. orderFuture.then((data) async {
  49. debugPrint('支付成功: orderNo = $orderNo');
  50. accountRepository.refreshUserInfo();
  51. await _lock.synchronized(() {
  52. callbackMap[orderNo]
  53. ?.onPaymentSuccess(orderNo, paymentWay, storeItemBean);
  54. callbackMap.remove(orderNo);
  55. });
  56. reportPaySuccess(storeItemBean.amount, orderNo, storeItemBean.name,
  57. paymentWay.payMethod);
  58. }).catchError((error) {
  59. debugPrint('支付失败: orderNo = $orderNo, error = $error');
  60. });
  61. pollingSubscriptionMap[orderNo] = orderFuture;
  62. });
  63. }
  64. void reportPaySuccess(
  65. int price, String orderId, String itemName, int paymentWay) {}
  66. void checkPaymentStatus(
  67. String orderNo, PaymentWay paymentWay, StoreItem storeItemBean) {
  68. // recordKeyInfoToDisk(orderNo, paymentWay, storeItemBean);
  69. _startCheckPolling(orderNo, paymentWay, storeItemBean);
  70. }
  71. void registerPaymentSuccessCallback(
  72. String orderNo, PaymentStatusCallback callback) async {
  73. await _lock.synchronized(() {
  74. callbackMap[orderNo] = callback;
  75. });
  76. }
  77. void unregisterPaymentSuccessCallback(PaymentStatusCallback callback) async {
  78. await _lock.synchronized(() {
  79. callbackMap.removeWhere((key, value) => value == callback);
  80. });
  81. }
  82. }
  83. class PaymentStatusException implements Exception {
  84. final int status;
  85. PaymentStatusException(this.status);
  86. @override
  87. String toString() {
  88. return '支付状态异常: status = $status';
  89. }
  90. }
  91. abstract class PaymentStatusCallback {
  92. void onPaymentSuccess(
  93. String orderNo, PaymentWay paymentWay, StoreItem storeItemBean);
  94. }
  95. final paymentStatusManager = PaymentStatusManager._();