如何绕过微信或支付宝的H5支付的拦截验证?下面我们从本质上来说明该如何解决这个问题。

微信和支付宝的H5支付下单成功后都会返回一个跳转支付的url连接,通过这个连接可以拉起微信或支付宝进行支付操作。

如果直接访问,支付宝会有一个中间的页面,而微信有个麻烦的refresh验证问题;那么是否可以跳过这个步骤直接将微信支付宝拉起进行支付呢?

网上大部分的教程都是让做安卓和IOS的自己去拦截微信和支付宝的地址进行处理。但是对这种内嵌网页,特别是那种直接通过前端HTML代码生成多端的情况,前端的同学就非常不好操作了; 那么这个活就需要后端的同学辛苦哈来解决了(ง •_•)ง。

首先需要知道的是每一个手机APP都有一个唯一的URL Scheme地址,访问这个地址即可将对应的APP打开。基于这个原理,那么微信和支付宝的支付最终肯定也是基于此来实现将其APP拉起然后让用户进行支付的。

因此让后端对支付地址处理下,直接返回可以拉起微信和支付宝的支付URL Scheme;这样就可以直接用了,微信的refresh验证也可以跳过了。

首先是微信H5支付

通过程序直接请求微信H5支付下单返回的支付链接,返回如下(下面是返回的部分html代码):

在Html代码中有以weixin://开头的链接;而weixin://正好是微信的URL Scheme,这个就是之后调用微信支付的链接,在手机浏览器上打开这个链接正好可以调起微信支付进行支付。
说明微信在这个页面上并没有做其他的骚操作,那些Referer拦截只是一些简单的前台拦截。那么我们通过后端程序直接去请求微信返回H5支付链接,然后将返回的HTML中的微信支付URL Scheme提取出来直接返回给前端即可。

下面是Java示例代码

HttpHeaders headers = new HttpHeaders();
headers.add("Host", "wx.tenpay.com");
headers.add("Accept-Language", "en, zh-CN; q=0.8,zh; q=0.6,en-US; q=0.4");
headers.add("Accept", "text/html,application/xhtml+xml, application/xml ; g=0. 9 ,image/webp,*/* ; q=0.8");
headers.add("Upgrade-Insecure-Requests", "1");
// 这个地方写你自己在微信支付后台配置的安全域名
headers.add("Referer", "https://www.baidu.com");
HttpEntity<String> httpEntity = new HttpEntity<>(headers);try{// 使用spring的 RestTemplate; mweb_url是微信的H5支付链接ResponseEntity<String> exchange = this.restTemplate.exchange(mweb_url, HttpMethod.GET, httpEntity, String.class);String body = exchange.getBody();if(StringUtils.isBlank(body)){System.out.println("请求无响应");return url;}// 通过正则表达式提取需要的字符串String pattern= "\"weixin(.*?)\"";Pattern p = Pattern.compile(pattern);Matcher matcher = p.matcher(body);if(matcher.find()){String pullUrl = matcher.group();return pullUrl.substring(1, pullUrl.length()-1);}
}catch (Exception e){System.out.println("请求异常");
}
return url;

需要注意的是使用这种方式就不要再将回跳地址传入了,同时需要自己做个是否支付成功的判断;也就是说在支付成功后我们的页面是不会自动回跳的,因此需要让前端的同学辛苦处理哈;比如弄个支付确认弹窗让用户主动点击,或者是定期去轮询几次订单状态,同时如果不条支付中间页那么最好把支付按钮暂时禁用了,免得由于网络延迟这些问题导致重复支付的问题。

其实去查看微信支付宝的HTML页面,你会发现它们的就是通过简单的js来直接跳转的

支付宝H5支付

基于刚才微信的思路,使用同样的方式来处理支付宝的。支付宝返回的HTML内容中没有现成的支付宝支付的URL Scheme。通过调试和HTML代码分析,提取出其支付URL Scheme如下:

# 安卓的(实际测试中,苹果手机使用这个也可以拉起支付宝,可以直接使用一个)
alipays://platformapi/startApp?appId=102564&orderSuffix=' + o.android + '#Intent;scheme=alipays;package=com.eg.android.AlipayGphone;end
# 苹果的
alipay://alipayclient/?o.ios

其中o.ios和o.android的内容是使用url encoder编码了的;其中苹果的内容是如下的JSON串:

{"requestType": "SafePay","fromAppUrlScheme": "alipays","dataString": "h5_route_token=\"FPwoiehfPAWuiofw\"&is_h5_route=\"true\"&need_invoke_app=\"true\""
}

安卓的只有一个dataString的值。通过字段的值对比h5_route_token其值就是HTML中的session的值;在返回的HTML代码中有如下代码:

    var inData = { "requestType": "SafePay", "fromAppUrlScheme": "alipays", "dataString": "h5_route_token=\"FPwoiehfPAWuiofw\"&is_h5_route=\"true\"&need_invoke_app=\"true\"" };

这个就是上面需要的内容,同样通过正则表达式将inData的值提取出来,然后手动来拼接这个支付的URL Scheme。

下面是Java示例代码:

HttpGet httpGet = new HttpGet(h5Url);
httpGet.setConfig(RequestConfig.custom().setConnectTimeout(HttpConstants.CONNECT_TIMEOUT).setConnectionRequestTimeout(HttpConstants.CONNECTION_REQUEST_TIMEOUT).setSocketTimeout(HttpConstants.SOCKET_TIMEOUT).build());CloseableHttpClient httpClient = HttpClientBuilder.create().build();
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {if(response.getEntity()!=null){String body = EntityUtils.toString(response.getEntity(), "UTF-8");// 通过正则表达式提取需要的字符串;也可以直接提取session的值 `pattern = "'session':(.*)'";`String pattern= "inData =(.*)";Pattern p = Pattern.compile(pattern);Matcher matcher = p.matcher(body);if(matcher.find()){String pullUrl = matcher.group();if(pullUrl.length()>9){pullUrl = pullUrl.substring(9, pullUrl.length()-1);// 这个isAndroid值是让前端同学传入的,如果不想区分可以直接就用安卓的这个支付链接;因为苹果端的用这个链接也可以拉起支付宝支付if(isAndroid){JSONObject params = JSONObject.parseObject(pullUrl);if(params.getString("dataString")!=null){pullUrl = params.getString("dataString");// 安卓return String.format("alipays://platformapi/startApp?appId=549984&orderSuffix=%s#Intent;scheme=alipays;package=com.eg.android.AlipayGphone;end", URLEncoder.encode(pullUrl, "utf-8"));}}else {// isoreturn String.format("alipay://alipayclient/?%s", URLEncoder.encode(pullUrl.trim(), "utf-8"));}}}System.out.println("请求返回内容:"+ body);}else {System.out.println("无请求内容返回");}
} catch (IOException e) {System.out.println("处理异常");
}finally {try {httpClient.close();} catch (IOException e) {e.printStackTrace();}
}
return null;

这种方式对原生的APP开发应该也适用,即不使用微信支付宝的APP支付方式,直接使用H5的支付方式,这样就无需再去对接其APP支付的SDK了,同时也跳过了微信支付中麻烦的验证问题了。

关注微信订阅号‘起岸星辰’获取最新资讯

APP内嵌网页使用微信或支付宝的H5支付相关推荐

  1. 移动端app内嵌网页开发框架

    框架技术栈 之前开发过一个项目,app内嵌网页应用使用Antd mobile + React + mobx + webpack的技术栈来开发.记录一下对于移动端开发中特殊的一些点: 自适应布局 我们在 ...

  2. iphone app内嵌网页高度100%问题(底部有白条)

    蓝色div,紫色body(高度均为100%)黑色fixed定位bottom:0 .发现元素无法填满,定位也到不了底部.百思不得其解.在一整天的 调试过后,终于发现了奥秘 首先,你的页面meta标签要设 ...

  3. 使用Chrome开发者工具调试Android端内网页(微信,QQ,UC,App内嵌页等)

    使用Chrome开发者工具调试Android端内网页(微信,QQ,UC,App内嵌页等) 传送门 转载于:https://www.cnblogs.com/momozjm/p/9389912.html

  4. 微信小程序与内嵌网页交互实现支付功能

    上个月,小程序开放了新功能,支持内嵌网页,所以我就开始了小程序内嵌网页之路,之前我只是个小安卓. 内嵌网页中可使用JSSDK 1.3.0提供的接口,可坑就来了,居然不支持支付接口的调用,经过一番研究, ...

  5. 微信小程序,实现内嵌网页的分享

    自从微信小程序支持内嵌网页之后,呼声高涨得不得了.的确,这个确实让我开发我们公司的小程序高效了很多,主要是可以引入现有的功能完整的普通网页. 需求是这样子的:小程序启动授权等操作成功后直接跳转到内嵌网 ...

  6. 微信小程序与H5内嵌网页交互实现地图定位功能

    小程序中有很多好用的API,整个项目我们是用vue实现的,使用小程序的内嵌网页功能完成交互. 使用小程序的< web-view >标签将vue项目在小程序中运行.大概的背景就是这样.接下来 ...

  7. 【愚公系列】2022年09月 微信小程序-webview内嵌网页的授权认证

    文章目录 前言 一.webview内嵌网页的授权认证 1.内嵌页面 2.登录页面 二.web端相关函数 1.判断是否是小程序环境 前言 随着微信小程序的广泛应用,小程序的用户越来越多,但受其小程序体积 ...

  8. 记录:app内嵌H5页面分享到微信后,在安卓手机打开白屏,苹果手机正常渲染的问题始末

    **背景:**app内嵌的一个个人名片页面需要分享到微信,测试环境下,分享到微信后,安卓和苹果手机都能正常渲染,生产环境苹果手机没问题,安卓手机打开分享的链接,页面一直空白. **原因分析:**单独加 ...

  9. 微信小程序内嵌webview实现微信登录

    一.调研场景 1, 微信小程序内嵌webview实现微信登录 二.技术实现 1. web-view标签实现链接内嵌 小程序里嵌套web-view页面 (1)src属性:webview 指向网页的链接. ...

最新文章

  1. Nginx热部署详解
  2. Silicon Labs收购业界RTOS厂商
  3. python中time模块常用功能
  4. source insight设置tab键为4个空格
  5. VTK:Filtering之ConstrainedDelaunay2D
  6. C++Adaline自适应线性神经网络算法(附完整源码)
  7. LeetCode OJ:Construct Binary Tree from Preorder and Inorder Traversal(从前序以及中序遍历结果中构造二叉树)...
  8. 爬虫小案例:基于Bing关键词批量下载图片
  9. 浅谈事理图谱认知:系统体系+领域收敛+人机协同+辅助范式
  10. 替换分隔符 ^p, 或者是回车
  11. 对于algorithm102的总结
  12. jQuery动画之显示隐藏动画
  13. Qt 启动应用程序的3种方式
  14. 1.什么是NoSql数据库?
  15. 小鑫の日常系列故事(一)——判断对错 (sdut oj)
  16. WPS如何打开pdf目录
  17. 第二章第三题(将英尺转换为米)(convert feet to meters)
  18. 验证码2020最新最实用的验证码
  19. spark graphx实现共同好友的聚合
  20. JVM垃圾回收——G1垃圾收集器

热门文章

  1. python题目-----计算时针分针夹角
  2. SOFA Weekly|MOSN v1.3.0 版本发布、公众号半自助投稿、本周 Contributor QA
  3. 零基础学UI设计难不难?
  4. 视频编码器效率评价标准:BDPSNR和BDBR
  5. C# DPI适配问题
  6. 教学用计算机示教仪器包括哪些,浙江省普通_高中通用技术教学器材.doc
  7. 微型计算机硬件系统中 最常用的输出设备是,微型计算机硬件系统中,最常用的输出设备是()。...
  8. 亲身经历告诉你,美团外卖通用红包cdk的套路骗局(附被骗全过程)
  9. 【uniapp前端组件】自定义车牌键盘
  10. (原創) 04/11/1984 サザン・ウインド (中森明菜)