APP内嵌网页使用微信或支付宝的H5支付
如何绕过微信或支付宝的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支付相关推荐
- 移动端app内嵌网页开发框架
框架技术栈 之前开发过一个项目,app内嵌网页应用使用Antd mobile + React + mobx + webpack的技术栈来开发.记录一下对于移动端开发中特殊的一些点: 自适应布局 我们在 ...
- iphone app内嵌网页高度100%问题(底部有白条)
蓝色div,紫色body(高度均为100%)黑色fixed定位bottom:0 .发现元素无法填满,定位也到不了底部.百思不得其解.在一整天的 调试过后,终于发现了奥秘 首先,你的页面meta标签要设 ...
- 使用Chrome开发者工具调试Android端内网页(微信,QQ,UC,App内嵌页等)
使用Chrome开发者工具调试Android端内网页(微信,QQ,UC,App内嵌页等) 传送门 转载于:https://www.cnblogs.com/momozjm/p/9389912.html
- 微信小程序与内嵌网页交互实现支付功能
上个月,小程序开放了新功能,支持内嵌网页,所以我就开始了小程序内嵌网页之路,之前我只是个小安卓. 内嵌网页中可使用JSSDK 1.3.0提供的接口,可坑就来了,居然不支持支付接口的调用,经过一番研究, ...
- 微信小程序,实现内嵌网页的分享
自从微信小程序支持内嵌网页之后,呼声高涨得不得了.的确,这个确实让我开发我们公司的小程序高效了很多,主要是可以引入现有的功能完整的普通网页. 需求是这样子的:小程序启动授权等操作成功后直接跳转到内嵌网 ...
- 微信小程序与H5内嵌网页交互实现地图定位功能
小程序中有很多好用的API,整个项目我们是用vue实现的,使用小程序的内嵌网页功能完成交互. 使用小程序的< web-view >标签将vue项目在小程序中运行.大概的背景就是这样.接下来 ...
- 【愚公系列】2022年09月 微信小程序-webview内嵌网页的授权认证
文章目录 前言 一.webview内嵌网页的授权认证 1.内嵌页面 2.登录页面 二.web端相关函数 1.判断是否是小程序环境 前言 随着微信小程序的广泛应用,小程序的用户越来越多,但受其小程序体积 ...
- 记录:app内嵌H5页面分享到微信后,在安卓手机打开白屏,苹果手机正常渲染的问题始末
**背景:**app内嵌的一个个人名片页面需要分享到微信,测试环境下,分享到微信后,安卓和苹果手机都能正常渲染,生产环境苹果手机没问题,安卓手机打开分享的链接,页面一直空白. **原因分析:**单独加 ...
- 微信小程序内嵌webview实现微信登录
一.调研场景 1, 微信小程序内嵌webview实现微信登录 二.技术实现 1. web-view标签实现链接内嵌 小程序里嵌套web-view页面 (1)src属性:webview 指向网页的链接. ...
最新文章
- Nginx热部署详解
- Silicon Labs收购业界RTOS厂商
- python中time模块常用功能
- source insight设置tab键为4个空格
- VTK:Filtering之ConstrainedDelaunay2D
- C++Adaline自适应线性神经网络算法(附完整源码)
- LeetCode OJ:Construct Binary Tree from Preorder and Inorder Traversal(从前序以及中序遍历结果中构造二叉树)...
- 爬虫小案例:基于Bing关键词批量下载图片
- 浅谈事理图谱认知:系统体系+领域收敛+人机协同+辅助范式
- 替换分隔符 ^p, 或者是回车
- 对于algorithm102的总结
- jQuery动画之显示隐藏动画
- Qt 启动应用程序的3种方式
- 1.什么是NoSql数据库?
- 小鑫の日常系列故事(一)——判断对错 (sdut oj)
- WPS如何打开pdf目录
- 第二章第三题(将英尺转换为米)(convert feet to meters)
- 验证码2020最新最实用的验证码
- spark graphx实现共同好友的聚合
- JVM垃圾回收——G1垃圾收集器
热门文章
- python题目-----计算时针分针夹角
- SOFA Weekly|MOSN v1.3.0 版本发布、公众号半自助投稿、本周 Contributor QA
- 零基础学UI设计难不难?
- 视频编码器效率评价标准:BDPSNR和BDBR
- C# DPI适配问题
- 教学用计算机示教仪器包括哪些,浙江省普通_高中通用技术教学器材.doc
- 微型计算机硬件系统中 最常用的输出设备是,微型计算机硬件系统中,最常用的输出设备是()。...
- 亲身经历告诉你,美团外卖通用红包cdk的套路骗局(附被骗全过程)
- 【uniapp前端组件】自定义车牌键盘
- (原創) 04/11/1984 サザン・ウインド (中森明菜)