nodejs支付宝回调页面

这两天弄支付宝的回调页面,被坑了两天,记录一下。javascript

首先获取请求参数java

//获取参数
let post_param = typeof req.body == 'string' ? req.body.split('&') : [];
for(let val of get_param)
{
    let tmp = val.split('=');
    params[tmp[0]] = decodeURIComponent(tmp[1].replace(/\+/g,'%20'));
}

接着校验是不是支付宝的请求api

//请求来源校验
let options = {
    hostname : 'mapi.alipay.com', 
    path     : `/gateway.do?service=notify_verify&partner=${ALIPAY_ID}&notify_id=${notify_id}`,
    method   : 'GET'
};
let alipay_rt = '';
let req = require('https').request(options, (res) => {
    res.on('data', async (rt) => {
        alipay_rt += rt;
    });
    res.on('end', async (rt) => {
        //校验是不是支付宝的请求
        if(alipay_rt !== 'true')
        {
            reply('faild');return;
        }
    });
});

而后按要求校验签名async

let tmp  = [];
let str  = '';
let keys = Object.keys(param);
keys.sort();//排序
for(let key of keys)
{
    if(key != 'sign' && key != 'sign_type' && param[key])//剔除空值及签名字段
    {
        tmp.push(`${key}=${param[key]}`);
    }
}
str = tmp.join('&');
let publickey = ['-----BEGIN PUBLIC KEY-----\n'];
let i = 0;
while(i < ALIPAY_RSA.length)
{
    publickey.push(ALIPAY_RSA.substring(i,i+64)+'\n');
    i+=64;
}
publickey.push('-----END PUBLIC KEY-----');
return require('crypto').createVerify('RSA-SHA1').update(str).verify(publickey.join(''), sign, 'base64');

以上校验经过后,再检查一下订单信息,就能够更新订单状态了。post

有两点要注意,一是接收参数要解码,这里因为NODEJS把参数中的空格转为了+号,解码前须要把+号替换为%20;二是校验签名前,要把公钥加上开头和结尾标识,还有中间的换行。ui

相关文章
相关标签/搜索