iOS端flutter_inappwebview集成RazorPay支付时新窗口无法弹出
iOS端flutter_inappwebview无法弹出RazorPay支付窗口的解决方法
问题背景
通过Web URL集成RazorPay支付功能,因需求限制未使用官方razorpay_plugin,采用flutter_inappwebview实现WebView。Android端测试模式下可正常弹出支付窗口并展示成功/失败选项,但iOS端无法弹出新窗口加载支付URL。
已在Info.plist中添加ATS配置:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsLocalNetworking</key> <true/> <key>NSAllowsArbitraryLoads</key> <true/> <key>NSAllowsArbitraryLoadsInWebContent</key> <true/> </dict>
相关实现代码:
class SomeScreen extends StatefulWidget { final String url; const SomeScreen({Key? key, required this.url}) : super(key: key); @override _SomeScreenState createState() => _SomeScreenState(); } class _SomeScreenState extends State<SomeScreen> { InAppWebViewController? _webViewController; InAppWebViewController? _webViewPopupController; late String url; final options = InAppWebViewGroupOptions( crossPlatform: InAppWebViewOptions( javaScriptCanOpenWindowsAutomatically: true, javaScriptEnabled: true, useOnDownloadStart: true, useOnLoadResource: true, preferredContentMode: UserPreferredContentMode.MOBILE, useShouldOverrideUrlLoading: true, mediaPlaybackRequiresUserGesture: true, allowFileAccessFromFileURLs: true, allowUniversalAccessFromFileURLs: true), android: AndroidInAppWebViewOptions( supportMultipleWindows: true, ), ios: IOSInAppWebViewOptions( allowsAirPlayForMediaPlayback: true, suppressesIncrementalRendering: true, ignoresViewportScaleLimits: true, selectionGranularity: IOSWKSelectionGranularity.DYNAMIC, isPagingEnabled: true, enableViewportScale: true, sharedCookiesEnabled: true, automaticallyAdjustsScrollIndicatorInsets: true, useOnNavigationResponse: true, allowsInlineMediaPlayback: true, ), ); @override void initState() { super.initState(); url = widget.url; } @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Container( child: InAppWebView( initialUrlRequest: URLRequest(url: Uri.parse(widget.url)), initialOptions: options, onWebViewCreated: (InAppWebViewController controller) { _webViewController = controller; }, iosOnNavigationResponse: (controller, response) async { return IOSNavigationResponseAction.ALLOW; }, onLoadStart: (controller, Uri? uri) { print("Load Started: $uri"); }, onCreateWindow: (controller, createWindowRequest) async { showDialog( context: context, builder: (context) { return AlertDialog( content: SizedBox( width: MediaQuery.of(context).size.width, height: 400, child: InAppWebView( // Setting the windowId property is important here! windowId: createWindowRequest.windowId, initialOptions: options, onWebViewCreated: (InAppWebViewController controller) { _webViewPopupController = controller; }, onLoadStart: (InAppWebViewController controller, Uri? url) { print("onLoadStart popup $url"); }, onLoadStop: (InAppWebViewController controller, Uri? url) { print("onLoadStop popup $url"); }, ), ), ); }, ); return true; }, ), ), ), ); } }
解决方法
1. 开启iOS多窗口支持
在IOSInAppWebViewOptions中明确添加多窗口支持配置,确保JavaScript可以自动打开新窗口:
ios: IOSInAppWebViewOptions( // 保留原有配置项 allowsAirPlayForMediaPlayback: true, suppressesIncrementalRendering: true, ignoresViewportScaleLimits: true, selectionGranularity: IOSWKSelectionGranularity.DYNAMIC, isPagingEnabled: true, enableViewportScale: true, sharedCookiesEnabled: true, automaticallyAdjustsScrollIndicatorInsets: true, useOnNavigationResponse: true, allowsInlineMediaPlayback: true, // 新增以下两项关键配置 supportsMultipleWindows: true, javaScriptCanOpenWindowsAutomatically: true, ),
2. 优化弹窗创建逻辑
调整弹窗的展示时机与布局,确保WebView正确绑定窗口ID,同时添加支付结果的回调处理:
onCreateWindow: (controller, createWindowRequest) async { // 延迟弹窗展示,确保WebView初始化完成 await Future.delayed(const Duration(milliseconds: 100)); showDialog( context: context, barrierDismissible: false, builder: (context) { return AlertDialog( insetPadding: const EdgeInsets.symmetric(horizontal: 10), contentPadding: EdgeInsets.zero, content: SizedBox( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height * 0.7, child: InAppWebView( windowId: createWindowRequest.windowId, initialOptions: InAppWebViewGroupOptions( crossPlatform: InAppWebViewOptions( javaScriptEnabled: true, javaScriptCanOpenWindowsAutomatically: true, useShouldOverrideUrlLoading: true, ), ios: IOSInAppWebViewOptions( supportsMultipleWindows: true, ), ), onWebViewCreated: (InAppWebViewController popupController) { _webViewPopupController = popupController; }, onLoadStop: (controller, url) async { print("弹窗加载完成: $url"); // 检测支付结果URL,关闭弹窗并处理逻辑 if (url != null && (url.toString().contains('success') || url.toString().contains('failure'))) { Navigator.pop(context); // 这里可以添加支付结果的后续处理,比如通知原页面更新状态 } }, ), ), ); }, ); return true; },
3. 补充Info.plist配置
添加RazorPay的URL Scheme支持,确保可以正常唤起相关链接:
<key>LSApplicationQueriesSchemes</key> <array> <string>razorpay</string> </array>
4. 日志调试
在关键回调中添加详细日志,确认弹窗触发与URL加载情况:
onCreateWindow: (controller, createWindowRequest) async { print("触发弹窗创建,请求URL: ${createWindowRequest.request.url}"); // 弹窗代码... },
内容的提问来源于stack exchange,提问作者Agnel Selvan
相关产品推荐
相关产品推荐

