UNPKG

egg-wechat-pay

Version:
203 lines (173 loc) 3.52 kB
const {Payment} = require('wechat-pay') const delegates = require('delegates') const moment = require('moment') const {defaults, BASIC_TYPES} = require('skema') const {shape} = defaults({ types: BASIC_TYPES.STRICT }) const MockData = shape({ nonce_str: { default (self) { return self._payment._generateNonceStr() } }, sign_type: { optional: true, validate (v) { return v === 'MD5' || v === 'HMAC-SHA256' } }, result_code: { default: 'SUCCESS' }, appid: { set (self) { return self._config.appId } }, mch_id: { set (self) { return self._config.mchId } }, openid: { default: 'wxd930ea5d5a258f4f' }, trade_type: { default: 'JSAPI' }, bank_type: { default: 'CMC' }, total_fee: Number, cash_fee: Number, settlement_total_fee: { optional: true, type: Number }, fee_type: { default: 'CNY', type: String }, transaction_id: String, out_trade_no: String, attach: { optional: true, type: String }, time_end: { default () { return new Date }, set (v) { const date = v instanceof Date ? date : new Date(date) return moment(date).format('YYYYMMDDHHmmss') } } }) class WechatPayBase { constructor ({ bodyPrefix, config }) { this._bodyPrefix = bodyPrefix this._config = config } requestPayment ({ body, spbill_create_ip, ip, ...others }) { return this._payment.getBrandWCPayRequestParams({ body: this._handleBody(body), spbill_create_ip: ip || spbill_create_ip, ...others }) } parse (xml) { return this._payment.validate(xml) } stringify (obj) { return this._payment.buildXml(obj) } fail (ctx, return_msg) { ctx.body = this.stringify({ return_code: 'FAIL', return_msg }) } success (ctx) { ctx.body = this.stringify({ return_code: 'SUCCESS' }) } mock (data) { const mocked = MockData.from(data, [this]) mocked.sign = this._payment._getSign(mocked) return this.stringify(mocked) } _handleBody (body) { const prefix = this._bodyPrefix if (!prefix) { return body } if (body.indexOf(prefix) === 0) { return body } return `${prefix}-${body}` } } delegates(WechatPayBase.prototype, '_payment') .method('refund') .method('refundQuery') .method('closeOrder') .method('orderQuery') .method('sendRedPacket') .method('redPacketQuery') .method('transfers') .method('downloadBill') class WechatPayNew extends WechatPayBase { constructor (payment, options) { super(options) this._payment = payment } } module.exports = class WechatPayManager extends WechatPayBase { constructor ({ secret, partnerKey, appId, merchantId, mchId, notifyUrl, pfx, bodyPrefix }) { const config = { partnerKey: secret || partnerKey, mchId: merchantId || mchId, notifyUrl, pfx, appId } super({bodyPrefix, config}) this._apps = Object.create(null) this._payment = this._newApp(appId) } _newApp (appId) { const app = this._apps[appId] if (app) { return app } const config = Object.assign({}, this._config, {appId}) return this._apps[appId] = new Payment(config) } // Creates a new instance newApp (appId) { if (appId === this._appId) { return this } return new WechatPayNew(this._newApp(appId), this._config) } }