微信公众号支付开发-JSSDK

最近微信网页开发要用到公众平台支付的功能,过程中坑不少。

引入js

在需要调用JS接口的页面引入如下JS文件
(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js

通过config接口注入权限验证配置
1
2
3
4
5
6
7
8
9
wx.config({
// 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
debug: true,
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名,
jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表
});
JS-SDK使用权限签名signature算法:

想要使用JSSDK必须要进行权限签名验证,和支付签名(paySign)不是一个东西!!

  1. 通过APPID和APPSECRET获取access_token
    https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

    1
    {"access_token":"ACCESS_TOKEN","expires_in":7200}
  2. 生成jsapi_ticket
    用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket
    https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

    1
    2
    3
    4
    5
    6
    {
    "errcode":0,
    "errmsg":"ok",
    "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
    "expires_in":7200
    }

需要注意access_token 和jsapi_ticket有效期均为7200s,jsapi_ticket每天限制2000次请求,所以服务端必须进行缓存。

  1. 生成signature
    签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
    即signature=sha1(string1)。 示例:
    1
    2
    3
    4
    noncestr=Wm3WZYTPz0wzccnW
    jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
    timestamp=1414587457
    url=[http://mp.weixin.qq.com?params=value](http://mp.weixin.qq.com/?params=value)

步骤1. 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:

1
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW&timestamp=1414587457&url=http://mp.weixin.qq.com?params=value

步骤2. 对string1进行sha1签名,得到signature:
0f9de62fce790f9a083d5c99e95740ceb90c27ed

调用JSSDK支付功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
wx.chooseWXPay({
// 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
timestamp: 0,
nonceStr: '', // 支付签名随机串,不长于 32 位
package: '', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
signType: '', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
paySign: '', // 支付签名
success: function (res) {
//res返回信息只有errMsg并没有err_msg,都是自己开调试模式,log出来的!都是泪
// 支付成功后的回调函数
}
cancel: function (res) {
// 支付取消的回调函数
}
error: function (res) {
// 支付失败的回调函数
}
});

注意啊!注意啊!这里取消和失败的回调要这么写!!可是官方开发文档上并没有啊!!

下面这种写法是官方给出的,但是这是处理JSSDK权限验证时config信息验证失败的回调!

1
2
3
wx.error(function(res){
});

还有需要注意的是,js上调起支付timestamp是小写,而服务端做签名时候timeStamp中’S’必须大写!
服务端做签名的时候一定要注意参数大小写和顺序问题,以及服务端和js参数要保持一致。

真心想吐槽微信公众平台开发文档!心好累!码农何苦为难码农!