node 网站调用支付宝支付 全程记录。
该遇到的坑,我觉得都遇到了,整个过程不算太顺,也没花多少时间。
1.找接口
这个容易,上蚂蚁金服开发平台,所有的注册什么的 都注册成功后。
https://docs.open.alipay.com/api_1/alipay.trade.pay
在该网站找到在线支付的接口。参数里面写的很全/
2.签名
使用工具生成公钥和私钥,公钥上传到蚂蚁金服的网站上。
let signer = crypto.createSign('RSA-SHA256') //rsa2
signer.update(_r)//_r 待签名的字符串
let _s = signer.sign(_privateKey, 'base64'); //_privateKey 私钥
在node 端 如果使用私钥
需要在开头添加一行—–BEGIN RSA PRIVATE KEY—–
在结尾添加 一行 —–END RSA PRIVATE KEY—–
产生签名后,再拿出待签名字段放在工具里,填上私钥,发现产生的签名和程序的不一样!!!
经过一番查找,,你妹的,待签名的参数排序的问题,顺序没排对��。
3.发送请求
我第一感觉是用node发送https 请求。(不要问为什么)
先用的是post ,发现返回的是 html (好吧,我已经发现该接口是 前端直接访问拼接好的url 即可,但是发现返回的是乱码,编码格式GB2312,平时爬虫没遇到过,正好试一下。)
使用的是iconv-lite 这个模块。我使用的是 原始的https 请求,自己封装的。所以使用方法是,先把 res.setEncoding(‘utf8’)控制编码的语句删掉。如此处理后,请求到的数据返回的是以二进制的形式,然后使用 let decodeHtmlData = iconv.decode(chunk,'gb2312')
然后我把参数和地址拼成一个url ,输入浏览器回车。
签名错误 不过还好支付宝把待签名的字符串给返回了,我比较了一下,
找到了问题,支付宝签名 除了排序,还需要使用 =和& 序列化,我比较懒直接使用的querystring模块。这个模块会把字符串直接进行url编码,然而签名时 不需要进行url 编码,然后就自己随便写了一个拼接的函数,因为是些demo 没写的那么严谨,也没写排序,因为我是按顺序添加的
function wjoin(par) {
let a = '';
for (let i in par) {
par[i]&&(a = a + i + '=' + par[i] + '&');
}
return a.slice(0, a.length - 1)
}
再次尝试,直接ok
4.验签
接收到支付宝的异步通知后,需要做的就是验签。不验签 谁知道这接口是谁通知你的。 需要接受阿里的异步通知 需要post 接口。
验签的函数crypto 里面有,网上一搜也是很多。
let verify = crypto.createVerify('RSA-SHA256');
verify.update(strp, 'utf8');
let result = verify.verify(_publishKey, sign, 'base64');
ps. 公钥需要添加
需要在开头添加一行—–BEGIN PUBLIC KEY—–
在结尾添加 一行 —–END PUBLIC KEY—–
本来我以为是—–BEGIN RSA PUBLIC KEY—– //-_-
然后只返回了个 false ,
用工具再试了一次,也是验证失败。
我试了很多次。查了N 多个文档。
最后 我发现 需要的是 支付宝公钥,而不是之前我们自己生成的公钥。
当我知道了这个东西后,我狠狠的说了一句 *
ps. 如果按我这个教程,还不能解决您的问题的话,可以留言。