Authored by 郭成尧

pay-modified

... ... @@ -208,4 +208,4 @@ module.exports = {
goAlipay,
payCod,
payAli
};
\ No newline at end of file
};
... ...
/**
* TAR NOTE: 从 YOHO-BLK 项目复制,未针对本项目做适配
* @author: jiangfeng<jeff.jiang@yoho.cn>
* @date: 16/7/22
*/
'use strict';
const config = global.yoho.config;
const helpers = global.yoho.helpers;
const common = require('./common');
const sign = require('./sign');
const payHelpersBank = require('./bank');
const md5 = require('md5');
const logger = global.yoho.logger;
const ALIPAY_URL = 'https://mapi.alipay.com/gateway.do';
const Alibank = {
pay(user, order, param, protocol) {
let payParams = JSON.parse(param.payParams);
let extraParam = JSON.stringify({
sign_id_ext: user.uid,
defaultbank: param.bankCode || ''
});
let params = {
service: 'create_direct_pay_by_user',
partner: payParams.merchant_id,
_input_charset: 'utf-8',
notify_url: config.pay.serviceNotify + 'payment/alipay_notify',
return_url: protocol + ':' + helpers.urlFormat('/shopping/pay/callback/alibank'),
subject: 'BLK订单号:' + order.order_code,
out_trade_no: order.order_code,
it_b_pay: common.getPayExpireMin(order.pay_expire) + 'm',
total_fee: order.payment_amount,
payment_type: '1',
defaultbank: param.bankCode,
seller_email: payParams.merchant_other_code,
extra_common_param: extraParam
};
// TODO 防钓鱼配置,参考php
let signStr = md5(sign.raw(params) + payParams.merchant_key);
let body = sign.rawUncode(params) + '&sign=' + signStr + '&sign_type=MD5';
return {
code: 200,
data: {
href: ALIPAY_URL + '?' + body
}
};
},
notify(data, param) {
let payParams = param.payParams && JSON.parse(param.payParams) || {};
let orderCode = parseInt(data.out_trade_no, 10);
let extraParam = data.extra_common_param && JSON.parse(data.extra_common_param) || {};
let bankName = payHelpersBank.getList()[extraParam.defaultbank] &&
payHelpersBank.getList()[extraParam.defaultbank].name || '';
logger.info(`Alibank notify, params = ${JSON.stringify(data)}`);
if (!this.checkNotify(data, payParams)) {
return {payResult: -1, bankName: bankName};
} else {
return {
bankName: bankName,
orderCode: orderCode,
payResult: data.trade_status === 'TRADE_SUCCESS' ? 200 : 400,
payTime: data.gmt_payment || '',
totalFee: data.total_fee,
resultMsg: data.notify_type,
payOrderCode: orderCode,
tradeNo: data.trade_no,
bankBillNo: data.bank_seq_no || ''
};
}
},
checkNotify(data, payParams) {
let signValue = data.sign;
if (!payParams || !data) {
return false;
}
delete data.sign;
delete data.sign_type;
delete data.code;
let signStr = md5(sign.raw(data) + payParams.merchant_key);
return signValue === signStr;
}
};
module.exports = Alibank;
... ...
... ... @@ -86,4 +86,4 @@ const Alipay = {
}
};
module.exports = Alipay;
\ No newline at end of file
module.exports = Alipay;
... ...
/**
* Created by TaoHuang on 2016/7/18.
*/
'use strict';
const Bank = {
getList() {
return {
BOCB2C: {
name: '中国银行',
ico: '//static.yohobuy.com/images/pay/icon/zhongguo.png'
},
ABC: {
name: '中国农业银行',
ico: '//static.yohobuy.com/images/pay/icon/nongye.png'
},
SPABANK: {
name: '平安银行',
ico: '//static.yohobuy.com/images/pay/icon/pingan.png'
},
CMBC: {
name: '中国民生银行',
ico: '//static.yohobuy.com/images/pay/icon/minsheng.png'
},
ICBCB2C: {
name: '中国工商银行',
ico: '//static.yohobuy.com/images/pay/icon/gongshang.png'
},
SPDB: {
name: '浦发银行',
ico: '//static.yohobuy.com/images/pay/icon/pufa.png'
},
BJRCB: {
name: '北京农商银行',
ico: '//static.yohobuy.com/images/pay/icon/beijingnongshang.png'
},
HZCBB2C: {
name: '杭州银行',
ico: '//static.yohobuy.com/images/pay/icon/hangzhou.png'
},
CMB: {
name: '招商银行',
ico: '//static.yohobuy.com/images/pay/icon/zhaoshang.png'
},
CIB: {
name: '兴业银行',
ico: '//static.yohobuy.com/images/pay/icon/xingye.png'
},
FDB: {
name: '富滇银行',
ico: '//static.yohobuy.com/images/pay/icon/fudian.png'
},
CEBDEBIT: {
name: '中国光大银行',
ico: '//static.yohobuy.com/images/pay/icon/guangda.png'
},
CCB: {
name: '中国建设银行',
ico: '//static.yohobuy.com/images/pay/icon/zhongguojianshe.png'
},
GDB: {
name: '广发银行',
ico: '//static.yohobuy.com/images/pay/icon/guangfa.png'
},
POSTGC: {
name: '中国邮政储蓄',
ico: '//static.yohobuy.com/images/pay/icon/zhongguoyouzhengchuxu.png'
},
SHBANK: {
name: '上海银行',
ico: '//static.yohobuy.com/images/pay/icon/shanghai.png'
},
NBBANK: {
name: '宁波银行',
ico: '//static.yohobuy.com/images/pay/icon/ningbo.png'
}
};
}
};
module.exports = Bank;
... ...
/**
* 各种支付的入口
*
* TAR NOTE: 本项目中仅支持支付宝和微信支付,其他支付方式需调试
* @author: jiangfeng<jeff.jiang@yoho.cn>
* @date: 16/7/22
*/
'use strict';
const PayData = require('../models/pay');
const OrderData = require('../models/order');
const PayModel = require('../models/pay');
const Alipay = require('./pay/alipay');
const Alibank = require('./pay/alibank');
const Wechat = require('./pay/wechat');
const Promise = require('bluebird');
const common = require('./pay/common');
... ... @@ -48,20 +48,25 @@ const Payment = {
let method = paymentPars[0] * 1;
if (method === PayData.payments.wechat) {
if (method === PayModel.payments.wechat) {
// 如果是微信支付,不需要调用获取支付方式详情接口
result = yield Wechat.pay(user, order, { id: PayData.payments.wechat });
result = yield Wechat.pay(user, order, { id: PayModel.payments.wechat });
} else {
payInfo = yield PayData.getPaymentInfo(method);
payInfo = yield PayModel.getPaymentInfo(method);
if (!payInfo.payParams) {
return result;
}
switch (payInfo.id) {
case PayData.payments.alipay:
case PayModel.payments.alipay:
result = Alipay.pay(user, order, payInfo, protocol);
break;
case PayModel.payments.alibank:
bankCode = paymentPars[1];
payInfo.bankCode = bankCode; // 设置默认银行
result = Alibank.pay(user, order, payInfo, protocol);
break;
default:
break;
}
... ... @@ -83,8 +88,8 @@ const Payment = {
beforePay(user, order, method, bankCode) {
return Promise.all([
OrderData.updateOrderPayment(order.order_code, method, user.uid),
PayData.getBankByOrder(order.order_code)
PayModel.updateOrderPayment(order.order_code, method, user.uid),
PayModel.getBankByOrder(order.order_code)
]).then(result => {
let paymentRecord = result[0];
let bankRecord = result[1];
... ... @@ -96,9 +101,9 @@ const Payment = {
}
if (bankRecord && bankRecord.bankCode) {
return PayData.updateOrderPayBank(order.order_code, method, bankCode);
return PayModel.updateOrderPayBank(order.order_code, method, bankCode);
} else {
return PayData.setOrderPayBank(order.order_code, method, bankCode);
return PayModel.setOrderPayBank(order.order_code, method, bankCode);
}
}).catch(e => {
... ... @@ -111,37 +116,37 @@ const Payment = {
});
},
afterPay(query, payId, user) {
afterPay(query, payId, user, sessionKey) {
return co(function*() {
let payInfo = yield PayData.getPaymentInfo(payId);
let payInfo = yield PayModel.getPaymentInfo(payId);
let payResult = {};
let payData = {};
let payName = '';
if (payId === PayData.payments.alipay) {
if (payId === PayModel.payments.alipay) {
payResult = Alipay.notify(query, payInfo);
} else if (payId === PayData.payments.alibank) {
} else if (payId === PayModel.payments.alibank) {
payResult = Alibank.notify(query, payInfo);
}
payResult.bankName = payName = payResult.bankName || payInfo.payName || '';
payResult.bankCode = payResult.bankCode || payInfo.pay_code || '';
//记录日志
// 记录日志
logger.info(`\r\n\r\n pay back confirmreq = ${JSON.stringify({
query: query,
payId: payId,
user: user,
payResult: payResult
})}`);
query: query,
payId: payId,
user: user,
payResult: payResult
})}`);
if (payResult && payResult.payResult === 200) {
if (payResult.orderCode) {
logger.info('pay back confirm');
yield PayData.sendPayConfirm(payResult.orderCode, payId, user.uid);
yield PayModel.sendPayConfirm(payResult.orderCode, payId, user.uid);
}
payData = yield PayData.procOrderData(payResult, user.uid);
payData = yield PayModel.procOrderData(payResult, user.uid, sessionKey);
} else {
payData = {
code: 500,
... ... @@ -156,4 +161,4 @@ const Payment = {
}
};
module.exports = Payment;
\ No newline at end of file
module.exports = Payment;
... ...
/**
* 支付相关api调用
* @author: jiangfeng<jeff.jiang@yoho.cn>
* @date: 2016/07/18
*/
'use strict';
const api = global.yoho.API;
// 获取支付宝等平台支付方式列表
const getPayProvider = () => {
return api.get('', {
method: 'web.SpaceOrders.getPaymentList'
}, {cache: true});
};
// 获取单个支付方式相关详细信息
const getPaymentInfo = (id) => {
return api.get('', {
method: 'web.SpaceOrders.getPaymentById',
id: id
}, {cache: true});
};
/* 获取上次使用的支付方式*/
const getBankByOrder = (code) => {
return api.get('', {
method: 'web.SpaceOrders.getOrderPayBank',
orderCode: code
});
};
/* 记录支付方式*/
const setOrderPayBank = (code, payment, bankCode) => {
return api.get('', {
method: 'web.SpaceOrders.addOrderPayBank',
orderCode: code,
payment: payment,
bankCode: bankCode
});
};
/* 更改支付方式*/
const updateOrderPayBank = (code, payment, bankCode) => {
return api.get('', {
method: 'web.SpaceOrders.modifyOrderPayBank',
orderCode: code,
payment: payment,
bankCode: bankCode
});
};
/* 发送支付确认*/
const sendPayConfirm = (code, payment, uid) => {
return api.get('', {
method: 'app.SpaceOrders.payConfirm',
order_code: code,
payment_id: payment,
uid: uid
});
};
const sendMessage = (mobile, template, codes) => {
return api.get('', {
method: 'app.message.sendMsg',
mobile: mobile,
template: template,
codes: codes
});
};
module.exports = {
getPayProvider,
getPaymentInfo,
getBankByOrder,
setOrderPayBank,
updateOrderPayBank,
sendPayConfirm,
sendMessage
};
... ...
... ... @@ -10,8 +10,11 @@ const api = global.yoho.API;
const serviceAPI = global.yoho.ServiceAPI;
const utils = '../../../utils';
const productProcess = require(`${utils}/product-process`);
const payApi = require('./pay-api');
const helpers = global.yoho.helpers;
const _ = require('lodash');
const co = require('bluebird').coroutine;
const logger = global.yoho.logger;
// 资源位
const _getBanner = (param) => {
... ... @@ -75,7 +78,7 @@ const _getOthersBuy = (param) => {
goodSkn = result[0].data.order_goods[0].product_skn;
}
return _getOthersBuy2(Object.assign(param, {skn: goodSkn}));
return _getOthersBuy2(Object.assign(param, { skn: goodSkn }));
}).then((result) => {
... ... @@ -94,28 +97,161 @@ const savePrePayInfo = (params) => {
uid: params.uid,
orderCode: params.orderCode,
payment: params.payment
}, {code: 200}).then(result => {
}, { code: 200 }).then(result => {
return result && result.data;
});
};
/**
* 更新订单的支付方式
* @param params
* @returns {*|Promise.<TResult>}
* 获取订单支付银行信息
* @param id
*/
const getBankByOrder = (id) => {
return co(function*() {
let result = yield payApi.getBankByOrder(id);
if (result && result.code === 200 && result.data) {
return result.data;
}
return {};
})();
};
/**
* 设置订单支付银行
* @param code
* @param payment
* @param bankCode
*/
const setOrderPayBank = (code, payment, bankCode) => {
return co(function*() {
let data = yield payApi.setOrderPayBank(code, payment, bankCode);
return data;
})();
};
/**
* 获取支付方式的相关参数, (密钥等信息)
* @param id
*/
const getPaymentInfo = (id) => {
return co(function*() {
let result = yield payApi.getPaymentInfo(id);
if (result && result.code === 200 && result.data) {
return result.data;
}
return {};
})();
};
/**
* 支付确认
* @param code
* @param payment
* @param uid
*/
const sendPayConfirm = (code, payment, uid) => {
return co(function*() {
let data = yield payApi.sendPayConfirm(code, payment, uid);
return data;
})();
};
/**
* 更新订单支付方式
* @param code
* @param payment
* @param uid
* @returns {*}
*/
const updateOrderPayment = (params) => {
const updateOrderPayment = (code, payment, uid) => {
return api.get('', {
method: 'app.SpaceOrders.updateOrdersPaymentByCode',
order_code: params.orderCode,
payment: params.payment,
uid: params.uid
}, {code: 200}).then(result => {
return result && result.data;
order_code: code,
payment: payment,
uid: uid
});
};
/**
* 更新订单支付银行
* @param code
* @param payment
* @param bankCode
*/
const updateOrderPayBank = (code, payment, bankCode) => {
return co(function*() {
let data = yield payApi.updateOrderPayBank(code, payment, bankCode);
return data;
})();
};
/**
* 支付成功,前端回调时,处理订单信息
* @param payResult
* @param uid
* @param sessionKey
*/
const procOrderData = (payResult, uid, sessionKey) => {
return co(function*() {
let orderCode = payResult.orderCode;
let result = { code: 400, message: '' };
if (!orderCode) {
result.message = '未查到订单信息,订单状态更新失败!';
return result;
} else {
let orderInfo = yield _getOtherDetail({
uid: uid,
orderCode: orderCode,
sessionKey: sessionKey
});
if (orderInfo && orderInfo.data) {
let order = orderInfo.data;
let amount = order.payment_amount;
if (order.is_cancel === 'Y') {
logger.warn('front pay success but order is cancel.', { payResult: payResult, order: order });
payApi.sendMessage(order.mobile, 'error_sms', '支付成功,但订单已取消,订单号为' + orderCode);
return { code: 417, message: '支付成功,但订单已取消,需联系客服!' };
}
if (order.payment_status === 'N') {
logger.warn('front pay success but may be notify fail');
}
if (_.round(parseFloat(amount), 2) !== _.round(parseFloat(payResult.totalFee), 2)) {
logger.warn('front pay success but the amount is not same.', { payResult: payResult, order: order });
return {
code: 415,
message: '支付金额与订单金额不一致,订单状态更新失败!'
};
}
return {
code: 200,
message: '支付成功,请等待发货',
data: {
order: order
}
};
} else {
result.message = '未查到订单信息,订单状态更新失败!';
}
}
return result;
})();
};
/**
* 支付相关的数据处理函数
*/
const payTool = {
... ... @@ -125,24 +261,21 @@ const payTool = {
* @returns {[*,*]}
*/
payAppInfo() {
return [
{
appIcon: '',
payLink: helpers.urlFormat('/shopping/pay/index'),
appId: 'alipay',
app: '支付宝支付',
hint: '支付宝钱包支付',
subHint: '推荐支付宝用户使用'
},
{
appIcon: '',
payLink: '',
appId: 'weixin',
app: '微信支付',
hint: '推荐使用',
subHint: ''
}
];
return [{
appIcon: '',
payLink: helpers.urlFormat('/shopping/pay/index'),
appId: 'alipay',
app: '支付宝支付',
hint: '支付宝钱包支付',
subHint: '推荐支付宝用户使用'
}, {
appIcon: '',
payLink: '',
appId: 'weixin',
app: '微信支付',
hint: '推荐使用',
subHint: ''
}];
},
/**
... ... @@ -264,6 +397,12 @@ module.exports = {
getOtherDetail: _getOtherDetail,
savePrePayInfo,
updateOrderPayment,
updateOrderPayBank,
getBankByOrder,
getPaymentInfo,
setOrderPayBank,
sendPayConfirm,
procOrderData,
payCenter,
getPayCod,
getPayAli
... ...