| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- import 'package:flutter/cupertino.dart';
- import 'package:injectable/injectable.dart';
- import 'package:location/data/bean/goods_bean.dart';
- import 'package:location/data/bean/pay_item_bean.dart';
- import 'package:location/data/repositories/member_repository.dart';
- import 'package:synchronized/synchronized.dart';
- import '../data/api/response/order_first_check_response.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 MemberRepository memberRepository;
- PaymentStatusManager(this.memberRepository);
- final Map<String, PaymentStatusCallback> callbackMap = {};
- final Map<String, CancelableFuture> pollingSubscriptionMap = {};
- final _lock = Lock();
- void _startCheckPolling(
- String orderNo, PayItemBean paymentWay, GoodsBean storeItemBean,
- {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, paymentWay, storeItemBean);
- callbackMap.remove(orderNo);
- });
- reportPaySuccess(storeItemBean.amount, orderNo, storeItemBean.name,
- paymentWay.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 memberRepository
- .orderStatus(orderNo, receiptData: receiptData)
- .then((status) async {
- if (status == PaymentStatus.payStatusSuccess) {
- return status;
- }
- throw PaymentStatusException(status);
- });
- }
- ///检查是否是第一次支付
- Future<OrderFirstCheckResponse> onOrderFirstCheck() {
- return memberRepository.
- orderFirstCheck()
- .then((checkResponse) {
- return checkResponse;
- });
- }
- void reportPaySuccess(
- int price, String orderId, String itemName, int paymentWay) {
- EventHandler.reportPay(price, orderId, itemName, paymentWay);
- }
- void checkPaymentStatus(
- String orderNo, PayItemBean paymentWay, GoodsBean storeItemBean,
- {String? receiptData}) {
- final way = paymentWay.copyWith();
- final goods = storeItemBean.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, PayItemBean paymentWay, GoodsBean storeItemBean);
- }
|