rapid-swiftpass
Version:
SwiftPass module
88 lines (83 loc) • 2.41 kB
JavaScript
/**
* Copyright (c) 2017 Lucky Byte, Inc.
*/
const debug = require('debug')('swiftpass');
const winston = require('winston');
const crypto = require('crypto');
const xml2js = require('xml2js');
/**
* 生成报文签名
*
* 参数:
* reqt_json: 请求报文
* key: 签名密钥
* 返回:
* 报文签名数据
*/
const gen_sign = (reqt_json, sign_key) => {
if (!reqt_json || !sign_key) {
throw new Error('生成威富通请求报文签名参数无效');
}
let input = [];
Object.keys(reqt_json).sort().forEach((key) => {
if (reqt_json[key] == null || reqt_json[key] === '') {
throw new Error(`请求报文字段[${key}]无效`);
}
if (key != 'sign') {
input.push(`${key}=${reqt_json[key]}`);
}
});
input.push(`key=${sign_key}`);
return crypto.createHash('md5').update(input.join('&'), 'utf-8')
.digest('hex').toUpperCase();
}
/**
* 验证报文签名
*
* 参数:
* resp_json: 响应报文
* sign_key: 签名密钥
* 返回:
* true: 签名通过
* false: 签名不通过
*/
const verify_sign = (resp_json, sign_key) => {
if (!resp_json || !sign_key) {
throw new Error('验证威富通响应报文签名参数无效');
}
if (!resp_json.sign) {
throw new Error('威富通响应报文缺少 sign 字段,验证签名失败');
}
return gen_sign(resp_json, sign_key) == resp_json.sign;
}
/**
* 解析响应数据
*
* 参数:
* resp_xml: 响应数据,XML 字符串
* 返回:
* 响应报文,JSON
*/
const parse_resp_xml = async (resp_xml) => {
return new Promise((resolve, reject) => {
const parser = new xml2js.Parser({
trim: true, explicitRoot: false, explicitArray: false,
});
parser.parseString(resp_xml, (err, result) => {
if (err) {
return reject(err);
}
if (parseInt(result.status) != 0) {
winston.error('威富通错误响应:', JSON.stringify(result, null, 2));
return reject(new Error(result.message || result.status ||
'响应报文缺少 status 字段'));
}
return resolve(result);
});
});
}
module.exports = {
gen_sign: gen_sign,
verify_sign: verify_sign,
parse_resp_xml: parse_resp_xml,
}