Flutter集成Razorpay遇支付界面多次弹出问题求解决
解决Flutter中Razorpay多次点击支付按钮打开多个界面的问题
问题分析
你当前的代码尝试用_isPaymentProcessing标志防止重复点击,但核心问题是标志重置时机错误:_razorpay.open()仅触发支付界面,不会等待界面关闭,而你在finally块里直接将_isPaymentProcessing设为false,导致支付弹窗还未关闭时,用户就能再次点击按钮发起新请求。
解决方案
将标志重置逻辑移到Razorpay的支付回调(成功/失败/取消)中,确保只有支付流程完全结束后,才允许发起新的支付请求。具体实现如下:
1. 初始化Razorpay并绑定回调
在initState中完成实例初始化,并绑定三个核心回调函数,在回调里重置状态标志:
late Razorpay _razorpay; bool _isPaymentProcessing = false; @override void initState() { super.initState(); _razorpay = Razorpay(); // 绑定支付状态回调 _razorpay.on(Razorpay.EVENT_PAYMENT_SUCCESS, _handlePaymentSuccess); _razorpay.on(Razorpay.EVENT_PAYMENT_ERROR, _handlePaymentError); _razorpay.on(Razorpay.EVENT_EXTERNAL_WALLET, _handleExternalWallet); } // 支付成功回调 void _handlePaymentSuccess(PaymentSuccessResponse response) { _isPaymentProcessing = false; // 这里添加支付成功后的业务逻辑,比如更新订单状态、弹窗提示等 } // 支付失败/取消回调 void _handlePaymentError(PaymentFailureResponse response) { _isPaymentProcessing = false; // 这里添加支付失败后的业务逻辑,比如提示用户错误信息 } // 外部钱包支付回调 void _handleExternalWallet(ExternalWalletResponse response) { _isPaymentProcessing = false; // 这里添加外部钱包支付后的处理逻辑 }
2. 修改openCheckout方法
移除finally块中的标志重置,仅在异常分支和回调中重置状态:
void openCheckout(int varTotalValue, String? razorpayOrderId) async { if (_isPaymentProcessing) return; // 直接拦截重复点击请求 _isPaymentProcessing = true; try { String varUserLoginValue = await Utils().funcGetSession(ConstantSession.KeyUserLoginValue); log("varTotalValue ==: $varTotalValue"); String emailId = _userController.userResponseModel.data?.email ?? varUserLoginValue; String name = _userController.userResponseModel.data?.firstName ?? varUserLoginValue; String contactNo = _userController.userResponseModel.data?.contactNo ?? varUserLoginValue; var options = { 'key': varWebRazorPayKey, 'amount': ((varTotalValue) * 100).toInt(), 'send_sms_hash': true, 'name': name.capitalizeFirstofEach, 'description': '', 'order_id': razorpayOrderId, 'theme': {'color': '#FFC300'}, 'prefill': {'contact': contactNo, 'email': emailId}, "notify": {"sms": true, "email": true}, }; _razorpay.open(options); log('_razorpayPayments'); } catch (e) { debugPrint('Error: $e'); _isPaymentProcessing = false; // 异常场景下重置标志,避免用户无法再次发起支付 } }
3. 完善页面销毁逻辑
确保页面销毁时移除回调并清理实例,避免内存泄漏:
@override void dispose() { _razorpay.clear(); // 移除所有绑定的回调 _razorpay.off(Razorpay.EVENT_PAYMENT_SUCCESS); _razorpay.off(Razorpay.EVENT_PAYMENT_ERROR); _razorpay.off(Razorpay.EVENT_EXTERNAL_WALLET); super.dispose(); }
关键说明
- 将
_isPaymentProcessing的重置放在回调中,保证只有支付界面完全关闭(无论成功、失败还是用户主动取消),才允许发起新的支付请求。 - 异常分支中必须重置标志,避免因网络错误或其他异常导致状态锁死,用户无法再次发起支付。
内容的提问来源于stack exchange,提问作者RT Developer
相关产品推荐
相关产品推荐

