如何在Flutter的inappwebview同窗口中打开RazorPay支付弹窗?
解决Flutter InAppWebView中RazorPay弹窗无法显示问题
核心原因
RazorPay Custom Checkout的createPayment方法默认会触发window.open请求弹出新窗口实现支付流程,即便开启javaScriptCanOpenWindowsAutomatically配置,InAppWebView也不会默认创建新的WebView实例承载弹出内容,因此弹窗无法正常渲染。
解决方案
方案一(优先推荐):修改Web端逻辑,使用内联弹窗避免新开窗口
直接在初始化RazorPay实例时添加modal: true配置,强制支付弹窗在当前页面的DOM内渲染,完全不触发新窗口请求,适配性最高。
修改后的Web端支付调用代码参考:
async makePayment() { try { // 初始化RazorPay时添加modal配置 const rz = new Razorpay({ key: '你的RazorPay密钥', // 其他原有初始化参数 modal: true // 新增该配置,强制内联渲染 }) const data = { callback_url: '<Callback URL>', redirect: false, // 改为false避免跳转 amount: 50000, email: 'gaurav.kumar@example.com', contact: '9123456780', order_id: 'order_<order_hash>', method: 'upi', upi: { vpa: this.vpa, flow: 'collect', }, }; rz.createPayment(data); } catch (e) { console.error(e); } }
方案二:适配InAppWebView弹窗逻辑,支持新窗口打开
如果必须保留RazorPay的弹出窗口逻辑,需要手动实现onCreateWindow回调,创建新的WebView承载弹出内容,修改后的Flutter代码如下:
@override Widget build(BuildContext context) { return WillPopScope( onWillPop: _handleBackPress, child: SafeArea( child: Scaffold( body: InAppWebView( initialUrlRequest: URLRequest( url: Uri.parse(Strings.checkoutUrl), ), initialOptions: InAppWebViewGroupOptions( crossPlatform: InAppWebViewOptions( clearCache: true, javaScriptCanOpenWindowsAutomatically: true, mediaPlaybackRequiresUserGesture: false, javaScriptEnabled: true, // 显式开启JS支持 supportMultipleWindows: true, // 新增:允许多窗口 ), android: AndroidInAppWebViewOptions(useHybridComposition: true), ios: IOSInAppWebViewOptions(allowsInlineMediaPlayback: true), ), onWebViewCreated: (controller) async { _controller = controller; _controller.clearCache(); _controller.addJavaScriptHandler( handlerName: 'PaymentHandle', callback: (data) { // ... 后续业务逻辑 }, ); }, // 新增:处理弹出窗口请求 onCreateWindow: (controller, createWindowAction) async { // 创建新的WebViewController承载弹窗内容 InAppWebViewController? newWebController; // 展示弹窗WebView,可根据需求封装为全屏Dialog或者新页面 showDialog( context: context, builder: (context) => AlertDialog( content: SizedBox( width: double.maxFinite, child: InAppWebView( windowId: createWindowAction.windowId, onWebViewCreated: (controller) { newWebController = controller; }, onCloseWindow: (controller) { Navigator.pop(context); }, ), ), ), ); return true; }, onLoadStop: (_, __) async { await _controller.evaluateJavascript(source: ''' window.parent.postMessage(${widget.paymentJsonData}, "*"); '''); }, ), ), ), ); }
验证注意事项
- 确认RazorPay初始化参数无错误,相关域名没有被跨域策略拦截
- iOS端需要确保在Info.plist中添加了对应的网络访问权限,没有禁止测试环境的HTTP请求
内容的提问来源于stack exchange,提问作者Yashwardhan Pauranik
相关产品推荐
相关产品推荐

