import 'dart:io'; import 'package:agile_pay/flutter_pay.dart'; import 'package:apple_pay/apple_pay.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:get/get_core/src/get_main.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:location/utils/common_expand.dart'; import '../data/api/response/request_pay_response.dart'; import '../data/bean/wechat_payment_sign_bean.dart'; import '../data/consts/channel_id.dart'; import '../data/consts/error_code.dart'; import '../data/consts/payment_type.dart'; import '../data/repositories/account_repository.dart'; import '../device/atmob_platform_info.dart'; import '../dialog/alipay_qr_code_dialog.dart'; import '../dialog/common_confirm_dialog.dart'; import '../dialog/loading_dialog.dart'; import '../dialog/wechat_qr_code_dialog.dart'; import '../module/login/login_page.dart'; import '../resource/string.gen.dart'; import '../utils/http_handler.dart'; import '../utils/payment_status_manager.dart'; import '../utils/toast_util.dart'; @lazySingleton class MemberPayHelper implements PaymentStatusCallback { final PaymentStatusManager paymentStatusManager; final MemberRepository memberRepository; MemberPayHelper(this.paymentStatusManager, this.memberRepository); Future launchPay(GoodsBean? bean, PayItemBean? payWay) async { if (bean == null) { ToastUtil.show(StringName.memberPleaseChoiceGoods); return; } if (payWay == null && !Platform.isIOS) { ToastUtil.show(StringName.memberPleaseChoicePayment); return; } //增加渠道登录判断 if (atmobPlatformInfo.tgPlatform == ChannelId.sd) { if (!AccountRepository.getInstance().isLogin.value) { ToastUtil.show(StringName.accountNoLogin); final isLogin = await LoginPage.start(); if (!isLogin) { return; } } } int goodsId = bean.id; int payPlatform = payWay!.payPlatform; int payMethod = payWay.payMethod; LoadingDialog.show(StringName.payLoading); memberRepository.setLastSelectedMember(bean, payWay); try { final RequestPayResponse response = await MemberRepository.getInstance() .submitAndRequestPay( goodsId: goodsId, payPlatform: payPlatform, payMethod: payMethod); int payWayType = getPayWayType(payMethod: payMethod, payPlatform: payPlatform); if (payWayType == PayWayType.paymentWayWechat) { _onWeChatPay(response.outTradeNo, response.wechatPayPrepayJson!, payMethod, bean, payWay); } else if (payWayType == PayWayType.paymentWayWechatScan) { _onWechatScanPay( response.outTradeNo, response.wechatPayQrcodeUrl!, payWay, bean); } else if (payWayType == PayWayType.paymentWayAlipay) { _onAliPay(response.outTradeNo, response.alipayOrderString!, payMethod, bean, payWay); } else if (payWayType == PayWayType.paymentWayAlipayScan) { _onAliScanPay( response.outTradeNo, response.alipayQrcodeHtml!, payWay, bean); } else if (payWayType == PayWayType.paymentWayApple) { _onApplePay( response.outTradeNo, response.appAccountToken ?? "", payWay, bean); } else { LoadingDialog.hide(); ToastUtil.show(StringName.payNotSupport); } } catch (error) { LoadingDialog.hide(); if (error is ServerErrorException) { if (error.code == ErrorCode.payOrderError) { ToastUtil.show(error.message); } else if (error.code == ErrorCode.noLoginError) { ToastUtil.show(StringName.accountNoLogin); LoginPage.start(); } else { ToastUtil.show(error.message); } } else { ToastUtil.show(StringName.memberPaymentFailed); } rethrow; } } Future _onApplePay( String outTradeNo, String appAccountToken, PayItemBean payWayInfo, GoodsBean goodsInfo, ) async { final result = await ApplePay().purchase( productId: goodsInfo.appleGoodsId ?? "", appAccountToken: appAccountToken, ); if (result["success"] == true) { var receipt = result['receipt']; print('购买成功: ${result['receipt']}'); checkPaymentStatus( outTradeNo, payWayInfo, goodsInfo, receiptData: receipt, ); } else { LoadingDialog.hide(); ToastUtil.show("支付失败,请稍后重试"); print('购买失败: ${result['error']}'); } } void _onAliScanPay(String outTradeNo, String qrHtml, PayItemBean paymentWay, GoodsBean goodsBean) { LoadingDialog.hide(); AlipayQrCodeDialog.show( qrCodeHtml: qrHtml, loadSuccessCallback: () { checkPaymentStatus(outTradeNo, paymentWay, goodsBean); }, onCloseCallback: () async { //关闭后再持续查询几秒 CustomLoadingDialog.show(); await Future.delayed(Duration(seconds: 4)); paymentStatusManager.removePollingSubscription(outTradeNo); CustomLoadingDialog.hide(); }); } void _onAliPay(String outTradeNo, String payJson, int payMethod, GoodsBean buyGoods, PayItemBean buyPayWay) { final payInfo = AliPayInfo(payJson); requestSdkPay(payInfo, outTradeNo, payMethod, buyGoods, buyPayWay); } void _onWeChatPay(String outTradeNo, String payJson, int payMethod, GoodsBean buyGoods, PayItemBean buyPayWay) { final bean = WechatPaymentSignBean.stringToBean(payJson); final payInfo = WechatPayInfo( appId: bean.appId, partnerId: bean.partnerId, prepayId: bean.prepayId, package: bean.package, noncestr: bean.nonceStr, timestamp: bean.timeStamp, sign: bean.sign); requestSdkPay(payInfo, outTradeNo, payMethod, buyGoods, buyPayWay); } void _onWechatScanPay(String outTradeNo, String qrCodeUrl, PayItemBean paymentWay, GoodsBean goodsBean) { LoadingDialog.hide(); WechatQrCodeDialog.show( qrCodeUrl: qrCodeUrl, loadSuccessCallback: () { checkPaymentStatus(outTradeNo, paymentWay, goodsBean); }, onCloseCallback: () async { //关闭后再持续查询几秒 CustomLoadingDialog.show(); await Future.delayed(Duration(seconds: 4)); paymentStatusManager.removePollingSubscription(outTradeNo); CustomLoadingDialog.hide(); }); } void requestSdkPay(dynamic payInfo, String outTradeNo, int payMethod, GoodsBean buyGoods, PayItemBean buyPayWay) { AgilePay.startPay(payInfo, success: (String? result) { checkPaymentStatus(outTradeNo, buyPayWay, buyGoods, receiptData: result); }, payError: (int errno, String? errorMessage) { LoadingDialog.hide(); debugPrint('MemberPayHelper---payError: $errno, $errorMessage'); errorPayToast(errno); }, error: (int errno, String? error) { LoadingDialog.hide(); debugPrint('MemberPayHelper---error: $errno, $error'); errorPayToast(errno); }); } void checkPaymentStatus( String orderNo, PayItemBean paymentWay, GoodsBean goodsBean, {String? receiptData}) { LoadingDialog.show(StringName.payQuerypayState); paymentStatusManager.registerPaymentSuccessCallback(orderNo, this); paymentStatusManager.checkPaymentStatus(orderNo, paymentWay, goodsBean, receiptData: receiptData); } void errorPayToast(int errno) { if (errno == AgilePayCode.payCodeNotSupport) { ToastUtil.show(StringName.payNotSupport); } else if (errno == AgilePayCode.payCodeCancelError) { ToastUtil.show(StringName.payUserCancel); } else if (errno == AgilePayCode.payCodeWxEnvError) { ToastUtil.show(StringName.payWxEvnError); } else if (errno == AgilePayCode.payCodeNotConnectStore) { ToastUtil.show(StringName.payNotConnectStore); } else { ToastUtil.show(StringName.payError); } } @override void onPaymentFail() { LoadingDialog.hide(); } @override void onPaymentSuccess( String orderNo, PayItemBean paymentWay, GoodsBean storeItemBean) { ///购买成功消失 LoadingDialog.hide(); memberRepository.clearLastSelectedMember(); ///购买成功之后弹出 onPaySucessShow(); } void onPaySucessShow() { try { WechatQrCodeDialog.dismiss(); AlipayQrCodeDialog.dismiss(); CustomLoadingDialog.hide(); LoadingDialog.hide(); } catch (e) { debugPrint('zk---onPaymentSuccess error: $e'); } showPaymentSuccessDialog(onConfirm: () { if (Get.key.currentState?.canPop() ?? false) { Get.back(); } }, onCancel: () { if (Get.key.currentState?.canPop() ?? false) { Get.back(); } }); } void showPaymentSuccessDialog( {required VoidCallback onConfirm, required VoidCallback onCancel}) { CommonConfirmDialog.show( backDismiss: false, clickMaskDismiss: false, titleWidget: Text(StringName.paySuccessTitle, style: TextStyle( fontSize: 17.sp, color: '#333333'.color, fontWeight: FontWeight.bold)), descWidget: Text( StringName.paySuccessDesc, style: TextStyle(fontSize: 14.sp, color: '#404040'.color), ), confirmText: StringName.dialogSure, cancelOnTap: onCancel, confirmOnTap: onConfirm); } }