UNPKG

swiftpass-weixin

Version:
198 lines (159 loc) 5.59 kB
var util = require('./util'); var request = require('request'); var md5 = require('MD5'); exports = module.exports = WXPay; function WXPay() { if (!(this instanceof WXPay)) { return new WXPay(arguments[0]); } ; this.rquestUrl = 'https://pay.swiftpass.cn/pay/gateway'; this.options = arguments[0]; this.wxpayID = {mch_id: this.options.mch_id}; }; WXPay.mix = function () { switch (arguments.length) { case 1: var obj = arguments[0]; for (var key in obj) { if (WXPay.prototype.hasOwnProperty(key)) { throw new Error('Prototype method exist. method: ' + key); } WXPay.prototype[key] = obj[key]; } break; case 2: var key = arguments[0].toString(), fn = arguments[1]; if (WXPay.prototype.hasOwnProperty(key)) { throw new Error('Prototype method exist. method: ' + key); } WXPay.prototype[key] = fn; break; } }; WXPay.mix('option', function (option) { for (var k in option) { this.options[k] = option[k]; } }); WXPay.mix('sign', function (param) { var querystring = Object.keys(param).filter(function (key) { return param[key] !== undefined && param[key] !== '' && ['pfx', 'partner_key', 'sign', 'key'].indexOf(key) < 0; }).sort().map(function (key) { return key + '=' + param[key]; }).join("&") + "&key=" + this.options.partner_key; return md5(querystring).toUpperCase(); }); WXPay.mix('createUnifiedOrder', function (opts, fn) { opts.nonce_str = opts.nonce_str || util.generateNonceString(); util.mix(opts, this.wxpayID); util.mix(opts, {service: 'pay.weixin.native'}); opts.sign = this.sign(opts); request({ url: this.rquestUrl, method: 'POST', body: util.buildXML(opts), agentOptions: { pfx: this.options.pfx, passphrase: this.options.mch_id } }, function (err, response, body) { util.parseXML(body, fn); }); }); WXPay.mix('getBrandWCPayRequestParams', function (order, fn) { order.trade_type = "JSAPI"; var _this = this; this.createUnifiedOrder(order, function (err, data) { var reqparam = { appId: _this.options.appid, timeStamp: Math.floor(Date.now() / 1000) + "", nonceStr: data.nonce_str, package: "prepay_id=" + data.prepay_id, signType: "MD5" }; reqparam.paySign = _this.sign(reqparam); fn(err, reqparam); }); }); WXPay.mix('createMerchantPrepayUrl', function (param) { param.time_stamp = param.time_stamp || Math.floor(Date.now() / 1000); param.nonce_str = param.nonce_str || util.generateNonceString(); util.mix(param, this.wxpayID); param.sign = this.sign(param); var query = Object.keys(param).filter(function (key) { return ['sign', 'mch_id', 'product_id', 'appid', 'time_stamp', 'nonce_str'].indexOf(key) >= 0; }).map(function (key) { return key + "=" + encodeURIComponent(param[key]); }).join('&'); return "weixin://wxpay/bizpayurl?" + query; }); WXPay.mix('useWXCallback', function (fn) { return function (req, res, next) { var _this = this; res.success = function () { res.end(util.buildXML({xml: {return_code: 'SUCCESS'}})); }; res.fail = function () { res.end(util.buildXML({xml: {return_code: 'FAIL'}})); }; util.pipe(req, function (err, data) { var xml = data.toString('utf8'); util.parseXML(xml, function (err, msg) { req.wxmessage = msg; fn.apply(_this, [msg, req, res, next]); }); }); }; }); WXPay.mix('queryOrder', function (query, fn) { if (!(query.transaction_id || query.out_trade_no)) { fn(null, {return_code: 'FAIL', return_msg: '缺少参数'}); } query.nonce_str = query.nonce_str || util.generateNonceString(); util.mix(query, this.wxpayID); util.mix(query, {service: 'trade.single.query'}); query.sign = this.sign(query); request({ url: this.rquestUrl, method: "POST", body: util.buildXML({xml: query}) }, function (err, res, body) { util.parseXML(body, fn); }); }); WXPay.mix('closeOrder', function (order, fn) { if (!order.out_trade_no) { fn(null, {return_code: "FAIL", return_msg: "缺少参数"}); } order.nonce_str = order.nonce_str || util.generateNonceString(); util.mix(order, this.wxpayID); order.sign = this.sign(order); request({ url: this.rquestUrl, method: "POST", body: util.buildXML({xml: order}) }, function (err, res, body) { util.parseXML(body, fn); }); }); WXPay.mix('refund', function (order, fn) { if (!(order.transaction_id || order.out_refund_no)) { fn(null, {return_code: 'FAIL', return_msg: '缺少参数'}); } order.nonce_str = order.nonce_str || util.generateNonceString(); util.mix(order, this.wxpayID); util.mix(order, {service: 'trade.single.refund'}); order.sign = this.sign(order); request({ url: this.rquestUrl, method: "POST", body: util.buildXML({xml: order}), agentOptions: { pfx: this.options.pfx, passphrase: this.options.mch_id } }, function (err, response, body) { util.parseXML(body, fn); }); });