coa-allin-pay
Version:
通联支付SDK for Node.js
169 lines (168 loc) • 6.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AllinPayBin = void 0;
const coa_error_1 = require("coa-error");
const coa_helper_1 = require("coa-helper");
const crypto_1 = require("crypto");
const querystring = require("querystring");
const padding = crypto_1.constants.RSA_PKCS1_PADDING;
class AllinPayBin {
constructor(config) {
// 触发事件过长的阈值
this.thresholdTooLong = 2 * 1000;
this.config = config;
}
// 发送service_soa请求
async service_soa(service, method, param) {
// 组装参数并请求
const params = await this.getParams({ service, method, param });
// 请求并记录开始、结束时间
const startAt = Date.now();
const res = await coa_helper_1.axios.get(this.config.endpoint + '/service/soa', { params, paramsSerializer: (params) => querystring.stringify(params) });
const endAt = Date.now();
// 触发请求事件
this.onRequest(params, res.data);
// 触发请求时间过长事件
if (endAt - startAt > this.thresholdTooLong) {
this.onRequestTooLong(params, res.data, { startAt, endAt });
}
// 处理结果
try {
return this.handleResult(res);
}
catch (e) {
// 触发请求错误事件
this.onRequestError(params, res.data, e);
throw e;
}
}
// 发送允许部分异常的service_soa请求
async service_soa_allow(service, method, param, allow, data = {}) {
// 处理异常结果
return await this.service_soa(service, method, param).catch(e => {
if (e.mark !== allow)
throw e;
return coa_helper_1._.assign(param, data, { allow });
});
}
// 获取gateway_url
async gateway_url(url, service, method, param) {
// 组装参数并返回
const params = await this.getParams({ service, method, param });
return this.config.endpoint + url + '?' + querystring.stringify(params) + '&';
}
// 加密字段中信息
param_encrypt(param, fields) {
fields.forEach(k => {
const value = coa_helper_1._.get(param, k);
if (value)
coa_helper_1._.set(param, k, this.rsa_encrypt(value));
});
}
// 解密字段中信息
param_decrypt(param, fields) {
if (param.allow)
return;
fields.forEach(k => {
const value = coa_helper_1._.get(param, k);
if (value)
coa_helper_1._.set(param, k, this.rsa_decrypt(value));
});
}
// 华通银行签名
bank_signer(PAYEE_ACCT_NO, PAYEE_ACCT_NAME, AMOUNT, SUMMARY = '') {
const str = JSON.stringify({
AMOUNT,
PAYEE_ACCT_NAME,
PAYEE_ACCT_NO,
SUMMARY,
});
return (0, crypto_1.createSign)('rsa-sha1').update(str, 'utf8').sign(this.config.bankPrivateKey, 'base64');
}
// 获取数据 rps
getData(result) {
// 解析结果
try {
return JSON.parse(result.rps);
}
catch (e) {
coa_error_1.die.hint('支付系统:返回结果解析失败');
}
}
// 获取校验后的数据 rps
getVerifyData(result) {
// 校验签名
const md5_str = (0, crypto_1.createHash)('md5')
.update(result.sysid + result.rps + result.timestamp)
.digest('base64');
const verify = (0, crypto_1.createVerify)('rsa-sha1')
.update(md5_str, 'utf8')
.verify(this.config.allinPublicKey, result.sign, 'base64');
verify || coa_error_1.die.hint('支付系统:返回结果校验失败');
return this.getData(result);
}
// 推送返回记录
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onBackReceive(body) { }
// 请求记录
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onRequest(param, response) { }
// 请求失败
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onRequestError(param, response, error) { }
// 请求时间过长
onRequestTooLong(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_param,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_response,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
time) { }
// 敏感信息加密
rsa_encrypt(data) {
const key = this.config.allinPublicKey;
return (0, crypto_1.publicEncrypt)({ key, padding }, Buffer.from(data)).toString('hex').toUpperCase();
}
// 敏感信息解密
rsa_decrypt(hexStr) {
const key = this.config.privateKey;
return (0, crypto_1.privateDecrypt)({ key, padding }, Buffer.from(hexStr, 'hex')).toString();
}
// 结果验签
handleResult(res) {
const data = res.data || {};
// console.log('res.data %j', data)
// 判断结果是否正确
if (data.status !== 'OK') {
coa_error_1.die.hint('支付系统提示:' + data.message, 400, data.errorCode);
}
// 校验签名(有签名才校验)
if (data.sign) {
const md5_str = (0, crypto_1.createHash)('md5').update(data.signedValue).digest('base64');
const verify = (0, crypto_1.createVerify)('rsa-sha1')
.update(md5_str, 'utf8')
.verify(this.config.allinPublicKey, data.sign, 'base64');
verify || coa_error_1.die.hint('支付系统:返回结果校验失败');
}
// 解析结果
try {
return JSON.parse(data.signedValue);
}
catch (e) {
coa_error_1.die.hint('支付系统:返回结果解析失败');
}
}
// 请求参数
getParams(request) {
const sysid = this.config.sysId;
const v = '2.0';
const req = JSON.stringify(request);
const timestamp = coa_helper_1.$.datetime();
// 计算签名
const source_str = `${sysid}${req}${timestamp}`;
const md5_str = (0, crypto_1.createHash)('md5').update(source_str).digest('base64');
const sign = (0, crypto_1.createSign)('rsa-sha1').update(md5_str, 'utf8').sign(this.config.privateKey, 'base64');
return { sysid, v, timestamp, sign, req };
}
}
exports.AllinPayBin = AllinPayBin;