| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- import 'package:flutter/cupertino.dart';
- import 'package:injectable/injectable.dart';
- import 'package:keyboard/data/bean/goods_info.dart';
- import 'package:keyboard/data/bean/pay_way_info.dart';
- import 'package:keyboard/data/repository/store_repository.dart';
- import 'package:synchronized/synchronized.dart';
- import '../handler/event_handler.dart';
- import 'async_util.dart';
- class PaymentStatus {
- PaymentStatus._();
- //订单状态
- //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;
- }
- @lazySingleton
- class PaymentStatusManager {
- final StoreRepository storeRepository;
- PaymentStatusManager(this.storeRepository);
- final Map<String, PaymentStatusCallback> callbackMap = {};
- final Map<String, CancelableFuture> pollingSubscriptionMap = {};
- final _lock = Lock();
- void _startCheckPolling(
- String orderNo, PayWayInfo payWayInfo, GoodsInfo goodsInfo,
- {String? receiptData}) async {
- await _lock.synchronized(() async {
- pollingSubscriptionMap[orderNo]?.cancel();
- debugPrint('开始轮询支付状态: orderNo = $orderNo');
- CancelableFuture<int> orderFuture = AsyncUtil.retry(
- () => _queryOrderStatus(orderNo, receiptData: receiptData),
- Duration(seconds: 2), predicate: (error) {
- if (error is PaymentStatusException) {
- return error.status == PaymentStatus.payStatusFail ||
- error.status == PaymentStatus.payStatusUnpaid;
- }
- return true;
- }, maxRetry: 50);
- orderFuture.then((status) async {
- debugPrint('支付成功: orderNo = $orderNo');
- await _lock.synchronized(() {
- callbackMap[orderNo]
- ?.onPaymentSuccess(orderNo, payWayInfo, goodsInfo);
- callbackMap.remove(orderNo);
- });
- reportPaySuccess(goodsInfo.amount, orderNo, goodsInfo.name,
- payWayInfo.payMethod);
- }).catchError((error) async {
- await _lock.synchronized(() {
- callbackMap.remove(orderNo);
- });
- debugPrint('支付失败: orderNo = $orderNo, error = $error');
- });
- pollingSubscriptionMap[orderNo] = orderFuture;
- });
- }
- Future<int> _queryOrderStatus(String orderNo, {String? receiptData}) {
- return storeRepository
- .orderStatus(orderNo, receiptData: receiptData)
- .then((status) async {
- if (status == PaymentStatus.payStatusSuccess) {
- return status;
- }
- throw PaymentStatusException(status);
- });
- }
- void reportPaySuccess(
- int price, String orderId, String itemName, int paymentWay) {
- EventHandler.reportPay(price, orderId, itemName, paymentWay);
- }
- void checkPaymentStatus(
- String orderNo, PayWayInfo payWayInfo, GoodsInfo goodsInfo,
- {String? receiptData}) {
- final way = payWayInfo.copyWith();
- final goods = goodsInfo.copyWith();
- // recordKeyInfoToDisk(orderNo, paymentWay, storeItemBean);
- _startCheckPolling(orderNo, way, goods, 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);
- });
- }
- void removePollingSubscription(String orderNo) {
- pollingSubscriptionMap[orderNo]?.cancel();
- pollingSubscriptionMap.remove(orderNo);
- callbackMap.remove(orderNo);
- }
- }
- class PaymentStatusException implements Exception {
- final int status;
- PaymentStatusException(this.status);
- @override
- String toString() {
- return '支付状态异常: status = $status';
- }
- }
- abstract class PaymentStatusCallback {
- void onPaymentSuccess(
- String orderNo, PayWayInfo payWayInfo, GoodsInfo goodsInfo);
- }
|