UNPKG

rapid-swiftpass

Version:

SwiftPass module

179 lines (163 loc) 5.38 kB
/** * 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'); /** * 根据商户订单号查询订单信息 * * 参数: * dest_url: 威富通服务地址 * params: JSON,包含下列的 keys: * pay_type: 支付方式,见下 * merno: 威富通平台内商户编号 * sign_key: 威富通商户签名密钥 * order_id: 平台内订单号,32 字符内,唯一 * amount: 交易金额,单位为分 * notify_url: 接收平台通知的 URL * front_url: 交易完成后跳转 URL(可选) * openid: 微信用户关注商家公众号的 openid,或者买家支付宝 userid * appid: 微信公众号 APPID * * 支付方式(pay_type)取值如下: * weixin: 微信支付 * alipay: 支付宝 * tenpay: QQ钱包 * jdpay: 京东支付 * * 返回: * 成功返回: { * reqt: 请求报文 * resp: 响应报文 * succ: true * pay_info: 支付信息 * token_id: 平台生成的预支付ID * pay_url: 支付链接 * } * 失败返回: { * reqt: 请求报文 * resp: 响应报文 * succ: false * errmsg: 错误信息 * } */ const exchange = async (dest_url, params) => { if (!dest_url || !params) { throw new Error('JS支付请求参数无效'); } const required = [ 'pay_type', 'merno', 'sign_key', 'order_id', 'amount', 'notify_url' ] for (let i = 0; i < required.length; i++) { if (!params[required[i]]) { throw new Error(`JS支付请求缺少字段[${required[i]}]`); } } const supported_type = [ 'weixin', 'alipay', 'tenpay', 'jdpay' ] if (supported_type.indexOf(params.pay_type) < 0) { throw new Error(`支付方式[${params.pay_type}]无效`); } let reqt_json = { service: `pay.${params.pay_type}.jspay`, version: '2.0', charset: 'UTF-8', sign_type: 'MD5', time_start: moment().format('YYYYMMDDHHmmss'), time_expire: moment().add(60, 'minutes').format('YYYYMMDDHHmmss'), nonce_str: crypto.randomBytes(16).toString('hex'), 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, } fix_reqt_by_pay_type(params, reqt_json); reqt_json.sign = utils.gen_sign(reqt_json, params.sign_key); winston.info('威富通JS支付请求报文:', 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('威富通JS支付响应报文:', JSON.stringify(resp_json, null, 2)); if (!utils.verify_sign(resp_json, params.sign_key)) { throw new Error('验证威富通JS支付响应报文签名失败'); } winston.info('验证威富通JS支付响应报文签名通过'); if (parseInt(resp_json.result_code) != 0) { return { reqt: reqt_json, resp: resp_json, succ: false, errmsg: resp_json.err_msg || '交易失败' } } let result = { reqt: reqt_json, resp: resp_json, succ: true, } fix_resp_by_pay_type(resp_json, params.pay_type, result); return result; } /** * 根据支付方式补充请求参数 */ const fix_reqt_by_pay_type = (params, reqt_json) => { if (params.pay_type == 'alipay') { if (!params.openid) { throw new Error(`请求缺少[openid]字段`); } reqt_json.buyer_id = params.openid; return; } if (params.front_url) { reqt_json.callback_url = params.front_url; } if (params.pay_type == 'weixin') { reqt_json.is_raw = '1'; reqt_json.is_minipg = '0'; if (!params.appid) { throw new Error(`请求缺少[appid]字段`); } if (!params.openid) { throw new Error(`请求缺少[openid]字段`); } reqt_json.sub_appid = params.appid; reqt_json.sub_openid = params.openid; } } /** * 根据支付方式设置响应数据 */ const fix_resp_by_pay_type = (resp_json, pay_type, result) => { if (pay_type == 'alipay') { result.pay_info = resp_json.pay_info; result.pay_url = resp_json.pay_url; return; } if (pay_type == 'weixin') { result.pay_info = resp_json.pay_info; result.token_id = resp_json.token_id; return; } if (pay_type == 'tenpay') { result.pay_info = resp_json.pay_info; result.token_id = resp_json.token_id; return; } if (pay_type == 'jdpay') { result.pay_info = resp_json.pay_info; result.token_id = resp_json.token_id; result.pay_url = resp_json.pay_url; return; } } module.exports = { exchange: exchange, }