.NET MAUI iOS端Safari自动唤起Paystack脚本问题求助
解决.NET MAUI集成Paystack时iOS端被Safari接管的问题
核心问题分析
iOS的WKWebView默认会将新窗口导航请求重定向到Safari,而Paystack的inline.js在检测到无法弹出内联模态框时,会自动触发跳转至Safari打开支付页面。Android端的WebView支持内联弹窗,因此功能正常。
解决方案
1. 移除HTML中固定的脚本引用
先删除HTML里的<script src="https://js.paystack.co/v2/inline.js"></script>,避免页面加载时自动触发脚本逻辑导致iOS跳转。
2. 自定义iOS WebView配置,允许内联弹窗
通过MAUI的Handler机制修改iOS的WKWebView配置,阻止跳转并允许内联弹窗:
创建自定义WebView Handler:
using Microsoft.Maui.Handlers; using WebKit; namespace YourAppNamespace; public class CustomWebViewHandler : WebViewHandler { protected override void ConnectHandler(WKWebView platformView) { base.ConnectHandler(platformView); // 允许内联内容弹窗 platformView.Configuration.AllowsInlineMediaPlayback = true; // 配置导航委托拦截跳转 platformView.NavigationDelegate = new PaystackNavigationDelegate(); } } public class PaystackNavigationDelegate : WKNavigationDelegate { public override void DecidePolicy(WKWebView webView, WKNavigationAction navigationAction, Action<WKNavigationActionPolicy> decisionHandler) { // 拦截Paystack相关链接,强制在WebView内打开 if (navigationAction.Request.Url?.AbsoluteString.Contains("paystack.co") == true) { decisionHandler(WKNavigationActionPolicy.Allow); } else { base.DecidePolicy(webView, navigationAction, decisionHandler); } } }
在MauiProgram.cs中注册该Handler:
builder.ConfigureMauiHandlers(handlers => { #if IOS handlers.AddHandler<WebView, CustomWebViewHandler>(); #endif });
3. 按需动态注入Paystack脚本
不在HTML中预加载脚本,而是在用户触发支付操作时,通过JSRuntime动态注入脚本并调用支付初始化函数:
private async Task TriggerPaystackPayment() { // 替换为你的WebView控件实例 var paymentWebView = this.PaymentWebView; var paystackConfig = new { Key = "YOUR_PAYSTACK_PUBLIC_KEY", Email = "user@example.com", Amount = 10000, // 单位为Kobo,10000 = 100 NGN Reference = Guid.NewGuid().ToString() }; await paymentWebView.EvaluateJavaScriptAsync($@" // 动态创建脚本标签 const script = document.createElement('script'); script.src = 'https://js.paystack.co/v2/inline.js'; script.onload = function() {{ // 初始化Paystack弹窗 PaystackPopUp({{ key: '{paystackConfig.Key}', email: '{paystackConfig.Email}', amount: {paystackConfig.Amount}, reference: '{paystackConfig.Reference}', onSuccess: function(res) {{ // 支付成功后通过自定义Scheme通知MAUI端 window.location.href = 'paystack://success?ref=' + res.reference; }}, onCancel: function() {{ window.location.href = 'paystack://cancel'; }} }}); }}; document.head.appendChild(script); "); }
4. 配置自定义URL Scheme处理支付回调(可选)
为了在支付完成后从WebView回调到MAUI应用,可配置自定义URL Scheme:
- 在iOS项目的
Info.plist中添加:
<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>paystack</string> </array> </dict> </array>
- 在MAUI的
App.xaml.cs中监听回调:
protected override void OnStart() { base.OnStart(); Microsoft.Maui.Events.EventHandlers.OnAppLinkRequestReceived += (sender, e) => { var uri = e.Uri; if (uri.Scheme.Equals("paystack", StringComparison.OrdinalIgnoreCase)) { switch (uri.Host) { case "success": var reference = uri.QueryParameters["ref"]; // 处理支付成功逻辑 break; case "cancel": // 处理支付取消逻辑 break; } } }; }
关键注意事项
- 动态注入脚本确保只有在用户主动触发支付时才加载Paystack逻辑,避免iOS提前触发跳转。
- iOS端必须通过NavigationDelegate拦截Paystack链接,强制在WebView内打开,阻止Safari接管。
- Android端无需额外配置,动态注入脚本后即可正常弹出内联支付窗口。
内容的提问来源于stack exchange,提问作者noetico
相关产品推荐
相关产品推荐

