微信支付做了有一定时间了,现在就来做一些知识的总结,总体来说微信支付的文档不是非常的完美,其中存在一些问题。虽然坑很多,但是还是把问题解决了。
微信支付的收货地址共享功能,主要是统一的管理微信用户个人的收货地址,其收货地址可以被应用于所有可以调用的开发者。用户的收货地址包含了很多个人信息,因此该接口必须要通过申请,申请的方式可以在mp平台上查看到。
申请开通
包含微信支付功能时,则需要配置微信的支付目录(支付目录为绝对路径,例如支付接口为wxpay.php,而该文件在wxpay目录下,那么支付目录必须写成http://test.mc.com/wxpay),配置该目录权限时候需要添加“可编辑和拉取共享地址”权限,这样开发者可以在该授权目录拉取共享收货地址。其次需要修改用户的oauth授权域名,将其域名修改为相应的授权目录的域名即可。例如我的授权目录是http://test.mc.com/wxpay/,那么oauth的授权域名则为test.mc.com。
接口开发
在开发前首先得去验证一下权限是否正确,因此你需要使用如下的demo,该demo可以帮助你验证目录权限是否正确,如果demo未跑通,则说明权限存在问题。
Demo校验权限
将demo解压,并将代码部分放到你的授权目录(请注意这里是代码部分,非addrdemo文件夹),修改配置文件config.php,将你所需的配置填写完整,修改完成后,使用微信访问连接:授权目录/addr.php
如果demo正常拉取的话,接下来你就可以进行正常逻辑的开发了。
共享收货地址开发
在开发前首先要明确拉取共享收货地址需要的参数配置,如下:
appId已知参数,scope(默认参数jsapi_address),signType (默认参数sha1),addrSign(需要生成参数),timeStamp(加密和解密所需参数),nonceStr(加密解密所需参数)。
通过简单分析,我们可以看出,需要我们生成的就是一个addrSign值,而这个值依赖与timeStamp和nonceStr,因此在给微信的参数中的timeStamp和nonceStr必须要和加密生成addrSign的值完全一致。
addrSign的生成过程,官网提供的例子是存在缺漏的,但是并不影响整个的生成方式,其介绍说:
addrSign 的生成规则如下。参与addrSign 签名的字段包括:appId、url(当前网页url)、timestamp、noncestr、accessToken(用户授权凭证,请参照oauth2.0 协议获取)。这里scope、signType 并不参与签名。
1、对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL 键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。
要注意的是所有参数名均为小写字符,例如appId 在排序后字符串则为appid。这里的意思很明确的表示参与的所有字段的键名必须是小写。
2、对string1作签名算法,字段名和字段值都采用原始值,不进行URL 转义,签名算法为addrSign = SHA1(string1)。
很多时候大家看到官网提供的加密后字符与字符串的sha1结果不符合,其实大家不要在意,也不要存在疑惑是否是因为自己的sha1加密算法和微信的不一致。官网提供的例子是存在问题的。
实际举例如下
1、加密字符串
appid=wx17ef1eaef46752cb
url=http://open.weixin.qq.com/
timestamp=1384841012
noncestr=123456
accesstoken=OezXcEiiBSKSxW0eoylIeBFk1b8VbNtfWALJ5g6aMgZHaqZwK4euEskSn78Qd5pLsfQtuMdgmhajVM5QDm24W8X3tJ18kz5mhmkUcI3RoLm7qGgh1cEnCHejWQo8s5L3VvsFAdawhFxUuLmgh5FRA
注意以上参数中的url,这个url为你需要拉起收货地址的调用页面,注意这个url必须与调用页面的url完全一致,包含参数。其中微信要求参与签名使用的url必须带上微信服务器返回的code和state参数,因此访问页面也必须携带两个参数,例如我们的加密url是:
http://test.mc.com/wxpay/addr.php?code=123&state=cft
那么我们拉取收货地址的页面http://test.mc.com/wxpay/addr.php也必须携带两个参数,也就是访问页面需要设置为http://test.mc.com/wxpay/addr.php?code=123&state=cft。
2、经过排序后的字符串
accesstoken=OezXcEiiBSKSxW0eoylIeBFk1b8VbNtfWALJ5g6aMgZHaqZwK4euEskSn78Qd5pLsfQtuMdgmhajVM5QDm24W8X3tJ18kz5mhmkUcI3RoLm7qGgh1cEnCHejWQo8s5L3VvsFAdawhFxUuLmgh5FRA&appid=wx17ef1eaef46752cb&noncestr=123456×tamp=1384841012&url=http://open.weixin.qq.com/
3、加密生成addrSign
addrSign=SHA1(accesstoken=OezXcEiiBSKSxW0eoylIeBFk1b8VbNtfWALJ5g6aMgZHaqZwK4euEskSn78Qd5pLsfQtuMdgmhajVM5QDm24W8X3tJ18kz5mhmkUcI3RoLm7qGgh1cEnCHejWQo8s5L3VvsFAdawhFxUuLmgh5FRA&appid=wx17ef1eaef46752cb&noncestr=123456×tamp=1384841012&url=http://open.weixin.qq.com/)=382aba817fa72b01fe8029a3b4020862
那么这些过程中你会遇到哪些问题呢?
1、微信提示拒绝访问
授权目录错误,请确认自己的授权目录是否为绝对路径,或者是否申请开通授权目录。
2、拉取收货地址提示fail,第一种情况
这个很多时候是签名出错,签名出错又包含以下几个错误
A)签名参数必须小写,也就是说你的签名参数名存在大写的。
B)加密所使用的token信息为用户oauth时候所返回的token信息,并非官号的token
C)参与签名使用的url必须带上微信服务器返回的code和state参数,这部分就是要保证拉起收货地址的页面url必须要与加密生成签名的url完全一致。其次,签名使用的url必须是调用时所在页面的url,此url域名要不填写Oauth2.0授权域名一致。
3、拉取收货地址提示fail,第二种情况
A)调用接口参数必须用字符串格式,主要是timeStamp和nonceStr两个值,必须要保证是字符串格式;
B)传递给微信的timeStamp和nonceStr必须是参与生成addrSign签名的值;