'use strict'; const IOrder = require('./wx_ipay'); const util = require('../utils/util'); // 支付 class Pay extends IOrder { constructor({ appid, mch_id, partner_key, pfx }) { super({ appid, mch_id, partner_key, pfx }); } // 初始化参数 请求 async init(params, name, properties) { this._otherParams(params); this._checkOptions(properties); this._xml = this._jsontoxml(); const result = await this._request(name, this._xml); return result; } // md5加密 暴露给外部调用 md5(params) { return this._md5(params); } // HMAC-SHA256 加密 暴露给外部调用 hmac(params) { return this._hmac(params); } // xml 转json 暴露给外部调用 xmltojson(data) { return this._xmltojson(data); } // 统一下单 async unifiedorder(params) { // 必传参数 const properties = ['body', 'out_trade_no', 'total_fee', 'spbill_create_ip', 'notify_url', 'trade_type']; if (params.trade_type === 'JSAPI') properties.push('openid'); if (params.trade_type === 'NATIVE') properties.push('product_id'); if (params.trade_type === 'MWEB') { properties.push('scene_info'); properties.push('redirect_url'); }; const result = await this.init(params, 'unifiedorder', properties); const { prepay_id, return_code, return_msg, result_code } = result; if (return_code !== 'SUCCESS' || result_code !== 'SUCCESS') return result; // 参数处理 let _data = {}; switch (this._params.trade_type) { case 'JSAPI': _data['appId'] = this._params.appid; _data['timeStamp'] = `${parseInt((+new Date()) / 1000)}`; _data['package'] = `prepay_id=${prepay_id}`; _data['nonceStr'] = util.getNonceStr().toLowerCase(); _data['signType'] = params['sign_type'] || 'MD5'; if (params['sign_type'] === 'HMAC-SHA256') { _data['paySign'] = this._hmac(_data); } else { _data['paySign'] = this._md5(_data); } break; case 'APP': _data['appid'] = this._params.appid; _data['timestamp'] = `${parseInt((+new Date()) / 1000)}`; _data['partnerid'] = this._params.mch_id; _data['prepayid'] = prepay_id; _data['package'] = 'Sign=WXPay'; _data['noncestr'] = util.getNonceStr().toLowerCase(); if (params['sign_type'] === 'HMAC-SHA256') { _data['sign'] = this._hmac(_data); } else { _data['sign'] = this._md5(_data); } break; case 'NATIVE': // pc端网站 模式二 _data = { // 把code_url 生成图片 ...result, }; break; case 'MWEB': // 不能直接在浏览器中访问mweb_url,会报商家参数错误,因为他会检测Referer,所以Referer不能为空 // 手机浏览器中支付 https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx20161110163838f231619da20804912345&package=1037687096&redirect_url=https%3A%2F%2Fwww.wechatpay.com.cn _data = { ...result, 'mweb_url': result.mweb_url + `&redirect_url=${encodeURIComponent(this._params.redirect_url)}`, }; break; default: console.error('trade_type参数有误'); _data = {}; } const req_data = { ...this._params, }; delete req_data['pfx']; delete req_data['key']; delete req_data['sign']; return { // req_data, // 创建订单的参数 用于回调验证 ..._data, return_code, return_msg, result_code, }; } // 支付回调验证 callback_check(data) { let _sign = ''; if (data.sign_type === 'HMAC-SHA256') { _sign = this._hmac(data); } else { _sign = this._md5(data); } return data.sign === _sign; // boolean true 成功 } // 订单查询 async orderquery(params) { // 必传参数 const properties = []; if (!params.transaction_id && !params.out_trade_no) throw new Error('缺少参数transaction_id或out_trade_no!'); let reuslt = await this.init(params, 'orderquery', properties); return reuslt; } // 关闭订单 async closeorder(params) { const properties = ['out_trade_no']; let reuslt = await this.init(params, 'closeorder', properties); return reuslt; } // 申请退款 async refund(params) { if (!params.transaction_id && !params.out_trade_no) throw new Error('缺少参数transaction_id或out_trade_no!'); if (!this._options.pfx) throw new Error('缺少pfx'); const properties = ['out_refund_no', 'total_fee', 'refund_fee']; let reuslt = await this.init(params, 'refund', properties); return reuslt; } // 查询退款 async refundquery(params) { if (!params.transaction_id && !params.out_trade_no && !params.out_refund_no && !params.refund_id) { throw new Error('缺少参数transaction_id或out_trade_no或refund_id或out_refund_no!'); } const properties = []; let reuslt = await this.init(params, 'refundquery', properties); return reuslt; } // 下载交易账单 async downloadbill(params) { this._otherParams(params); const properties = ['bill_date']; this._checkOptions(properties); this._xml = this._jsontoxml(); const result = await this._request2('downloadbill', this._xml); if (result.status !== 200 && result.statusCode !== 200) return result; // 参数处理 if (result.type === 'application/x-gzip') { return { 'data': result.body, 'return_code': 'SUCCESS', }; } else if (result.type === 'text/plain') { if (result.text.indexOf('') !== -1) return this._xmltojson(result.text); return { 'data': result.text, 'return_code': 'SUCCESS', }; } return result; } // 下载资金账单 async downloadfundflow(params) { this._otherParams(params); if (params.sign_type !== 'HMAC-SHA256') throw new Error('请选择HMAC-SHA256加密!'); if (!this._params.pfx) throw new Error('缺少pfx'); const properties = ['bill_date', 'account_type']; this._checkOptions(properties); this._xml = this._jsontoxml(); const result = await this._request2('downloadfundflow', this._xml); if (result.status !== 200 && result.statusCode !== 200) return result; // 参数处理 if (result.type === 'application/x-gzip') { return { 'data': result.body, 'return_code': 'SUCCESS', 'result_code': 'SUCCESS', }; } else if (result.type === 'text/plain') { if (result.text.indexOf('') !== -1) return this._xmltojson(result.text); return { 'data': result.text, 'return_code': 'SUCCESS', 'result_code': 'SUCCESS', }; } return result; } // 交易保障 async report(params) { const properties = ['interface_url', 'execute_time_', 'return_code', 'result_code', 'user_ip']; let reuslt = await this.init(params, 'report', properties); return reuslt; } // 拉取订单评价数据 async batchquerycomment(params) { this._otherParams(params); const properties = ['begin_time', 'end_time', 'offset', 'limit']; if (!this._params.pfx) throw new Error('缺少pfx'); this._checkOptions(properties); this._xml = this._jsontoxml(); const result = await this._request2('batchquerycomment', this._xml); if (result.status !== 200 && result.statusCode !== 200) return result; // 参数处理 if (result.type === 'text/html') { if (result.text.indexOf('') !== -1) { return this._xmltojson(result.text); } return { 'data': result.text, 'return_code': 'SUCCESS', 'result_code': 'SUCCESS', }; } return result; } // 付款码支付 async micropay(params) { const properties = ['body', 'out_trade_no', 'total_fee', 'spbill_create_ip', 'auth_code']; let reuslt = await this.init(params, 'micropay', properties); return reuslt; } // 撤销订单(只支持付款码支付的订单才可以撤销,统一下单生成的订单不能撤销) async reverse(params) { if (!params.transaction_id && !params.out_trade_no) throw new Error('缺少参数transaction_id或out_trade_no!'); const properties = []; let reuslt = await this.init(params, 'reverse', properties); return reuslt; } // 付款码查询openid async authcodetoopenid(params) { const properties = ['auth_code']; let reuslt = await this.init(params, 'authcodetoopenid', properties); return reuslt; } } module.exports = Pay;