UNPKG

rapid-swiftpass

Version:

SwiftPass module

93 lines (85 loc) 2.97 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'); /** * 微信 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, }