|
|
/**
|
|
|
*
|
|
|
* @author: jiangfeng<jeff.jiang@yoho.cn>
|
|
|
* @date: 16/7/22
|
|
|
*/
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
const moment = require('moment');
|
|
|
const rq = require('request-promise');
|
|
|
const common = require('./common');
|
|
|
const sign = require('./sign');
|
|
|
const md5 = require('md5');
|
|
|
const _ = require('lodash');
|
|
|
const logger = global.yoho.logger;
|
|
|
const config = global.yoho.config;
|
|
|
|
|
|
const wechatUnifiedOrderUrl = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
|
|
|
|
|
|
const Wechat = {
|
|
|
pay(user, order, info) {
|
|
|
let expire = common.getPayExpireCouple(order.payExpire);
|
|
|
|
|
|
info = JSON.parse(info.payParams || '{}');
|
|
|
|
|
|
let unifiedOrder = {
|
|
|
body: 'BLK订单号:' + order.orderCode,
|
|
|
out_trade_no: order.orderCode,
|
|
|
total_fee: parseInt(order.paymentAmount * 100, 10),
|
|
|
time_start: moment(expire.start).format('YYYYMMDDHHmmss'),
|
|
|
time_expire: moment(expire.end).format('YYYYMMDDHHmmss'),
|
|
|
trade_type: 'NATIVE',
|
|
|
product_id: order.orderCode,
|
|
|
notify_url: config.pay.serviceNotify + 'payment/weixin_notify',
|
|
|
appid: info.app_id,
|
|
|
mch_id: info.partner_id,
|
|
|
nonce_str: common.nonceStr()
|
|
|
};
|
|
|
|
|
|
let signStr = md5(sign.raw(unifiedOrder) + '&key=' + info.partner_key);
|
|
|
|
|
|
unifiedOrder.sign = _.toUpper(signStr);
|
|
|
|
|
|
return this.unifiedOrder(unifiedOrder).then(result => {
|
|
|
if (result && result.xml) {
|
|
|
let data = result.xml || {};
|
|
|
|
|
|
if (data.return_code === 'SUCCESS' && Wechat.checkSign(data, info)) {
|
|
|
return {
|
|
|
code: 200,
|
|
|
data: {
|
|
|
href: data.code_url
|
|
|
}
|
|
|
};
|
|
|
}
|
|
|
}
|
|
|
return {
|
|
|
code: 400,
|
|
|
message: '请稍后重试'
|
|
|
};
|
|
|
|
|
|
});
|
|
|
},
|
|
|
|
|
|
unifiedOrder(unifiedOrder) {
|
|
|
let xml = common.toXml(unifiedOrder);
|
|
|
|
|
|
return rq({
|
|
|
method: 'POST',
|
|
|
uri: wechatUnifiedOrderUrl,
|
|
|
headers: {
|
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
|
'Content-Length': Buffer.byteLength(xml)
|
|
|
},
|
|
|
body: xml,
|
|
|
timeout: 1000
|
|
|
}).then(result => {
|
|
|
if (result) {
|
|
|
return common.xml2Obj(result);
|
|
|
} else {
|
|
|
return {};
|
|
|
}
|
|
|
}).catch(err => {
|
|
|
logger.error(`call wechat pay unifiedOrder fail. order=${JSON.stringify(unifiedOrder)}`, err);
|
|
|
return {};
|
|
|
});
|
|
|
},
|
|
|
|
|
|
notify(data, info) { // eslint-disable-line
|
|
|
|
|
|
},
|
|
|
|
|
|
checkSign(data, info) {
|
|
|
if (data && data.sign) {
|
|
|
let signStr = data.sign || '';
|
|
|
|
|
|
delete data.sign;
|
|
|
return signStr === md5(sign.raw(data) + info.partner_key);
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
module.exports = Wechat; |