import 'package:electronic_assistant/data/repositories/account_repository.dart'; import 'package:electronic_assistant/data/repositories/store_repository.dart'; import 'package:electronic_assistant/handler/event_handler.dart'; import 'package:electronic_assistant/utils/async_util.dart'; import 'package:flutter/cupertino.dart'; import 'package:synchronized/synchronized.dart'; import '../../data/bean/payment_way.dart'; import '../../data/bean/store_item.dart'; class PaymentStatusManager { PaymentStatusManager._(); //订单状态 //0-查询失败,继续轮询 //1-未支付,继续轮询 //2-支付成功 //3-支付关闭 //4-已退款 static const int payStatusFail = 0; static const int payStatusUnpaid = 1; static const int payStatusSuccess = 2; static const int payStatusClose = 3; static const int payStatusRefund = 4; final Map callbackMap = {}; final Map pollingSubscriptionMap = {}; final _lock = Lock(); void _startCheckPolling( String orderNo, PaymentWay paymentWay, StoreItem storeItemBean, {String? receiptData}) async { await _lock.synchronized(() async { pollingSubscriptionMap[orderNo]?.cancel(); debugPrint('开始轮询支付状态: orderNo = $orderNo'); CancelableFuture orderFuture = AsyncUtil.retryWithExponentialBackoff( () { return storeRepository .orderStatus(orderNo, receiptData: receiptData) .then((status) { if (status == payStatusSuccess) { return true; } else { throw PaymentStatusException(status); } }); }, 10, predicate: (error) { if (error is PaymentStatusException) { return error.status == payStatusFail || error.status == payStatusUnpaid; } return true; }); orderFuture.then((data) async { debugPrint('支付成功: orderNo = $orderNo'); accountRepository.refreshUserInfo(); await _lock.synchronized(() { callbackMap[orderNo] ?.onPaymentSuccess(orderNo, paymentWay, storeItemBean); callbackMap.remove(orderNo); }); reportPaySuccess(storeItemBean.amount, orderNo, storeItemBean.name, paymentWay.payMethod); }).catchError((error) { debugPrint('支付失败: orderNo = $orderNo, error = $error'); }); pollingSubscriptionMap[orderNo] = orderFuture; }); } void reportPaySuccess( int price, String orderId, String itemName, int paymentWay) { EventHandler.reportPay(price, orderId, itemName, paymentWay); } void checkPaymentStatus( String orderNo, PaymentWay paymentWay, StoreItem storeItemBean, {String? receiptData}) { // recordKeyInfoToDisk(orderNo, paymentWay, storeItemBean); _startCheckPolling(orderNo, paymentWay, storeItemBean, receiptData: receiptData); } void registerPaymentSuccessCallback( String orderNo, PaymentStatusCallback callback) async { await _lock.synchronized(() { callbackMap[orderNo] = callback; }); } void unregisterPaymentSuccessCallback(PaymentStatusCallback callback) async { await _lock.synchronized(() { callbackMap.removeWhere((key, value) => value == callback); }); } } class PaymentStatusException implements Exception { final int status; PaymentStatusException(this.status); @override String toString() { return '支付状态异常: status = $status'; } } abstract class PaymentStatusCallback { void onPaymentSuccess( String orderNo, PaymentWay paymentWay, StoreItem storeItemBean); } final paymentStatusManager = PaymentStatusManager._();