原文:https://blog.niceue.com/front-end-development/wechat-h5-payment-process-as-well-as-some-pits.html

最近做的 SPA 网站集成了微信支付,使用的是微信 H5 调起支付API接口。做完后对微信 H5 支付的流程有了进一步的了解,在前后端调试接口的过程中也遇到了一些问题,在这里记录下来。

支付流程

  1. 在订单页 ajax 请求后端发起下单,后端挂起请求
  2. 后端根据订单号结合微信支付相关配置参数向微信服务器发起统一下单
  3. 下单成功,微信通知前面传递的 notify_url,返回 prepay_id (预支付交易会话标识)
  4. 后端返回前端 JSAPI 调用的参数
  5. 前端使用 JSSDK 的 wx.chooseWXPay 发起支付
wx.chooseWXPay({
timestamp: '', // 支付签名时间戳
nonceStr: '', // 支付签名随机串
package: '', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
signType: 'MD5', // 签名方式
paySign: '', // 支付签名
})

这里看起来是 5 步,但其实还少了一步。调用“统一下单”接口的时候需要微信用户的 openid。

openid 是什么?

官方解释

加密后的微信号,每个用户对每个公众号的 openid 是唯一的。对于不同公众号,同一用户的 openid 不同

这个 openid 只能在微信环境通过重定向拿到。但是在下单的时候用的是 ajax 请求,还用重定向用户体验就比较差。所以需要在进入微信的时候就通过重定向拿到 openid 缓存起来,后面就可以直接使用了。所以入口页面就要做点小动作。

获取 openid

官方有OpenID的获取指引。对于 H5 应用,获取方式分 3 步走:

1. 后端重定向到获取 code 接口

后端可以定义一个 /wechat/redirect 接口,例如:

http://yoursite.com/wechat/redirect?url=home_url 

用这个地址重定向获取 code 地址,其中的 url 参数为最终的重定向地址,在拿到 openid 后跳转到该 url

2. 获取 code:

接口地址

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirec

接口参数:

  • appid: 公众账号ID
  • redirect_uri: 接收 code 的回调地址(请UrlEncode)
  • response_type: 固定值 code
  • scope: 应用授权作用域,填 snsapi_base 或者 snsapi_login(可获取用户信息,如头像、昵称等)
  • state: 用于保持请求和回调的状态,防止 csrf 攻击,可设置为简单的随机数加 session 进行校验

提示:snsapi_login 会跳转到授权页让用户授权
微信接着会重定向三次,第三次重定向返回到 redirect_uri 地址,并且带上了 code 参数

3. 通过 code 获取 openid 和 access_token

接口地址

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

获取到 openid 后注意在 session 中缓存起来

一些需要注意的坑

1. 获取 code 的接口地址

OpenID的获取指引文档,请注意黑色标题“微信公众平台”和“微信开放平台”。两个地方获取 code 的接口地址不一样,但参数是一样的。最开始后端看错了文档使用的是“网站应用微信登录”文档里面提供的获取 code 的接口,这样子怎么都是调不通的。

// 微信公众平台是
https://open.weixin.qq.com/connect/oauth2/authorize
// 微信开放平台是
https://open.weixin.qq.com/connect/qrconnect

2. 后端签名用 timeStamp,而前端调用支付接口使用全小写 timestamp

微信官方网页端调起支付API这个接口文档参数却误导观众,写的是驼峰的 timeStamp
后端为了方便返回给前端的也是 timeStamp,所以在前端需要转换
解决办法:

if (!data.timestamp) data.timestamp = data.timeStamp

3. iOS 和 Android 版微信对“支付授权目录”的检测不同

http://yousite.com/mobile/#!/checkout

以上路径,iOS 微信识别正确:http://yousite.com/mobile/
而 Android 微信识别出的目录是:http://yousite.com/mobile/#!/checkout
这应该是 Android 版微信的 Bug
解决办法是在 # 前添加一个 ?http://yousite.com/mobile/?#!/checkout

微信 H5 支付流程以及一些坑的更多相关文章

  1. ***新版微信H5支付技术总结(原创)

    新版微信H5支付官方文档: https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_20&index=1 H5支付是指商户在微信客户端外 ...

  2. 微信支付之微信H5支付(坑,ajax不支持重定向跳转)

    这里讲的是  微信h5支付,    是微信以外的手机浏览器调用微信h5支付  h5支付: H5支付是指商户在微信客户端外的移动端网页展示商品或服务,用户在前述页面确认使用微信支付时,商户发起本服务呼起 ...

  3. 微信H5支付坑一--手续费未结算

    简单随笔小记: 场景:在微信H5支付的过程中,无论怎么支付完成,在微信商户后台查询手续费依然未扣除,当时手续费账户月为5元. 解决方法:起初无论怎么测试都不知道代码到底问题出在哪里了,想一下手续费账户 ...

  4. 微信H5支付 遇到坑的一些解决方法

    解决办法 1. 商家参数格式有误,请联系商家解决 a.对于前后端分离的开发模式 前端发起请求 服务端请求微信h5支付统一下单接口 返回参数mweb_url 给前端 然后前端调起微信h5支付 b.注意的 ...

  5. 微信公众号支付|微信H5支付|微信扫码支付|小程序支付|APP微信支付解决方案总结

    最近负责的一些项目开发,都用到了微信支付(微信公众号支付.微信H5支付.微信扫码支付.APP微信支付).在开发的过程中,在调试支付的过程中,或多或少都遇到了一些问题,今天总结下,分享,留存. 先说注意 ...

  6. PHP微信H5支付开发

    近来公司项目要求用到微信H5开发,因为微信开发文档处处都是坑,我也走了不少弯路,现在就把H5支付的过程记录一下,已备后用!! 首先 先去商户平台申请开通 H5支付!!!! 我们从微信官方下载H5支付d ...

  7. 黄聪:详解申请微信h5支付方法,开通微信h5网页支付接口(转)

    版权声明:图文并茂的微信小程序教程!欢迎转载,请保留作者名字和链接:商业合作请联系子恒老师助理 QQ : 2334512685 https://blog.csdn.net/towtotow/artic ...

  8. 详解申请微信h5支付方法,开通微信h5网页支付接口(转)

    现在大街小巷的商家都在使用微信支付,但是一些商家使用的是个人微信收款,这个虽然很便利,但是如果你想要数据统计汇总,让客户在网络上在线付款,就需要用到微信的h5支付. 微信h5支付 今天子恒老师跟你分享 ...

  9. 解决iOS微信H5支付跳转微信后不返回App问题(Swift-WKWebview)(转)

    问题分析 正常的H5支付流程如下 按照上面的支付流程会出现 App -> 微信 -> 支付 -> 点击 完成 -> safari访问redirect_url设置的URL,这种流 ...

随机推荐

  1. UWP忽略短时间内重复触发的事件

    原链接:UWP忽略短时间内重复触发的事件 - 超威蓝火 做移动端开发的可能都会遇到这种需求,当用户点击一个按钮之后,由于没有异步,或者设备性能很差等等原因,程序卡住了.但是用户不知道是咋回事啊,就开始 ...

  2. [转]kaldi中的特征提取

    转:http://blog.csdn.net/wbgxx333/article/details/25778483 本翻译原文http://kaldi.sourceforge.net/feat.html ...

  3. python pickle模块的使用/将python数据对象序列化保存到文件中

    # Python 使用pickle/cPickle模块进行数据的序列化 """Python序列化的概念很简单.内存里面有一个数据结构, 你希望将它保存下来,重用,或者发送 ...

  4. React.js 三周 -- 入门到搭建团队基础项目

    吐槽 公司自己的产品,由于历史遗留问题,前端一直是和java放到一个项目里写的. 导致了,前端就被死死的绑在了IDEA战车上.想要看页面效果,先起几个java服务.想要调试一个改动,重启个java服务 ...

  5. JDBC连接池原理、自定义连接池代码实现

    首先自己实现一个简单的连接池: 数据准备: CREATE DATABASE mybase; USE mybase; CREATE TABLE users( uid INT PRIMARY KEY AU ...

  6. linux系统学习方法分享

    初学者可以自己安装虚拟机,然后把 linux 常用命令例如 cd.ls.chmod.useradd.vi 等等多练习几十遍,把自己敲打命令的熟练程度提升上来.然后根据文档搭建 Linux 下常见的各种 ...

  7. 【sping揭秘】22、事务管理

    有关事务的楔子 什么是事务??? 事务就是以可控的方式对数据资源进行访问的一组操作. 事务本身持有四个限定属性 原子性,一致性,隔离性,持久性 事务家族 Resource Manager  RM,负责 ...

  8. Flask源码复习之路由

    构建路由规则 一个 web 应用不同的路径会有不同的处理函数,路由就是根据请求的 URL 找到对应处理函数的过程. 在执行查找之前,需要有一个规则列表,它存储了 url 和处理函数的对应关系.最容易想 ...

  9. Git 强制回退到某个历史版本再推送到远程

    1. 使用 git log 命令历史版本记录回退版本 git reset --hard f6a7c803a6931a9eca011d4e097389e0845cbe49 2. 推送到远程 git pu ...

  10. 【Promise】Promise实现请求超时处理(加强版)

    昨天闲来无事,于是把之前写过的promise优化了一下,代码如下: /*写文件.追加写.读文件*/ var fs = require('fs'); function wrapper(fn,contex ...