You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 04:25:09