微信支付趟坑之旅之单页面应用
年初产品引入了微信支付到现在不到半年的时间,一直没有过太大的坑爹经历,自认为微信支付也能hold住了,没想到上周还是被微信支付团队的同学狠狠的摆了一道。在这里留个记录,希望同入此坑的同学能尽快爬上来。
背景:
上半年上线了商城的微信支付,此项目前端为angularjs 的SPA(single page application,单页面应用)。地址类似于:http://mall.zjkyz8.com/public/page/index.html。微信支付需要配置一个神奇的支付授权目录,你需要将项目中的支付地址置于该配置之下,支付方能成功。所以将该配置设为:http://mall.zjkyz8.com/public/page/。 而实际上由于我们的项目前端使用了angularjs。所以实际的支付地址为http://mall.zjkyz8.com/public/page/index.html#/pay-method/0df8398837。
微信对其支付授权目录的配置规则描述如下:
- 1、所有使用公众号支付方式发起支付请求的链接地址,都必须在支付授权目录之下;
- 2、最多设置3个支付授权目录,且域名必须通过ICP备案;
- 3、头部要包含http或https,须细化到二级或三级目录,以左斜杠“/”结尾。
其中并为对是否允许特殊字符做特别描述(此处特殊字符指#),但实际据客服讲是不允许的,也就是说对SPA,支付目录是无法配置到细化的目录的。不过没关系,这样的配置微信支付是可以正常工作的。目前为止,一切正常。
问题:
下面我们来说说问题是什么。这两天做了个列表页,将一些推广活动放在一起,需求要求用户通过这个列表页点击某个商品也可以完成购买。平衡功能分离与复用后,实现浏览购买流程如下:http://mall.zjkyz8.com/public/page/list.html(列表页) ->http://mall.zjkyz8.com/public/page/list.html#/detail/83984775(商品详情页)->http://mall.zjkyz8.com/public/page/index.html#/create-order/83984775(下单页)->http://mall.zjkyz8.com/public/page/index.html#/pay-method/0df8398837(支付页)。然后神奇的事情发生了:微信支付报错!错误信息为:“当前页面的URL未注册:http://mall.zjkyz8.com/public/page/index.html#/create-order/83984775”.。
分析:
很奇怪,微信错误信息中提及的URL并不是发起支付的页面,而是下单页。更奇怪的是整个下单支付逻辑完全是复用商城中已有逻辑,并未做任何修改,但测试后发现商城中的功能正常。于是通过邮件联系微信支付技术支持(邮件啊,亲,效率那是要多低有多低),客服一口咬定是SPA的中的哈希路由的问题,移除以后就没有问题。虽然我反复强调之前的功能同样带着这部分,但是却可以支付成功,但客服同学完全忽略这个观点,只是不停强调是这个问题。最后事实证明客服的这个说法是正确的,但是原因却让人哭笑不得。
原因:
客服沟通失败,只能靠自己了。折腾了一星期,反复google。最后终于找到原因。文末会添加给了我巨大帮助的一篇文章,感兴趣的小伙伴可以看一下。这个问题的产生实际是两个原因共同作用的结果:
1. 当微信支付被调起时,微信自己会验证当前调起微信支付的页面URL是否与微信支付授权目录匹配。那么何为调起微信支付页面的URL呢,嘿嘿,并不是window.location.href这么简单。这个URL实际是最后一次引起页面刷新的URL。回归到我们的项目,商城端的这个URL实际是http://mall.zjkyz8.com/public/page/index.html,因为只有第一次打开商城时也就是点击了链接后会引起全页面刷新,而之后的所有操作均是SPA内部的路由变换,只会引起哈希变化,页面部分刷新。而新的这个列表页比较复杂,因为有了复用,用户在点击下单后会跳转下单页,即http://mall.zjkyz8.com/public/page/list.html#/detail/83984775(商品详情页)->http://mall.zjkyz8.com/public/page/index.html#/create-order/83984775(下单页),SPA发生了切换,从list.html切换到了index.html,这时候微信会重新获取调起微信支付的页面URL,正好这次变换是带着哈希部分的,所以微信会连着哈希部分一起取过来比较。这正好解释了为什么微信报错的URL不是当前URL。
2. 比较过程就比较有意思了,这部分内容由于无法接触到微信的检查逻辑,所以基本上是自己根据现象猜的,各位小伙伴可以自行选择与理解。大概的逻辑可能是取到URL后用最后一个'/'做分隔符,将URL分为两部分,用第一部分和配置的支付授权目录做比对,匹配则验证成功,否则验证失败。很显然,这种验证方式下,URL分隔后的第一部分会包含哈希,于是验证失败。
解决方案:
既然知道了微信获取支付页面URL不能支持哈希部分,那么想办法把哈希部分干掉。方法很简单粗暴,在#前加个?。哈哈,既然你微信不想支持SPA的哈希,那你总得支持查询参数吧。而且既然不支持哈希,估计也没想着URL中会出现哈希,那么他们的逻辑就会写成在分隔URL前先来步预处理,将查询参数干掉,估计也是简单的用?分隔,取第一部分。
写在最后:
经过验证,这个解决方案是可行的。这也从一个侧面反映出很多人对于URL的理解以及对代码兼容性的理解。URL中的哈希部分并不是一个新的技术。我想如果我换为锚点大家就一定有印象了。这个东西最早被应用于页面内定位到某个DOM节点。后来在SPA中被用来做路由。很显然,微信在做支付功能时完全没有考虑这个技术,虽然我们可以说已经很少使用锚点了。但是单页面应用的普及却在逐步提高。换个角度,我觉得既然查询参数已经能够支持了,那么再支持一个哈希并不是什么困难的事情吧。10分钟的开发时间加半小时的测试时间换来的是对整个SPA的友好支持,应该不吃亏啊。
最后的最后,提出一个我的疑问。我始终无法理解微信支付中授权支付目录的业务价值在哪里。听名字像是尝试解决安全问题。但是整个JSSDK是基于网站域名的,这还不够吗?真诚地希望了解的同学来普及一下。
附上对我帮助巨大的文章地址:http://www.kejik.com/article/152868.html。 不知道为什么chrome访问这个地址,会报有安全隐患,请小伙伴们自行斟酌吧 :) 。
微信支付趟坑之旅之单页面应用相关推荐
- android微信支付坑,微信支付踏坑之旅
其实微信支付的集成步骤也就那么几步,奈何第一次接触无论是微信官方文档还是5+SDK文档都看的晕头转向,于是我换个思路 (以下只针对android app支付功能,服务端为java) 1.首选确定app ...
- 加入域时出现以下错误 登陆失败 该目标账户名称不正确_微信支付踩坑合集:微信小程序支付失败是什么原因?持续更新...
微信小程序开发的过程一定会遇到各种问题,最让人棘手的就是支付问题,因为没有支付做商城类似的小程序就没有办法完成最关键的一步.那么支付失败到底什么原因呢?一下子收集了几个错误类似,希望对你有帮助: No ...
- 微信开发踩坑之旅 之 开发准备及服务器配置
在工作和兴趣的机缘巧合之下,我开始接触微信开发.在这里简单记述自己的微信开发踩坑之旅. 首先,由于本人标准的理工科生,记述的语言有所不足,我尽量说明准确和详细点. 本文记述主线 ·申请公众号 ·公众号 ...
- 微信小程序 通过wx.redirectTo,实现单页面刷新效果 & 下拉刷新页面数据效果
微信小程序 通过wx.redirectTo,实现单页面刷新效果 & 下拉刷新页面数据效果 一: 使用 wx.redirectTo(),实现页面刷新数据效果 API说明: 关闭当前页面,跳转到应 ...
- 微信支付软件架构重构之旅
方秋枋 读完需要 10 分钟 速读仅需 1 分钟 原文链接:https://www.cnblogs.com/imstudy/p/12567241.html 本文原文由微信客户端高级工程师方秋枋原创发表 ...
- 微信支付踩坑血泪史(JAVA -V3版本)
背景介绍 最近第一次接触到微信支付,踩了很多坑,赶紧写下来,全是心酸和眼泪.话不多说.开始展示. 项目中使用的接入方式是JSAPI(参考 产品中心 - 微信支付商户平台),当然也可以使用其他接入方式, ...
- 微信支付的坑 返回值 -1
2019独角兽企业重金招聘Python工程师标准>>> 最近在用android接入微信支付.. 之前的包没问题,发现这段时间突然不行了... 于是调试之. 1.开始用的支付配置参数估 ...
- 微信支付的坑(思路)
获取openid页面刷新:https://bbs.csdn.net/topics/391115929 异步通知验证签名:微信返回xml数据中的sign使用的是HMAC-SHA256加密方法,所以不能使 ...
- app端微信支付(二) - 生成预付单
前一篇文章的时序图中说了,app端调用微信支付必须先由后台调用微信后台生成预付单,再构建参数给手机端,而数据的构建要以xml形式,那么看看代码具体实现吧,代码已经精简过了,自己的业务已经除去,精简的 ...
最新文章
- js调用python脚本_javascript – 如何从NodeJs调用python脚本
- $cfg_dbtype = mysql_多库操作2:终于实现多个数据库操作
- Windows学习总结(6)——MindManager新手入门教程
- python创_Python创建Windows 服务
- C/C++——cmd下丢失mspdb100.DLL解决方法
- kaggle:PUBG Finish Placement Prediction
- asp adodb连接mysql数据库语句_ASP连接MySQL数据库的方法
- 2021年安徽全椒中学高考成绩查询,全椒中学2020届高考记录是这样的!
- 安卓修改大师功能简介
- 苹果电脑怎样禁用首字母自动大写?
- AD(altium designer)15原理图与PCB设计教程(五)——工程编译与报表生成
- 计算机网络基础之互联网总结
- iCCP: cHRM chunk does not match sRGB
- flutter安装及过程中遇到的问题解决
- 使用BIOS进行键盘输入和磁盘读写
- 工具分享--IDM下载工具利器,让下载速度提升一百倍
- Google SEO优化排名常见的三种问题
- 电脑垃圾,怎么清理电脑垃圾 让电脑全面瘦身
- 我们利用计算机解决问题时第一步应该,算法与程序设计综合评价练习题
- 不可多得的WinXP技巧十则(转)