安卓非微信内置浏览器中的网页调起微信支付的方案研究

问题来源

之前在app中集成过微信支付,此种微信支付方式为app支付,即在我们自己的应用中嵌入微信支付SDK,由Native代码调起微信支付。

后来由于业务需要在我们app的WebView中打开第三方店铺的网页,在第三方网页中有微信支付按钮,测试反馈说ios可以调起微信支付,而android不可以。后来网上看到说微信内置Webview和京东的网页也可以调起微信支付,微信自己没什么奇怪的,而京东可以的话,如果它跟微信没什么合作协议的话,那么其他app应该也可以在网页中调用微信支付。

探索

由于ios可以支持,因此找ios同事测试了一下,发现ios内置浏览器中只要输入相关协议都可以调起相关app的,比如:
1. 输入weixin:// 可以调起微信
2. 输入alipay:// 可以调起支付宝

这样就不难解释为什么ios的webview中第三方网页可以调起微信支付了,但android在浏览器中输入上述协议,没有任何响应。因此本文主要探讨是基于android平台的。

后来终于找到微信支付|商户平台开发者文档,作为客户端开发者,是不会想到这个开发文档的,当时集成app支付的时候所查阅的文档也未提到H5支付的方式。在文档的使用场景介绍中有这么一段:

H5支付是基于公众号基础开发的一种非微信内浏览器支付方式(需要单独申请支付权限),可以满足在微信外的手机H5页面进行微信支付的需求。同时,由于H5链接传播十分方便、来源不易追踪,商户需要特别注意做好防钓鱼、防刷单的处理,控制风险。

由此看来,确实官方是支持在非微信内置浏览器中调起微信支付的。

在文档中,微信给了一个官方的测试链接:http://wxpay.weixin.qq.com/pub_v2/pay/wap.v2.php,在手机浏览器中打开该页面,点击“立即购买”,就可以调起微信支付,我测试了Nexus手机的Chorme浏览器和Sony手机的自带浏览器,均可以。具体效果如下图:

这里写图片描述这里写图片描述

通过查看网页源代码,发现“立即购买”是一个按钮,其连接点击协议是这样的:

href="weixin://wap/pay?appid%3Dwx2421b1c4370ec43b%26noncestr%3D3e84679af4efab5f32ee9ea01b2ec290%26package%3DWAP%26prepayid%3Dwx20160504154919fdacd7bc0d0127918780%26timestamp%3D1462348159%26sign%3DC40DC4BB970049D6830BA567189B463B"

瞬间觉得非常熟悉,以前集成app支付的关键代码是这样的:

IWXAPI api;
PayReq request = newPayReq();
request.appId = "wxd930ea5d5a258f4f";
request.partnerId = "1900000109";
request.prepayId="1101000000140415649af9fc314aa427",;
request.packageValue = "Sign=WXPay";
request.nonceStr="1101000000140429eb40476f8896f4c9";
request.timeStamp="1398746574";
request.sign="7FFECB600D7157C5AA49810D2D8F28BC2811827B";
api.sendReq(req);
上述a链接里的协议就是app支付里面的各种参数,因此可以得到结论,weixin://wap/pay是微信定义的一种支付协议,用于网页端支付,微信app必定设置了名为weixin://的scheme,因此可以在网页上唤起微信app,在通过约定的参数名称,获取各种参数,从而可以完成支付,具体机制跟app支付是相同的。至于上面一系列参数,是第三方网页端跟微信那边获取的,均由第三方服务端处理,客户端不必关心。

知道了以上原理,就该讨论解决方案了,下面有几种可行的方案。

解决方案1

上面可知,微信的H5支付协议可以在浏览器中调起微信,这也是最简单的方案。如果我们的app打开第三方网页用的是手机浏览器的话,就不用做什么,直接可以调起微信支付了。按微信文档所说,应该大部分浏览器都支持,我只是简单测试了两款。

解决方案2

第一种方案固然简单,但事实上我们往往使用WebView来打开第三方网页,而不是手机浏览器,因此如何让WebView也支持调起微信支付才是核心问题。经过测试发现,原生WebView是可以唤起微信支付的,核心代码如下:

webView = newWebView(this);
webView.getSettings().setJavaScriptEnabled(true); 
webView.loadUrl("http://wxpay.weixin.qq.com/pub_v2/pay/wap.v2.php");
</code>


对,就这样简单就OK了。

然而往往我们的app中使用自定义的WebView,经测试发现如果为WebView设置了WebViewClient,如下:

webView.setWebViewClient(newWebViewClient() {
    // some logic
}

那么就不能唤起微信支付了,errorCode返回-10,提示“不支持该协议”。联系到可以在浏览器中唤起微信支付,因此我的解决方案如下,经测试是可以的。

webView.setWebViewClient(newWebViewClient() {  
        @Override 
        publicbooleanshouldOverrideUrlLoading(WebView view, String url) {  
            // 如下方案可在非微信内部WebView的H5页面中调出微信支付
            if(url.startsWith("weixin://wap/pay?")) {
                Intent intent = newIntent();
                intent.setAction(Intent.ACTION_VIEW);
                intent.setData(Uri.parse(url));
                startActivity(intent);
 
                returntrue;
            }
            returnsuper.shouldOverrideUrlLoading(view, url);
        }
 
        @Override
        publicvoidonPageFinished(WebView view, String url) {
            // TODO Auto-generated method stub              
            super.onPageFinished(view, url);
        }
 
        @Override
        publicvoidonReceivedError(WebView view, interrorCode,
                String description, String failingUrl) {
            // TODO Auto-generated method stub              
            super.onReceivedError(view, errorCode, description, failingUrl);
        }           
 
    });

第二种解决方案的效果图如下,注意使用了WebView打开的网页:

这里写图片描述这里写图片描述

解决方案3

跟前两种方案相比,第三种就算直接暴力了。结合之前嵌入SDK的app支付方式,我们可以在WebView里拦截H5的支付协议,从上述协议中取出各个参数,完全可以走微信APP支付的方式了。可以发现H5的支付协议中唯独少了partnerId,partnerId指商户ID,在注册微信支付时都会有。至于为什么没有商户id,猜测一是为了安全,另外第三方自家的网页,当然已知partnerId了(如京东的网页,京东在微信的商户id当然知道的),就没必要放到协议中去。

如果我们的app知道第三方的partnerId的话,这样就能拿到所有参数的话,理论上完全可以转走app支付的方式,具体我没有测试,有兴趣的可以试一下。

<think>好的,用户的问题是关于如何修改微信内置浏览器的设置或者切换默认浏览器。首先,我需要确认微信内置浏览器本身是否允许用户自行修改设置或切换默认浏览器。根据已有的知识,微信内置浏览器是基于腾讯的X5内核,普通用户通常无法直接修改其核心设置,比如默认浏览器切换。 接下来,用户可能的需求是什么?用户可能希望在微信中点击链接时,自动跳转到手机的其他浏览器,比如Chrome或Safari,以便下载应用或访问某些被微信限制的页面。根据引用内容,微信会拦截下载链接,导致无法直接下载,这时候需要跳转到外部浏览器。 现在需要整理现有的解决方案。引用3提到了使用Mindjump的API接口生成跳转链接,这种方法可以绕过微信的限制,让用户自动跳转到默认浏览器。另外,引用5也提到了类似的技术方案,可能涉及中间页面的处理,比如通过用户点击按钮触发跳转,或者服务器端检测User-Agent来引导用户。 需要注意的是,微信官方并不鼓励绕过其内置浏览器的行为,所以这些方法可能有一定的风险,比如链接被微信封禁。此外,iOS和Android的处理方式不同,iOS可能需要引导用户通过Safari打开,而Android可以直接跳转到默认浏览器。 用户的问题中还提到修改微信内置浏览器的设置,但根据现有信息,用户无法直接修改微信内置浏览器设置。因此,回答需要明确说明这一点,并重点提供间接方法,比如生成跳转链接或使用中间页面。 最后,需要验证这些方法的可行性和最新情况,因为微信的政策和技术可能会变化。确保提供的解决方案是目前有效的,比如Mindjump的API是否仍然可用,或者是否有其他替代服务。</think>### 如何实现微信内置浏览器跳转默认浏览器微信内置浏览器默认无法直接修改其核心设置或切换默认浏览器,但可通过以下方法间接实现跳转需求: --- #### **1. 通过中间跳转链接(推荐)** 利用第三方服务生成跳转链接,绕过微信拦截: - **操作步骤**: 1. 使用工具如[Mindjump](http://www.mindjump.cn)生成跳转链接[^3]。 2. 将生成的链接或二维码分享至微信。 3. 用户点击后,系统自动判断设备类型: - **iOS**:直接打开App Store或跳转Safari下载。 - **Android**:自动启动默认浏览器访问目标页面[^3]。 --- #### **2. 技术方案(需开发能力)** 通过检测浏览器标识(User-Agent)实现跳转: - **代码示例(PHP/JavaScript)**: ```javascript // 判断是否为微信内置浏览器 function isWeixinBrowser() { const ua = navigator.userAgent.toLowerCase(); return ua.indexOf('micromessenger') !== -1; } // 若是微信环境,提示用户用浏览器打开 if (isWeixinBrowser()) { window.location.href = "https://跳转中间页地址"; // 替换为中间页URL } ``` **中间页逻辑**: - 显示提示信息(如“点击右上角用浏览器打开”)[^5]。 - 或通过页面重定向引导外部浏览器访问[^2]。 --- #### **3. 平台差异处理** - **iOS系统**: - 企业签名包可直接在微信内下载。 - App Store链接需通过跳转中间页触发[^1]。 - **Android系统**: - 直接跳转默认浏览器访问目标页面。 --- #### **注意事项** - 微信可能更新拦截策略,需定期测试跳转功能。 - 避免使用敏感关键词(如“下载”)降低被封风险。 - 用户需手动授权地理位置等权限[^4]。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值