webview里面h5无法唤醒微信支付

将H5网页打包成APK时,在Android的WebView中遇到无法唤醒微信支付的问题。通过重写shouldOverrideUrlLoading方法来解决这个问题。此外,发现开启护眼模式的手机在唤醒支付时可能出现屏幕闪烁,关闭护眼模式可以避免此现象。

背景

因为运营推广问题,需要把原来基于h5的网页打包成一个apk,遇到难题了,ios的没有开发环境,于是就先搞一个安卓的试试,最开始遇到各种问题。

解决方案

重写方法 shouldOverrideUrlLoading
代码位置:
在这里插入图片描述

webview.setWebViewClient(new WebViewClient() {
   
   
            /**
             * 拦截 url 跳转,在里边添加点击链接跳转或者操作
             */
<think>我们正在讨论在App的WebView中正确处理微信H5支付回调的方法。根据提供的引用材料,我们可以总结出以下步骤和注意事项: 核心问题:在WebView中发起H5支付后,支付完成时如何正确返回到App并传递支付结果。 步骤: 1. 生成支付链接时,通过服务端请求微信支付接口,获取mweb_url。 2. 在mweb_url后拼接`redirect_url`参数,该参数是经过URL编码的App自定义URL Scheme(例如:myapp://payresult?orderId=123),用于支付完成后微信跳转回App。 3. 在App的WebView中加载这个拼接后的URL。 4. 配置App的URL Scheme处理,以便在微信支付完成后通过Scheme唤醒App并传递支付结果。 5. 在App中处理Scheme,根据参数更新订单状态或提示用户。 关键点(根据引用材料): - 引用[1]指出,支付页面并不在WebView中加载,也不依赖于调起支付的App(即使杀掉App进程,支付页面依然存在)。因此,我们需要通过回调URL来通知App支付结果。 - 引用[2]提到,在App的WebView中调起H5支付后,支付完成后会返回之前的H5页面,但我们需要的是返回App并关闭支付页面,而不是留在H5页面。 - 引用[3]提供了H5页面的处理示例:在发起支付时,后端返回微信支付链接,前端拼接自定义的redirect_url(即App的Scheme)并跳转。 - 引用[4]和[5]指出,在iOS上支付完成后微信会跳转到Safari,然后通过Scheme跳回App,但可能会遇到白屏或无法返回的问题,需要特殊处理。 具体实现步骤: 一、H5页面处理(前端) 1. 当用户点击支付按钮时,H5页面请求自己的后端,后端调用微信统一下单接口(H5支付)获取mweb_url。 2. 将mweb_url拼接上redirect_url参数,redirect_url的值是自定义的URL Scheme,并包含必要的参数(如订单号),注意需要URL编码。 示例代码(类似引用[3]): ```javascript // 假设后端返回的微信支付链接是 data.mwebUrl let myScheme = 'myapp://payresult?orderId=12345'; // 自定义Scheme,需与App中配置一致 let redirectUrl = encodeURIComponent(myScheme); window.location.href = data.mwebUrl + '&redirect_url=' + redirectUrl; ``` 二、App端处理(Android和iOS) 1. 在WebView中加载上述拼接后的URL,此时会调起微信支付。 2. 配置App的URL Scheme(Android为Intent Filter,iOS为Info.plist),例如:myapp。 3. 在App中处理通过Scheme打开的事件: - Android:在Activity的onNewIntent方法中处理Intent,解析Scheme参数。 - iOS:在AppDelegate的application:openURL:options:方法中处理URL。 三、支付完成后的处理 1. 当用户支付完成(成功/失败)后,微信会跳转到我们设置的redirect_url(即myapp://...),从而唤醒App。 2. 此时,App需要根据URL中的参数(如订单号)去查询支付状态(因为redirect_url跳转并不携带支付结果,所以需要主动查询)。 3. 同时,App需要关闭WebView页面(或跳转到支付结果页),并清除支付中间页。 四、iOS特殊处理(根据引用[4][5]) 问题:支付完成后,微信可能会先跳转到Safari,然后再通过Scheme跳回App,但此时WebView可能已经销毁,导致返回时白屏。 解决方案: 1. 在WebView中发起支付前,记录当前页面的URL(或订单信息)。 2. 支付完成后,通过Scheme唤醒App,App接收到Scheme后,主动刷新WebView(加载支付结果页)或直接关闭WebView。 3. 参考引用[4]:可以通过通知机制强制刷新WebView(例如:支付完成后发送通知,WebView接收到通知后刷新)。 4. 另一种方式:在支付完成后,微信跳转回App,App直接关闭WebView所在的页面,并打开订单详情页面。 五、避免白屏问题(引用[5]) 问题:支付完成后返回App时,WebView显示白屏。 原因:可能是微信支付中间页的历史记录问题(push而非replace)。 解决:在支付完成后,App处理Scheme时,主动关闭WebView或清除历史记录。 完整流程示例: 1. 用户在App的WebView中打开H5订单页。 2. 点击支付按钮,H5请求后端,获得mweb_url。 3. H5拼接redirect_url(包含自定义Scheme和订单参数),并跳转。 4. App的WebView检测到跳转到微信支付链接(mweb_url),允许跳转(注意:需要设置WebView支持跳转外部应用)。 5. 调起微信支付,用户支付。 6. 支付完成后,微信跳转到redirect_url(即myapp://payresult?orderId=12345),此时App被唤醒。 7. App处理该Scheme,根据订单号查询支付结果。 8. App关闭WebView(或导航到支付结果页),同时清除支付中间页(避免用户按返回键又回到支付页)。 注意事项: 1. 自定义URL Scheme需要唯一,且需要在App中注册。 2. 由于支付结果不可靠(用户可能中途退出),建议在App唤醒后主动查询订单状态(调用后端接口)。 3. 对于Android,需要在WebView中设置支持重定向到外部应用(例如:覆盖shouldOverrideUrlLoading方法,检测到微信支付链接则跳转外部浏览器或微信,但这里我们使用H5支付,所以是直接跳转)。 4. 对于iOS,由于平台限制,无法WebView内直接调起微信支付,所以需要允许跳转到外部(微信),支付完成后再通过Scheme跳回。 代码示例(Android WebView设置): ```java webView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { // 如果检测到是微信支付链接(包含mweb_url),则直接跳转 if (url.startsWith("https://wx.tenpay.com") || url.contains("mweb_url")) { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); startActivity(intent); return true; } // 其他链接在WebView内加载 view.loadUrl(url); return true; } }); ``` 注意:在iOS的WebView中,通常也需要类似的处理(如WKWebView的decidePolicyForNavigationAction方法中判断跳转)。 但是,根据引用[1]和[3]的做法,他们并没有直接跳转到外部,而是在WebView中加载支付链接,然后由系统处理(因为支付页面实际上是在独立于App的进程中进行)。因此,我们需要根据实际情况调整。 总结最佳实践: 在App的WebView中加载拼接了redirect_url的支付链接,然后由系统自动处理跳转微信支付,支付完成后通过Scheme唤醒App,App处理Scheme并关闭WebView或跳转到结果页。 相关问题: 1. 如何配置Android和iOS的URL Scheme? 2. 在WebView中如何区分普通链接和微信支付链接? 3. 支付完成后,如何避免WebView出现白屏? </think>### 在App的WebView中正确处理微信H5支付回调的方法 根据引用材料,以下是完整的解决方案(以Android/iOS双平台为例): #### 一、核心处理流程 ```mermaid graph TD A[WebView加载H5支付页] --> B[拼接redirect_url] B --> C[跳转mweb_url支付] C --> D{支付完成} D -->|成功/失败| E[微信跳转redirect_url] E --> F[App捕获URL Scheme] F --> G[关闭WebView/刷新订单] ``` #### 二、具体实现步骤 1. **H5页面发起支付(关键代码参考[^3])** ```javascript // 请求后端获取微信支付mweb_url fetchPayUrl().then(data => { // 拼接App自定义Scheme(需URL编码) const appScheme = 'myapp://payresult?orderId=123'; const redirectUrl = encodeURIComponent(appScheme); // 跳转支付页面(关键!) window.location.href = `${data.mweb_url}&redirect_url=${redirectUrl}`; }); ``` 2. **App端URL Scheme配置** - **Android**:在`AndroidManifest.xml`添加 ```xml <intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> <data android:scheme="myapp"/> </intent-filter> ``` - **iOS**:在`Info.plist`添加 ```xml <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>myapp</string> </array> </dict> </array> ``` 3. **支付回调处理(核心逻辑)** - **Android处理示例**: ```kotlin webView.setWebViewClient(object : WebViewClient() { override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean { if (url.startsWith("myapp://")) { // 1.解析订单参数 val orderId = Uri.parse(url).getQueryParameter("orderId") // 2.关闭WebView(避免白屏[^5]) activity.finish() // 3.查询支付结果并更新UI checkPaymentStatus(orderId) return true } return super.shouldOverrideUrlLoading(view, url) } }) ``` - **iOS处理示例**(Swift): ```swift func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { if url.scheme == "myapp" { // 1.获取订单ID let orderId = url.queryItems?["orderId"] // 2.发送刷新通知(解决白屏[^4]) NotificationCenter.default.post(name: .wxPayCallback, object: orderId) // 3.关闭WebView navigationController?.popViewController(animated: true) return true } return false } ``` 4. **状态同步保障措施** - **双重验证机制**: ```java void checkPaymentStatus(String orderId) { // 方法1:立即查询微信支付接口 weixinApi.queryOrder(orderId); // 方法2:5秒后检查本地订单状态 handler.postDelayed(() -> { if(!orderRepository.isPaid(orderId)) { showPaymentTimeoutAlert(); } }, 5000); } ``` #### 三、关键注意事项 1. **防白屏策略**(引用[^5]) - 支付完成后必须立即关闭WebView - iOS需通过`NotificationCenter`强制刷新页面[^4] - 避免在`redirect_url`中携带敏感参数 2. **支付中断处理** ```mermaid graph LR A[用户中断支付] --> B[微信返回原H5页面] B --> C[添加定时检测器] C -->|每3秒| D[查询订单状态] D -->|已支付| E[自动跳转成功页] D -->|未支付| F[显示继续支付按钮] ``` 3. **多平台适配要点** | 平台 | 核心差异 | 解决方案 | |---------|-----------------------------------|------------------------------| | Android | 可直接关闭WebView | finish()销毁Activity | | iOS | 需处理Universal Link跳转 | 配置Associated Domains | | 小程序 | 需返回原H5页面[^2] | 保持WebView实例不销毁 | > **实测建议**:在支付链接中添加`&force_redirect=true`参数可强制微信优先使用Scheme跳转(微信官方隐藏参数) #### 四、调试技巧 1. **日志埋点**: ```javascript // H5页面添加日志 console.log("[WeixinPay] Redirect to:", redirectUrl); ``` 2. **Android调试命令**: ```bash adb shell am start -a android.intent.action.VIEW -d "myapp://payresult?orderId=test123" ``` 3. **iOS调试方案**: - 在Safari中输入`myapp://payresult`测试Scheme唤醒 - 使用Console.app查看系统日志 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

壬戌知秋

您的打赏将是我最大的鼓励感谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值