微信小程序支付流程
闲话不多说,先来简单的梳理一下微信小程序的支付流程:
上面呢是一张支付流程图,我们跟句上面的图片来进行讲解:
- 首先用户下单,点击按钮就会去发起一个请求道后端服务器,下单前要进行登录操作,在后台发起一个登录操作。
- 然后由我的后台登录访问到去请求微信的后台,得到一个openId。
- 得到openId之后的话才能去进行支付功能,然后再自己的后台去生成一个商户订单,商户订单要定义:支付类型,金额,我是谁(openId),商户Id,当然在做这个订单的时候还要进行一些加密操作,经过一系列的加密之后他会去把这些作为参数。
- 这里要注意的是微信支付的参数都是用的xml的格式,所以说呢,我们除了要进行一系列的加密操作之后,还要把它转成xml的字符串格式,才能去请求
他的api请求。- 有了这个xml的参数,那我们就可以去发起这个统一支付的api,然后把这个api发送到微信后台的服务器之后,他会判断你这个传的参数有没有问题。
- 如果没有问题的话他会去生成一个订单,生成订单之后他会返回一个订单id,这个订单id呢就是预支付的一个id,你需要把预支付的id相关的信息进行二次加密。
- 然后再返回到用户的这一边来,返回这边的话就说明你这个请求都已经成功了。
- 成功之后的话,你需要去调用微信小程序的wx.pay的api,调用wx.pay的api的话,把传过来的全部带过去,调过去之后他就会由微信小程序的api接口去调取支付的页面,这个支付页面就会显示出来,告诉你需要多少钱,你需要进行支付。
- 如果用户点击支付,这些的话全部都是通过微信的app自己去实现的,然后就会去要求用户去输入密码,或者指纹认证,认证成功就会去扣钱,那么微信后台就会去修改订单的支付状态。
- 那么支付成功之后,我们就会在我们的服务端等待微信的通知,微信这边服务器支付成功之后,他一定会有一个消息通知,通知支付结果的情况,然后我们需要去准备一个接口,这个接口是需要微信服务器能够请求到的一个接口,这个接口就是用来去接收微信支付的结果,如果接收到的是sucess就说明订单已经支付成功了,那这时候就可以再自己的服务器去修改支付的状态,并且如果在页面做一些展示的功能,就可以去做了,这就是整个微信小程序的支付流程!
下图是标记的流程:
详解
一.小程序调用登录接口获取code,传递给商户服务器用来获取用户的openID
我们知道在微信平台中,同一个公众号的openID都是不同的,它是用户身份识别的id,也就是说,我们通过openID来区分不同的用户,这个有微信开发基础的应该都很熟悉。为了知道谁在支付,我们需要先获取当前用户的openid,那么openID应该怎么获取呢?看下图:
小程序调用wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
开发者服务器以code换取 用户唯一标识openid 和 会话密钥session_key。
看不懂吗?不急,听我慢慢解释,这个业务流程大致就是首先你得先在小程序的代码中调用wx.login()来向微信获取到code,拿到了之后把code通过request传给商户服务器,再由商户服务器通过骚操作来跟微信服务器要session_key和openID。
伪代码如下(小程序端):
getToken: function () {
//调用登录接口
wx.login({
success: function (res) {
var code = res.code;
wx.request({
url: 商户服务器接口地址,
data: {
code: code
},
method: 'POST',
success: function (res) {
wx.setStorageSync('token', res.data.token); //存在小程序缓存中
},
fail: function (res) {
console.log(res.data);
}
})
}
})
}
调用这几行代码就可以向跟微信服务器要code,并且将code传到商户服务器中,记住这里最好使用post发送请求,安全性的东西我应该不用讲了,因为避免其他人滥用接口,于是我们使用token来进行验证。并将商户服务器返回的token存在小程序缓存中。
那么服务器端应该怎么做呢?
我门通过小程序提交的code,和小程序的APPID以及APPSECRET和拼接下列的url,并用curl进行get请求。
https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
返回的数据是一个json对象,我门通过使用json_decode(JSON,true)解析为数组,数据包括用户的openID以及session_key,获取到了后我们应该将openID存入数据库中,它代表着用户的身份,那么令牌应该怎么生成呢。
二.token的生成以及缓存
我们根据一个用户表将id和openid联系起来,对应openID的id则是用户的uid,我们可以这么封装
//要缓存的数据数组
$cacheValue = $result; //包含openID和session_key
$cacheValue['uid'] =$uid; //用户id
$cacheValue['scope'] =ScopeEnum::User; //用户权限级别
缓存的方式我们可以选择redis,memcache, 文件缓存等等,采用键值对(key-value)的方式进行存储,记得设置好过期时间。这里的key我们用token来赋值,token可以通过这样的方式进行生成:
//获取32位随机字符串
$str = getRandChar(32); //自定义方法生成32位随机串
//三组字符串进行md5加密
$timeStamp =$_SERVER