rapid-swiftpass
Version:
SwiftPass module
93 lines (85 loc) • 2.97 kB
JavaScript
/**
* Copyright (c) 2017 Lucky Byte, Inc.
*/
const debug = require('debug')('swiftpass');
const crypto = require('crypto');
const moment = require('moment');
const winston = require('winston');
const utils = require('../lib/utils');
const post = require('../lib/post');
/**
* 微信 APP 支付下单
*
* 参数:
* dest_url: 威富通服务地址
* params: JSON,包含下列的 keys:
* appid: 商户APP对应的微信开发平台移动应用 appid
* merno: 威富通平台内商户编号
* sign_key: 威富通商户签名密钥
* order_id: 平台内订单号,32 字符内,唯一
* amount: 交易金额,单位为分
* notify_url: 接收平台通知的 URL
*
* 返回:
* 成功返回: {
* reqt: 请求报文
* resp: 响应报文
* succ: true
* token: 支付授权码
* }
*/
const exchange = async (dest_url, params) => {
if (!dest_url || !params) {
throw new Error('微信APP支付请求参数无效');
}
const required = [
'appid', 'merno', 'order_id', 'amount', 'notify_url', 'sign_key'
]
for (let i = 0; i < required.length; i++) {
if (!params[required[i]]) {
throw new Error(`微信APP支付请求缺少字段[${required[i]}]`);
}
}
let reqt_json = {
service: 'pay.weixin.raw.app',
version: '2.0',
charset: 'UTF-8',
sign_type: 'MD5',
nonce_str: crypto.randomBytes(16).toString('hex'),
time_start: moment().format('YYYYMMDDHHmmss'),
time_expire: moment().add(60, 'minutes').format('YYYYMMDDHHmmss'),
appid: params.appid,
mch_id: params.merno,
out_trade_no: params.order_id,
body: `订单${params.order_id}`,
total_fee: parseInt(params.amount),
mch_create_ip: '127.0.0.1',
notify_url: params.notify_url,
}
reqt_json.sign = utils.gen_sign(reqt_json, params.sign_key);
winston.info('威富通微信APP支付请求报文:', JSON.stringify(reqt_json, null, 2));
const resp_data = await post(dest_url, reqt_json);
const resp_json = await utils.parse_resp_xml(resp_data);
winston.info('威富通微信APP支付响应报文:', JSON.stringify(resp_json, null, 2));
if (!utils.verify_sign(resp_json, params.sign_key)) {
throw new Error('验证威富通微信APP支付响应报文签名失败');
}
winston.info('验证威富通微信APP支付响应报文签名通过');
if (parseInt(resp_json.result_code) != 0) {
return {
reqt: reqt_json,
resp: resp_json,
succ: false,
errmsg: resp_json.err_msg || '交易失败'
}
}
return {
reqt: reqt_json,
resp: resp_json,
succ: true,
pay_info: resp_json.pay_info,
};
}
module.exports = {
exchange: exchange,
}