Showing 69 changed files with 3550 additions and 12 deletions
... ... @@ -98,7 +98,7 @@ const easypayOrderSubmit = (uid, cartType, params, remoteIp) => {
if (result.code === 200) {
let d = result.data;
d.url = helper.urlFormat('/shopping/pay', {
d.url = helper.urlFormat('/shopping/newpay', {
ordercode: d.order_code
});
}
... ...
... ... @@ -75,7 +75,7 @@ const submit = (uid, cartType, p, remoteIp) => {
if (result.code === 200) {
let d = result.data;
d.url = helper.urlFormat('/shopping/pay', {
d.url = helper.urlFormat('/shopping/newpay', {
ordercode: d.order_code
});
}
... ...
... ... @@ -35,9 +35,25 @@ const index = (req, res, next) => {
res.jsonp(data);
}).catch(next);
}
};
/** 为你优选**/
const getRecommend = (req, res, next) => {
let uid = req.user.uid;
let udid = req.user.uid + req.yoho.udid;
rvModel.recommend({
yh_channel: req.yoho.channelNum,
uid: uid,
udid: udid,
rec_pos: req.body.recPos,
limit: req.body.limit
}).then(d => {
res.json(d);
}).catch(next);
};
module.exports = {
index
index,
getRecommend
};
... ...
... ... @@ -10,6 +10,24 @@ const _ = require('lodash');
const api = global.yoho.API;
const helper = global.yoho.helpers;
/**
* 处理商品
*/
const _handleProduct = (products) => {
return products.map((product) => {
return {
href: helper.getUrlBySkc(product.product_id,
_.get(product, 'goods_list[0].product_skc', ''),
product.cn_alphabet
),
thumb: product.default_images,
name: product.product_name,
price: product.sales_price,
productId: product.product_id
};
});
};
const index = (skn, limit) => {
return api.get('', {
... ... @@ -63,6 +81,22 @@ const index = (skn, limit) => {
});
};
/**
* [为你优选]
* @param {[type]} params [(yh_channel、uid、udid、rec_pos、limit)]
* @return {[type]} [{}]
*/
const recommend = (params) => {
params.limit = params.limit || 30;
return api.get('', Object.assign({
method: 'app.home.newPreference'
}, params)).then(d => {
return _handleProduct(_.get(d, 'data.product_list', []));
});
};
module.exports = {
index
index,
recommend
};
... ...
... ... @@ -19,6 +19,7 @@ const getBanner = require(`${cRoot}/getBanner`);
const passport = require(`${cRoot}/passport`);
router.get('/recentReview', rvCtrl.index); // 最近浏览
router.post('/getRecommend', rvCtrl.getRecommend); // 为你优选
router.post('/upload/image', multipartMiddleware, uploadCtrl.uploadImg);
... ...
... ... @@ -42,7 +42,7 @@ const ORDER_OP_ALL = [
type: 'buyNow',
name: '立即付款',
payNow: true,
hrefFun: it => helpers.urlFormat('/shopping/pay', {ordercode: it})
hrefFun: it => helpers.urlFormat('/shopping/newpay', {ordercode: it})
},
{
type: 'getExpress',
... ... @@ -552,7 +552,7 @@ const _getOrderDetailOp = (orderId, payment, status,
// 立刻付款
if (paymentType === 1 && paymentStatus === 'N' && isCancel === 'N' && payment !== 19) {
Object.assign(operation, {
goPay: helpers.urlFormat('/shopping/pay', {ordercode: orderId})
goPay: helpers.urlFormat('/shopping/newpay', {ordercode: orderId})
});
}
... ...
... ... @@ -246,7 +246,12 @@ const bind = {
sourceType: sourceType + '_relate'
});
return loginService.syncUserSession(result.data.uid, req, res, result.data.session_key).then(() => {
return loginService.syncUserSession(
result.data.uid,
req,
res,
result.data.session_key
).then(() => {
return {code: 200, message: result.message, data: {refer: refer}};
});
} else {
... ...
... ... @@ -92,8 +92,10 @@ const applysave = (req, res, next) => {
try {
for (let key in req.body) {
key = key + '';
param[_.camelCase(key)] = req.body[key];
if (req.body.hasOwnProperty(key)) {
key = key + '';
param[_.camelCase(key)] = req.body[key];
}
}
} catch (e) {
console.log(e);
... ...
/**
* 订单支付
* @author: xiaoxiao.hao<xiaoxiao.hao@yoho.cn>
* @date: 2017/03/20
*/
'use strict';
const headerModel = require('../../../doraemon/models/simple-header');
const PayData = require('../models/pay');
const PayHelpers = require('../helpers/payment');
const _ = require('lodash');
const integerTest = /^\d+$/;
/**
* 支付页
* @param req
* @param res
* @param next
*/
const online = (req, res, next) => {
let orderCode = req.query.ordercode || req.query.order_code;
let uid = req.user.uid;
if (!integerTest.test(orderCode)) {
// 不合法订单号
return next();
}
if (_.get(req.app.locals.pc, 'pay.newPay', false)) {
return res.redirect(`//www.yohobuy.com/shopping/pay?ordercode=${orderCode}`);
}
PayData.getPayInfo(uid, orderCode).then(result => {
let order = result.order;
let amount = _.toNumber(order.payment_amount);
let header = headerModel.setSimpleHeaderData() || {};
if (!order.order_code) {
// 不合法订单号
return next();
}
order.payment_type = parseInt(order.payment_type, 10);
if (amount <= 0 || order.payment_type === 2) {
PayData.deliveryData(order, PayData.payments.delivery).then(orderInfo => {
res.render('pay-success', {
module: 'shopping',
page: 'success',
simpleHeader: header,
order: orderInfo,
isDelivery: orderInfo.payment_type === 2
});
});
} else {
res.render('pay', Object.assign({
module: 'shopping',
page: 'pay',
title: '支付页面',
simpleHeader: header,
username: decodeURIComponent(req.user.name) || ''
}, result));
}
}).catch(next);
};
/**
* 获取第三方支付跳转url
* @param req
* @param res
* @param next
*/
const toPay = (req, res, next) => {
let orderCode = req.body.code;
let payType = req.body.payType;
let uid = req.user.uid;
let user = req.user;
if (!integerTest.test(orderCode)) {
// 不合法订单号
return next();
}
PayData.orderDetail(uid, orderCode).then(result => {
if (result && result.data) {
return PayHelpers.pay(Object.assign({IP: req.id}, user), result.data, payType, req.protocol);
} else {
return {
code: 400,
message: '获取订单失败'
};
}
}).then(result => {
res.json(result);
}).catch(next);
};
/**
* 微信扫码支付页面
* @param req
* @param res
* @param next
*/
const weixinQr = (req, res, next) => {
let code = req.query.code;
let qrcodeUrl = req.query.url;
let uid = req.user.uid;
let header = headerModel.setSimpleHeaderData() || {};
if (!integerTest.test(code)) {
// 不合法订单号
return next();
}
PayData.orderDetail(uid, code).then(d => {
d = d && d.data || {};
res.render('weixin-pay', {
module: 'shopping',
page: 'wxpay',
title: '微信扫码支付页面',
simpleHeader: header,
choosePayUrl: `//www.yohobuy.com/shopping/newpay?ordercode=${d.order_code}`,
qrcodeUrl: qrcodeUrl,
order: d
});
}).catch(next);
};
const weixinPayState = (req, res) => {
let code = req.body.code;
let uid = req.user.uid;
if (!integerTest.test(code)) {
return res.json({
code: 401,
message: '订单不存在'
});
}
PayHelpers.getWxSign(uid, code).then(d => {
return res.json(d);
}).catch(() => {
return res.json({});
});
};
/**
* 支付成功回调
* @param req
* @param res
*/
const callback = (req, res, next) => {
let type = req.params.type;
let payId = PayData.payments[type];
let query = req.query;
let header = headerModel.setSimpleHeaderData() || {};
if (!payId) {
return next();
}
// 银联、网银支付是post返回的
if (type === 'unionpay' || type === 'chinabank') {
query = req.body;
}
PayHelpers.afterPay(query, payId, req.user).then(result => {
if (result.code === 200 && result.data && result.data.order) {
res.render('pay-success', {
module: 'shopping',
page: 'success',
simpleHeader: header,
order: result.data.order
});
} else {
res.render('pay-fail', {
module: 'shopping',
page: 'fail',
point: result.point,
simpleHeader: header,
payName: result.payName
});
}
}).catch(next);
};
// 支付确认
const sendPayConfirm = (req, res, next) => {
let code = req.body.code;
let payment = req.body.payment;
let uid = req.user.uid;
PayData.sendPayConfirm(code, payment, uid).then(result => {
res.json(result);
}).catch(next);
};
// 支付异步回调
const notify = (req, res, next) => {
let type = req.params.type;
let query = req.query;
let payId = PayData.payments[type];
if (!payId) {
return res.json('');
}
PayHelpers.notifyPay(query, payId).then(result => {
res.json(result);
}).catch(next);
};
module.exports = {
online,
callback,
toPay,
weixinQr,
weixinPayState,
sendPayConfirm,
notify
};
... ...
/**
* 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;
... ...
/**
*
* @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 PAY_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.domains.serviceNotify + 'payment/alipay_notify',
return_url: protocol + ':' + helpers.urlFormat('/shopping/newpay/callback/alibank'),
subject: '有货订单号:' + 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
};
let signStr = md5(sign.raw(params) + payParams.merchant_key);
let body = sign.rawUncode(params) + '&sign=' + signStr + '&sign_type=MD5';
return {
code: 200,
data: {
href: PAY_URL + body
}
};
},
notify(data, param) {
let payParams = JSON.parse(param.payParams || '{}');
let orderCode = parseInt(data.out_trade_no, 10);
let extraParam = 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};
}
return {
bankName: bankName,
bankCode: extraParam.defaultbank || '',
orderCode: orderCode,
payResult: data.trade_status === 'TRADE_SUCCESS' ? 200 : 400,
totalFee: data.total_fee,
tradeNo: data.trade_no,
bankBillNo: data.bank_seq_no || ''
};
},
checkNotify(data, payParams) {
let signValue = data.sign;
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;
... ...
/**
*
* @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 md5 = require('md5');
const logger = global.yoho.logger;
const PAY_URL = 'https://mapi.alipay.com/gateway.do?';
const Alipay = {
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.domains.serviceNotify + 'payment/alipay_notify',
return_url: protocol + ':' + helpers.urlFormat('/shopping/newpay/callback/alipay'),
subject: '有货订单号:' + 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',
seller_email: payParams.merchant_other_code,
extra_common_param: extraParam
};
let signStr = md5(sign.raw(params) + payParams.merchant_key);
let body = sign.rawUncode(params) + '&sign=' + signStr + '&sign_type=MD5';
return {
code: 200,
data: {
href: PAY_URL + body
}
};
},
notify(data, param) {
let payParams = JSON.parse(param.payParams || '{}');
let orderCode = parseInt(data.out_trade_no, 10);
logger.info(`Alipay notify, params = ${JSON.stringify(data)}`);
if (!this.checkNotify(data, payParams)) {
return {payResult: -1};
}
return {
bankName: '',
orderCode: orderCode,
payResult: data.trade_status === 'TRADE_SUCCESS' ? 200 : 400,
totalFee: data.total_fee,
tradeNo: data.trade_no,
bankBillNo: ''
};
},
checkNotify(data, payParams) {
let signValue = data.sign;
delete data.sign;
delete data.sign_type;
delete data.code;
let signStr = md5(sign.raw(data) + payParams.merchant_key);
return signValue === signStr;
}
};
module.exports = Alipay;
... ...
/**
* @author: xiaoxiao.hao<xiaoxiao.hao@yoho.cn>
* @date: 2017/3/23
*/
'use strict';
const helpers = global.yoho.helpers;
const md5 = require('md5');
const PAY_URL = 'https://pay3.chinabank.com.cn/PayGate';
const Chinabank = {
pay(user, order, param, protocol) {
let payParams = JSON.parse(param.payParams);
let extraParam = JSON.stringify({
sign_id_ext: user.uid
});
let params = {
v_mid: payParams.merchant_id, // 商户号
v_oid: order.order_code, // 商户订单号
v_amount: order.payment_amount, // 总金额 以元为单位
v_moneytype: 'CNY', // 以人民币为单位
v_url: protocol + ':' + helpers.urlFormat('/shopping/newpay/callback/chinabank'), // 同步地址
v_md5info: '', // 签名
remark1: extraParam
};
params.v_md5info = md5(
`${params.v_amount}${params.v_moneytype}${params.v_oid}` +
`${params.v_mid}${params.v_url}${payParams.merchant_key}`
).toUpperCase();
return {
code: 200,
data: Object.assign({reqType: PAY_URL}, params)
};
},
notify(data, param) {
let payParams = JSON.parse(param.payParams || '{}');
let orderCode = parseInt(data.v_oid, 10);
if (!this.checkResponse(data, payParams)) {
return {payResult: -1};
}
return {
bankName: '',
orderCode: orderCode,
payResult: 200,
totalFee: data.v_amount,
tradeNo: '',
bankBillNo: ''
};
},
// 验证验证
checkResponse(data, payParams) {
let signText;
if (parseInt(data.v_pstatus, 10) !== 20) {
return false;
}
signText = md5(
`${data.v_oid}${data.v_pstatus}${data.v_amount}${data.v_moneytype}${payParams.merchant_key}`
).toUpperCase();
return data.v_md5str === signText;
}
};
module.exports = Chinabank;
... ...
/**
*
* @author: jiangfeng<jeff.jiang@yoho.cn>
* @date: 16/7/22
*/
'use strict';
const moment = require('moment');
const common = {
getPayExpireMin(expire) {
let defaultValue = 120;
if (expire) {
let expireTime = moment(expire, 'YYYY-MM-DD HH:mm:ss');
let diff = expireTime.diff(moment());
if (diff > 0) {
return Math.floor(diff / 1000 / 60);
} else {
return 0;
}
} else {
return defaultValue;
}
},
getPayExpireCouple(expire) {
let start = expire ? moment(expire, 'YYYY-MM-DD HH:mm:ss') : moment();
let end = expire ? moment(expire, 'YYYY-MM-DD HH:mm:ss') : moment();
return {
start: start.subtract(2, 'hours'),
end: end.add(5, 'minutes')
};
},
nonceStr(length) {
length = length || 32;
let chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
let str = '';
for (let i = 0; i < length; i++) {
str += chars[parseInt(Math.random() * length, 10)];
}
return str;
}
};
module.exports = common;
... ...
/**
*
* @author: jiangfeng<jeff.jiang@yoho.cn>
* @date: 16/7/22
*/
'use strict';
const Sign = {
raw(args) {
let keys = Object.keys(args);
keys = keys.filter(k => {
return args[k] === '' || args[k] === 'undefined' ? false : true;
}).sort();
return keys.map(k => {
return k + '=' + decodeURI(args[k]);
}).join('&');
},
rawUncode(args) {
let keys = Object.keys(args);
keys = keys.filter(k => {
return args[k] === '' || args[k] === 'undefined' ? false : true;
}).sort();
return keys.map(k => {
return k + '=' + encodeURI(args[k]);
}).join('&');
}
};
module.exports = Sign;
... ...
/**
*
* @author: xiaoxiao.hao<xiaoxiao.hao>
* @date: 2017/3/24
*/
'use strict';
const helpers = global.yoho.helpers;
const moment = require('moment');
const sign = require('./sign');
const md5 = require('md5');
const logger = global.yoho.logger;
const PAY_URL = 'https://gw.tenpay.com/gateway/pay.htm?';
const Tenpay = {
pay(user, order, param, protocol) {
let payParams = JSON.parse(param.payParams);
let extraParam = JSON.stringify({
sign_id_ext: user.uid
});
let params = {
partner: payParams.merchant_id, // 商户号
out_trade_no: order.order_code, // 商户订单号
total_fee: order.payment_amount * 100, // 总金额 以分为单位
return_url: protocol + ':' + helpers.urlFormat('/shopping/newpay/callback/tenpay'), // 同步地址
notify_url: protocol + ':' + helpers.urlFormat('/shopping/newpay/notify/tenpay'), // 异步通知地址
body: '有货订单号:' + order.order_code, // 商品描述
bank_type: 'DEFAULT', // 银行类型,默认为财付通
spbill_create_ip: user.IP, // 客户端IP
fee_type: '1', // 币种
subject: '有货订单号:' + order.order_code, // 商品名称,(中介交易时必填)
sign_type: 'MD5',
service_version: '1.0', // 接口版本号
input_charset: 'UTF-8', // 字符集
sign_key_index: '1', // 密钥序号
time_start: moment(order.create_time * 1000).format('YYYYMMDDHHmmss'), // 订单生成时间-yyyymmddhhmmss
time_expire: moment(order.pay_expire).format('YYYYMMDDHHmmss'), // 订单失效时间--yyyymmddhhmmss
attach: extraParam // 附加数据,原样返回
};
let signStr = md5(sign.raw(params) + '&key=' + payParams.merchant_key).toLocaleUpperCase();
let body = sign.rawUncode(params) + '&sign=' + signStr;
return {
code: 200,
data: {
href: PAY_URL + body
}
};
},
notify(data, param) {
let payParams = JSON.parse(param.payParams || '{}');
let orderCode = parseInt(data.out_trade_no, 10);
logger.info(`Alipay notify, params = ${JSON.stringify(data)}`);
if (!this.checkNotify(data, payParams)) {
return {payResult: -1};
}
return {
bankName: '',
orderCode: orderCode,
payResult: 200,
totalFee: data.total_fee * 0.01,
tradeNo: data.transaction_id,
bankBillNo: ''
};
},
checkNotify(data, payParams) {
let signValue;
if (data && parseInt(data.trade_state, 10) !== 0) {
return false;
}
signValue = data.sign;
delete data.sign;
let signStr = md5(sign.raw(data) + '&key=' + payParams.merchant_key).toLocaleUpperCase();
return signValue === signStr;
}
};
module.exports = Tenpay;
... ...
/**
* @author: xiaoxiao.hao<xiaoxiao.hao@yoho.cn>
* @date: 2017/3/23
*/
'use strict';
const ServiceAPI = global.yoho.ServiceAPI;
const helpers = global.yoho.helpers;
const PAY_URL = 'https://gateway.95516.com/gateway/api/frontTransReq.do';
const Unionpay = {
pay(user, order, info) {
return ServiceAPI.get('payment/unionpay_data', {
order_code: order.order_code,
payment_code: info.id,
uid: user.uid,
front_url: info.protocol + ':' + helpers.urlFormat('/shopping/newpay/callback/unionpay')
}).then(result => {
if (result && result.code === 200 && result.data) {
return {
code: 200, // reqType是post方式,默认
data: Object.assign({reqType: PAY_URL}, result.data)
};
}
return {
code: 400,
message: result.message
};
});
},
notify(data) {
let orderCode = parseInt(data.orderId, 10);
// https://open.unionpay.com/ajweb/help/faq/list?id=234&level=0&from=0
if (!data.respCode || (data.respCode.indexOf('00') < 0 && data.respCode.indexOf('A6') < 0)) {
return {payResult: -1};
}
return {
bankName: '',
orderCode: orderCode,
payResult: 200,
totalFee: data.txnAmt * 0.01,
tradeNo: data.queryId,
bankBillNo: ''
};
}
};
module.exports = Unionpay;
... ...
/**
* @author: xiaoxiao.hao<xiaoxiao.hao@yoho.cn>
* @date: 2017/3/23
*/
'use strict';
const ServiceAPI = global.yoho.ServiceAPI;
const helpers = global.yoho.helpers;
const Wechat = {
pay(user, order, info) {
return ServiceAPI.get('payment/weixin_data', {
order_code: order.order_code,
payment_code: info.id,
app_key: 'yohopc'
}).then(result => {
if (result && result.code === 200 && result.data) {
let url = `/shopping/newpay/weixin?url=${result.data.codeUrl}&code=${order.order_code}`;
return {
code: 200,
data: {
href: helpers.urlFormat(url)
}
};
} else {
return {
code: 400,
message: result.message
};
}
});
}
};
module.exports = Wechat;
... ...
/**
* 各种支付的入口
*
* @author: xiaoxiao.hao<xiaoxiao.hao@yoho.cn>
* @date: 16/7/22
*/
'use strict';
const Promise = require('bluebird');
const PayData = require('../models/pay');
const Alipay = require('./pay/alipay');
const Wechat = require('./pay/wechat');
const Unionpay = require('./pay/unionpay');
const Alibank = require('./pay/alibank');
const Tenpay = require('./pay/tenpay');
const Chinabank = require('./pay/chinabank');
const common = require('./pay/common');
const co = Promise.coroutine;
const logger = global.yoho.logger;
const md5 = require('md5');
const paySign = require('./pay/sign');
const helpers = global.yoho.helpers;
const _ = require('lodash');
const Payment = {
pay(user, order, payType, protocol) {
return co(function*() {
let result = {
code: 400,
message: '获取支付方式信息失败'
};
let paymentPars = payType.split('_');
let payInfo;
let bankCode = '';
if (paymentPars.length !== 2) {
return result;
}
if (!order.order_code) {
result.message = '没有找到该订单';
return result;
}
if (order.is_cancel && order.is_cancel === 'Y') {
result.message = '该订单已经取消';
return result;
}
if (order.pay_expire && common.getPayExpireMin(order.pay_expire) <= 0) {
result.message = '当前订单不可支付';// 该订单已超过2个小时
return result;
}
let method = parseInt(paymentPars[0], 10);
if (method === PayData.payments.wechat) {
// 如果是微信支付,不需要调用获取支付方式详情接口
result = yield Wechat.pay(user, order, {id: method});
} else if (method === PayData.payments.unionpay) {
// 不需要调用获取支付方式详情接口
result = yield Unionpay.pay(user, order, {id: method, protocol: protocol});
} else {
payInfo = yield PayData.getPaymentInfo(method);
if (!payInfo.payParams) {
return result;
}
switch (payInfo.id) {
case PayData.payments.alipay:
result = Alipay.pay(user, order, payInfo, protocol);
break;
case PayData.payments.tenpay:
result = Tenpay.pay(user, order, payInfo, protocol);
break;
case PayData.payments.chinabank:
result = Chinabank.pay(user, order, payInfo, protocol);
break;
case PayData.payments.alibank:
bankCode = paymentPars[1];
payInfo.bankCode = bankCode;// 设置默认银行
result = Alibank.pay(user, order, payInfo, protocol);
break;
default:
break;
}
}
logger.info(`pay to url, params = ${JSON.stringify(result)}`);
if (result.code === 200) {
let updateInfo = yield Payment.beforePay(user, order, method, bankCode);
if (updateInfo && updateInfo.code !== 200) {
return updateInfo;
}
}
return result;
})();
},
beforePay(user, order, method, bankCode) {
return Promise.all([
PayData.updateOrderPayment(order.order_code, method, user.uid),
PayData.getBankByOrder(order.order_code)
]).then(result => {
let paymentRecord = result[0];
let bankRecord = result[1];
if (!paymentRecord || paymentRecord.code !== 200) {
let message = paymentRecord && paymentRecord.message ? paymentRecord.message : '系统繁忙,请稍后再试';
return {code: 400, message: message};
}
if (bankRecord && bankRecord.bankCode) {
return PayData.updateOrderPayBank(order.order_code, method, bankCode);
} else {
return PayData.setOrderPayBank(order.order_code, method, bankCode);
}
}).catch(e => {
logger.error('update order pay info error.', e);
return Promise.resolve({
code: 400,
message: '更新订单支付信息失败'
});
});
},
_validate(query, payId, user) {
return co(function*() {
let payInfo = yield PayData.getPaymentInfo(payId);
let payResult = {};
let payData = {};
let payName = '';
let isPcpayNotify = false;// 回调地址,java未做,走前端逻辑
if (payId === PayData.payments.alipay) {
payResult = Alipay.notify(query, payInfo);
} else if (payId === PayData.payments.alibank) {
payResult = Alibank.notify(query, payInfo);
} else if (payId === PayData.payments.unionpay) {
payResult = Unionpay.notify(query);
} else if (payId === PayData.payments.tenpay) {
payResult = Tenpay.notify(query, payInfo);
isPcpayNotify = true;
} else if (payId === PayData.payments.chinabank) {
payResult = Chinabank.notify(query, payInfo);
isPcpayNotify = true;
}
payResult.bankName = payName = (payResult.bankName || payInfo.payName || '');
payResult.bankCode = (payResult.bankCode || '');
// 记录日志
logger.info(`\r\n\r\n pay back confirmreq = ${JSON.stringify({
query: query,
payId: payId,
user: user,
payResult: payResult
})}`);
if (payResult && payResult.payResult === 200) {
if (payResult.orderCode) {
logger.info('pay back confirm');
PayData.sendPayConfirm(payResult.orderCode, payId, user.uid);
}
payData = yield PayData.procOrderData(payResult, user.uid, payId);
if (isPcpayNotify && payData.code === 200 && payData.data.order.payment_status === 'N') {
// 更新订单状态
yield PayData.pcpayNotify(Object.assign({payId: payId}, payResult));
}
} else {
payData = {
code: 500,
message: '支付失败'
};
}
payData.payName = payName;
return payData;
})();
},
afterPay(query, payId, user) {
let _this = this;
return co(function*() {
let payData = {code: 500, message: '支付失败'};
let sign = query.sign || '';
switch (payId) {
case PayData.payments.wechat: // 微信支付不须要验证,但前端必须校验sign
delete query.sign;
if (md5(paySign.raw(Object.assign({tradeStatus: 'Y'}, query))) === sign) {
payData = yield PayData.procOrderData(query, user.uid, payId);
}
payData.payName = '微信';
break;
default:// 须要验证的支付方式
payData = _this._validate(query, payId, user);
break;
}
return payData;
})();
},
getWxSign(uid, code) {
return PayData.orderDetail(uid, code).then(result => {
let data = {};
result = (result.code === 200 ? result.data : {});
if (result.is_cancel === 'Y') {
return {
code: 401,
message: '订单已取消'
};
}
if (result.payment_status === 'Y') {
let payParams = {
orderCode: code,
tradeStatus: 'Y',
totalFee: _.round(parseFloat(result.payment_amount), 2)
};
data = {
code: 200,
data: {
href: helpers.urlFormat('/shopping/newpay/callback/wechat', Object.assign(payParams, {
sign: md5(paySign.raw(payParams))
}))
}
};
}
return data;
});
},
// 异步通知地址
notifyPay(query, payId) {
return co(function*() {
let d = '';
let payInfo = yield PayData.getPaymentInfo(payId);
if (payId === PayData.payments.tenpay) {
let payResult = Tenpay.notify(query, payInfo);
if (payResult.payResult === 200) {
// 更新订单状态
yield PayData.pcpayNotify(Object.assign({payId: payId}, payResult));
return 'success';
}
return 'fail';
}
return d;
})();
}
};
module.exports = Payment;
... ...
/**
* sub app shopping
* @author: xiaoxiao.hao<xiaoxiao.hao@yoho.cn>
* @date: 2017/03/20
*/
var express = require('express'),
path = require('path');
var app = express();
// set view engin
var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root
app.on('mount', function(parent) {
delete parent.locals.settings; // 不继承父 App 的设置
Object.assign(app.locals, parent.locals);
});
app.use(global.yoho.hbs({
extname: '.hbs',
defaultLayout: 'layout',
layoutsDir: doraemon,
partialsDir: [path.join(__dirname, 'views/partial')],
views: path.join(__dirname, 'views/action'),
helpers: global.yoho.helpers
}));
// router
app.use(require('./router'));
module.exports = app;
... ...
/**
* 支付相关api调用
* @author: jiangfeng<jeff.jiang@yoho.cn>
* @date: 2016/07/18
*/
'use strict';
const api = global.yoho.API;
const serviceApi = global.yoho.ServiceAPI;
// 获取支付宝等平台支付方式列表
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
});
};
/**
* [订单详情]
* @param {[type]} uid [用户uid]
* @param {[type]} orderCode [订单号]
* @return {[type]} [{}]
*/
const orderDetail = (uid, orderCode)=>{
return api.get('', {
method: 'app.SpaceOrders.detail',
uid: uid,
order_code: orderCode
});
};
/**
* [更新订单支付方式]
* @param {[type]} code [订单号]
* @param {[type]} payment [支付方式]
* @param {[type]} uid [用户uid]
* @return {[type]} [{}]
*/
const updateOrderPayment = (code, payment, uid) => {
return api.get('', {
method: 'app.SpaceOrders.updateOrdersPaymentByCode',
order_code: code,
payment: payment,
uid: uid
});
};
/**
* [获取资源数据]
* @param {[type]} code [资源位code]
* @return {[type]} [{}]
*/
const getResourceData = (code) => {
return serviceApi.get('operations/api/v5/resource/get', {
content_code: code
}, {
cache: true
});
};
/**
* [获取用户的订单数目]
* @param {[type]} uid [用户uid]
* @return {[type]} [{}]
*/
const getOrderCountByUid = (uid) => {
return api.get('', {
method: 'web.SpaceOrders.getOrderCountByUid',
uid: uid
});
};
/**
* [更新订单状态]
* @param {[type]} code [订单号]
* @param {[type]} payment [支付方式]
* @param {[type]} amount [金额(单位:元)]
* @param {[type]} bankName [银行名称]
* @param {[type]} bankCode [银行代码]
* @param {[type]} tradeNo [交易流水号]
* @param {[type]} bankBillNo [银行流水号]
* @return {[type]} [{}]
*/
const pcpayNotify = (code, payment, amount, bankName, bankCode, tradeNo, bankBillNo) => {
let params = {
method: 'web.SpaceOrders.pcpayNotify',
order_code: code,
payment: payment,
amount: amount,
bank_name: bankName || '',
bank_code: bankCode || '',
trade_no: tradeNo || '',
bank_bill_no: bankBillNo || ''
};
return api.get('', params);
};
module.exports = {
getPayProvider,
getPaymentInfo,
getBankByOrder,
setOrderPayBank,
updateOrderPayBank,
sendPayConfirm,
sendMessage,
orderDetail,
updateOrderPayment,
getResourceData,
getOrderCountByUid,
pcpayNotify
};
... ...
/**
* 订单支付
* @author: xiaoxiao.hao<xiaoxiao.hao@yoho.cn>
* @date: 2016/07/18
*/
'use strict';
const payApi = require('./pay-api');
const Promise = require('bluebird');
const co = Promise.coroutine;
const payHelpersBank = require('./../helpers/bank');
const logger = global.yoho.logger;
const _ = require('lodash');
const helpers = global.yoho.helpers;
const FRAUD_CONTENT_CODE = '78d0fb6c97d691863286edcb4d8abfa9';
const payments = {
alipay: 2, // 支付宝
wechat: 21, // 微信支付
alibank: 12, // 支付宝支联
unionpay: 25, // 银联支付
chinabank: 4, // 网银在线
tenpay: 1, // 财付通
delivery: 3 // 货到付款和0元订单
};
/**
* [更新订单支付方式]
* @param {[type]} code [订单号]
* @param {[type]} payment [支付方式]
* @param {[type]} uid [用户uid]
* @return {[type]} [{}]
*/
const updateOrderPayment = (code, payment, uid) => {
return payApi.updateOrderPayment(code, payment, uid);
};
/**
* [订单详情]
* @param {[type]} uid [用户uid]
* @param {[type]} orderCode [订单号]
* @return {[type]} [{}]
*/
const orderDetail = (uid, orderCode)=>{
return payApi.orderDetail(uid, orderCode);
};
/**
* 获取在线支付方式
* @returns {*|Promise.<TResult>}
*/
const getOnlinePayProvider = () => {
return payApi.getPayProvider().then(result => {
let payPattern = [], nav = [];
if (!(result.code && result.code === 200)) {
return payPattern;
}
// 处理支付宝等平台数据
_.each(result.data, val => {
// 去除icon为空的
if (_.isEmpty(val.payIcon)) {
return true;
}
// 财付通和网银关闭
if (val.id === 4 || val.id === 1) {
return true;
}
nav.push({
id: val.id,
name: val.payName,
value: val.id + '_platform',
img: val.payIcon
});
});
payPattern.push({
name: '支付宝等平台',
children: nav
});
// 处理使用银行卡数据
nav = [];
_.each(payHelpersBank.getList(), (val, key) => {
nav.push({
id: payments.alibank,
name: val.name,
value: payments.alibank + '_' + key,
img: val.ico
});
});
payPattern.push({
name: '使用银行卡',
children: nav
});
return payPattern;
});
};
/**
* 获取订单详情
* @param uid
* @param code
*/
const getOrderInfo = (uid, code) => {
return orderDetail(uid, code).then(data => {
return data && data.code === 200 && data.data || {};
});
};
/**
* 获取订单支付银行信息
* @param id
*/
const getBankByOrder = (id) => {
return payApi.getBankByOrder(id).then(data => {
return data && data.code === 200 && data.data || {};
});
};
/**
* 获取支付页数据
* @param uid
* @param code
*/
const getPayInfo = (uid, code) => {
return Promise.all([
getOnlinePayProvider(),
getOrderInfo(uid, code),
getBankByOrder(code),
payApi.getOrderCountByUid(uid)
]).then(payment => {
let paymentId = parseInt(payment[2].payment || 0, 10);
let orderInfo = payment[1] || {};
let findIndex;
let payDefault;
// 渲染选择的默认支付方式
if (paymentId === payments.alibank && payment[0][1] && payment[2]) { // 银行支付
findIndex = _.findIndex(payment[0][1].children, {value: payments.alibank + '_' + payment[2].bankCode});
findIndex = findIndex > 0 ? findIndex : 0;
payment[0][1].selected = true;
payment[0][1].children[findIndex].selected = true;
payDefault = payment[0][1].children[findIndex];
} else if (payment[0] && payment[0][0]) { // 支付宝等平台
findIndex = _.findIndex(payment[0][0].children, {id: paymentId});
findIndex = findIndex > 0 ? findIndex : 0;
payment[0][0].selected = true;
payment[0][0].children[findIndex].selected = true;
payDefault = payment[0][0].children[findIndex];
}
if (orderInfo.order_code) {
// 订单处理
if (orderInfo.attribute === 3) {
orderInfo.deliveryTimes = '自动发货 - 在您支付成功后,系统将立即为您发放二维码,您可以在您的订单中查看。';
} else {
orderInfo.deliveryTimes = orderInfo.delivery_time || '';
}
// 用于订单统计
orderInfo.uid = uid;
orderInfo.orderCount = 0;
if (payment[3].code === 200 && payment[3].data) {
orderInfo.orderCount = payment[3].data.count || 0;
}
orderInfo.isOldUser = orderInfo.orderCount > 1;
orderInfo.ordersGoodsNums = orderInfo.order_goods.length;
let sknList = [];
let skuList = [];
let goodsData = [];
let pinyouGoodsArr = [];
_.each(orderInfo.order_goods, function(el) {
sknList.push(el.product_skn);
skuList.push(el.product_sku);
goodsData.push({
goods_name: el.product_name,
product_sku: el.product_sku,
price: el.goods_price,
number: el.buy_number
});
pinyouGoodsArr.push(`${el.product_skn},${el.buy_number}`);
});
orderInfo.sknList = sknList;
orderInfo.skuList = skuList;
orderInfo.goodsData = goodsData;
orderInfo.goodsDatas = JSON.stringify(goodsData);
// 品友统计需要的商品数据
orderInfo.pinyouGoods = pinyouGoodsArr.join(';');
}
return {
pay: payment[0],
order: orderInfo,
payDefault: payDefault
};
});
};
/**
* 获取支付方式的相关参数, (密钥等信息)
* @param id
*/
const getPaymentInfo = (id) => {
return co(function *() {
let data = yield payApi.getPaymentInfo(id);
return data && data.code === 200 && data.data || {};
})();
};
/**
* 设置订单支付银行
* @param code
* @param payment
* @param bankCode
*/
const setOrderPayBank = (code, payment, bankCode) => {
return co(function *() {
return yield payApi.setOrderPayBank(code, payment, bankCode);
})();
};
/**
* 更新订单支付银行
* @param code
* @param payment
* @param bankCode
*/
const updateOrderPayBank = (code, payment, bankCode) => {
return co(function *() {
return yield payApi.updateOrderPayBank(code, payment, bankCode);
})();
};
/**
* 支付确认
* @param code
* @param payment
* @param uid
*/
const sendPayConfirm = (code, payment, uid) => {
return co(function *() {
return yield payApi.sendPayConfirm(code, payment, uid);
})();
};
/**
* [埋点数据公共处理]
* @param {[type]} orderInfo [订单详情]
* @param {[type]} payId [支付方式id]
* @param {[type]} payResultStatus [支付成功状态]
* @return {[type]} [{}]
*/
const _point = (orderInfo, payId, payResultStatus) => {
let sknArr = [];
let skuArr = [];
_.each(orderInfo.order_goods, function(el) {
sknArr.push(el.product_skn);
skuArr.push(el.product_sku);
});
return {
order_code: orderInfo.order_code,
payResult: payResultStatus, // 1支付成功,2支付失败
amount: orderInfo.payment_amount,
payStyle: payId, // 支付方式id
proSkn: sknArr.join(','),
proSku: skuArr.join(',')
};
};
/**
* [公共支付成功数据处理]
* @param {[type]} orderInfo [订单信息]
* @param {[type]} fraudData [资源位数据]
* @param {[type]} payId [支付方式ID]
* @return {[type]} [{}]
*/
const _execOrderData = (orderInfo, fraudData, payId) => {
let fraud = _.result(_.find(fraudData, {template_name: 'text'}), 'data') || {};
return {
paymentTypes: (orderInfo.payment_type === 1 ? '在线支付' : '货到付款'),
multiPackage: orderInfo.is_multi_package === 'Y',
ordersUrl: helpers.urlFormat('/home/orders'),
vipUrl: helpers.urlFormat('/help/detail', {id: 9}),
returnGoodsUrl: helpers.urlFormat('/help/detail', {id: 49}),
yohoCoinUrl: helpers.urlFormat('/help/detail', {id: 105, contId: 233}),
detailUrl: helpers.urlFormat('/home/orders/detail', {
orderCode: orderInfo.order_code
}),
packageTitle: orderInfo.package_title || '商品需要品牌商调货',
fraudTip: fraud.text || '',
criteo: {// criteo统计代码有关数据
order_code: orderInfo.order_code,
items: orderInfo.order_goods
},
point: _point(orderInfo, payId, 1)
};
};
/**
* 支付成功,前端回调时,处理订单信息
* @param payResult
* @param uid
*/
const procOrderData = (payResult, uid, payId) => {
return co(function *() {
let orderCode = payResult.orderCode;
let result = {code: 400, message: ''};
if (!orderCode) {
result.message = '订单不存在';
return result;
}
return Promise.all([orderDetail(uid, orderCode), payApi.getResourceData(FRAUD_CONTENT_CODE)]).then(procData => {
let orderInfo = procData[0].code === 200 && procData[0].data;
if (!orderInfo) {
result.message = '订单不存在!';
return result;
}
if (orderInfo.is_cancel === 'Y') {
logger.warn('front pay success but order is cancel.', {payResult: payResult, order: orderInfo});
return {code: 417, message: '支付成功,但订单已取消,需联系客服!', point: _point(orderInfo, payId, 2)};
}
if (orderInfo.payment_status === 'N') {
logger.warn('front pay success but may be notify fail');
}
if (_.round(parseFloat(orderInfo.payment_amount), 2) !== _.round(parseFloat(payResult.totalFee), 2)) {
logger.warn('front pay success but the amount is not same.', {payResult: payResult, order: orderInfo});
return {
code: 415,
message: '支付金额与订单金额不一致,订单状态更新失败!',
point: _point(orderInfo, payId, 2)
};
}
return {
code: 200,
message: '支付成功,请等待发货',
data: {
order: Object.assign(
orderInfo,
_execOrderData(orderInfo, procData[1] && procData[1].data || {}, payId)
)
}
};
});
})();
};
/**
* [0元订单或者货到付款-成功处理]
* @param {[type]} orderInfo [订单详情]
* @param {[type]} payId [支付方式ID]
* @return {[type]} [{}]
*/
const deliveryData = (orderInfo, payId) => {
return payApi.getResourceData(FRAUD_CONTENT_CODE).then(procData => {
return Object.assign(orderInfo, _execOrderData(orderInfo, procData && procData.data || {}, payId));
});
};
const pcpayNotify = (param) => {
return co(function *() {
return yield payApi.pcpayNotify(
param.orderCode, param.payId, param.totalFee, param.bankName || '',
param.bankCode || '', param.tradeNo || '', param.bankBillNo || ''
);
})();
};
module.exports = {
orderDetail,
getPayInfo,
getPaymentInfo,
getBankByOrder,
setOrderPayBank,
updateOrderPayBank,
sendPayConfirm,
procOrderData,
updateOrderPayment,
payments,
deliveryData,
pcpayNotify
};
... ...
/**
* router of sub app shopping
* @author: xiaoxiao.hao<xiaoxiao.hao@yoho.cn>
* @date: 2017/03/20
*/
'use strict';
const router = require('express').Router(); // eslint-disable-line
const cRoot = './controllers';
const auth = require(`${global.middleware}/auth`);
const pay = require(`${cRoot}/pay`); // 支付
// 支付
router.get('/newpay', auth, pay.online);
router.get('/newpay/weixin', auth, pay.weixinQr);
router.post('/newpay/weixin/state', auth, pay.weixinPayState);
router.post('/newpay/go', auth, pay.toPay);
router.post('/newpay/sendPayConfirm', auth, pay.sendPayConfirm);
// 支付回调
router.get('/newpay/callback/:type', auth, pay.callback);
router.post('/newpay/callback/:type', auth, pay.callback);// 银联是post方式返回的
// 支付异步回调
router.get('/newpay/notify/:type', auth, pay.notify);
module.exports = router;
... ...
<div class="pay-notice-wechatqrcodereturn-page yoho-page clearfix">
<div class="wechatqrcodereturn">
<div class="pay-title">
<div class="step5"></div>
<ul>
<li><span>查看购物车</span></li>
<li><span>填写订单</span></li>
<li class="end"><span>付款,完成购买</span></li>
</ul>
</div>
<div class="pay-wechat-return">
<p class="payerror">
很抱歉,订单支付失败,请立即联系客服!
</p>
<p class="arrival-time">
客服电话:
<b class="tell-phone">
400-889-9646
</b>
</p>
</div>
<div class="cart-bigbtns">
<span class="btn-type">
<a href="/">返回首页</a>
</span>
</div>
<div class="we-alert">
<span class="we-font">感谢您选择 {{payName}} 的方式,我们的客服随后会和您确认订单。</span>
</div>
</div>
</div>
{{> pay/point}}
... ...
<div class="pay-notice-page yoho-page">
{{# order}}
<div class="order-wrap">
<h1>
<i class="pay-sure-icon"></i>
{{#if ../isDelivery}}订单提交成功!您需要在收货时向送货员支付{{else}}恭喜您,购买完成!您已成功支付{{/if}}
<span class="red">{{payment_amount}}</span>元!
</h1>
<div class="order-info">
<ul>
<li><span class="l-b">订单号: {{order_code}}</span></li>
<li><span class="l-b">订单金额: {{payment_amount}}</span></li>
<li>
<span class="l-b back-yoho-coin">共返有货币:{{yoho_give_coin}}</span>
<a href="{{yohoCoinUrl}}" class="notice-link" target="_blank">有货币能做什么>></a>
</li>
<li>
<span class="l-b">获得VIP累计金额:{{payment_amount}}</span>
<a href="{{vipUrl}}" class="notice-link" target="_blank">查看VIP特权>></a>
</li>
<li class="opt-btns">
<a href="{{detailUrl}}">查看订单详情</a>
<a href="/">继续逛逛</a>
</li>
</ul>
</div>
</div>
<div class="extra-wrap">
<h5>温馨提示:</h5>
{{#if multiPackage}}
<p>
1.{{packageTitle}}至有货仓库,预计3-5日内发货给您。<br>
2.当订单发货后,您可以登录<a href="{{ordersUrl}}" class="notice-link" target="_blank">订单中心</a>查询快递发货详情。<br>
3.YOHO!BUY有货支持 “开箱验货” 和 “15天退换货保障”,收货后请当面验货,如果发现商品有任何问题请致电客服电话400-889-9646,
<a href="{{returnGoodsUrl}}" class="notice-link" target="_blank">“退换货政策”</a> 请点击查看。<br>
4.VIP金额的累计,将在您订单签收15天后积累到您的账户,请您知悉。<br>
5.购买商品及参与促销活动赠送的有货币,将在您订单签收7天后积累到您的账户,您可以在个人中心-我的有货币中查看。<br>
{{#if fraudTip}}
<span class="red">6.{{{fraudTip}}}</span>
{{/if}}
</p>
{{^}}
<p>
1.当订单发货后,您可以登录<a href="{{ordersUrl}}" class="notice-link" target="_blank">订单中心</a>查询快递发货详情。<br>
2.YOHO!BUY有货支持 “开箱验货” 和 “15天退换货保障”,收货后请当面验货,如果发现商品有任何问题请致电客服电话400-889-9646,
<a href="{{returnGoodsUrl}}" class="notice-link" target="_blank">“退换货政策”</a> 请点击查看。<br>
3.VIP金额的累计,将在您订单签收15天后积累到您的账户,请您知悉。<br>
4.购买商品及参与促销活动赠送的有货币,将在您订单签收7天后积累到您的账户,您可以在个人中心-我的有货币中查看。<br>
{{#if fraudTip}}
<span class="red">5.{{{fraudTip}}}</span>
{{/if}}
</p>
{{/if}}
</div>
<div class="best-for-you"></div>
{{> pay/pay-analysis}}
{{> pay/point}}
{{/order}}
</div>
... ...
<div class="shopping-pay-page yoho-page clearfix">
<div class="pay-page">
<div class="pay-title">
<div class="step4"></div>
<ul>
<li><span>查看购物车</span></li>
<li><span>填写订单</span></li>
<li class="end"><span>付款,完成购买</span></li>
</ul>
</div>
{{# order}}
<div class="cart-pay">
<h2>您的订单已成功,现在就去付款吧~</h2>
<h3>您的订单号:<strong class="order-num">{{order_code}}</strong> 应付金额:<strong>{{payment_amount}}</strong>&nbsp; &nbsp;
支付方式:在线支付 &nbsp; &nbsp; &nbsp; 送货时间:{{deliveryTimes}}</h3>
<h4>{{../username}},如果2小时内您无法完成付款,系统会将您的订单取消。</h4>
</div>
{{/order}}
<div class="wrapper">
<div class="pay-way">
<span class="word">使用:</span>
<img src="{{payDefault.img}}" class="pay-type-img" id="show-pay-img">
</div>
<div id="tab-box">
<ul class="tabs" id="tabs">
{{# pay}}
<li{{#if selected}} class="active"{{/if}}>{{name}}</li>
{{/pay}}
</ul>
<ul class="tab-conbox">
{{# pay}}
<li class="tab-con {{#unless selected}} hide{{/unless}}">
{{# children}}
<div class="mode{{#if selected}} active{{/if}}" data-id="{{id}}" data-value="{{value}}" data-name="{{name}}">
<span class="choosed-tag"></span>
<img src="{{img}}" alt="{{name}}" />
</div>
{{/children}}
</li>
{{/pay}}
</ul>
</div>
<div>
<input type="button" class="btnby " data-order="{{order.order_code}}" data-amount="{{order.payment_amount}}" value="前往{{payDefault.name}}" />
</div>
</div>
<div class="light-box">
<div class="opacity" id="fade"></div>
<div class="content" id="light">
<h2>请您在新打开的页面上完成付款</h2>
<div class="notice">
<p>付款完成前请不要关闭此窗口</p>
<p>完成付款后请根据您的情况点击下面的按钮</p>
</div>
<div class="btns">
<a href="javascript:void(0);" data-url = "{{ordersUrl}}"class="over">已完成付款</a>
<a href="#" class="change">更换支付方式</a>
</div>
<a href="#" class="close">x</a>
</div>
</div>
</div>
</div>
{{!--银联支付跳转地址--}}
<form action="" method="post" class='form-go hide' target="_blank"></form>
{{!--下面是统计,不确定有没有作用--}}
{{# order}}
<!-- Google Code for &#19979;&#21333;&#25104;&#21151; Conversion Page -->
<script type="text/javascript">
/* <![CDATA[ */
var google_conversion_id = 959290965;
var google_conversion_language = "zh_CN";
var google_conversion_format = "2";
var google_conversion_color = "ff0000";
var google_conversion_label = "n6GICNu3-AIQ1by2yQM";
var google_conversion_value = 100;
/* ]]> */
</script>
<script type="text/javascript" src="//www.googleadservices.com/pagead/conversion.js"></script>
<noscript>
<div style="display: inline;">
<img height="1" width="1" style="border-style: none;" alt=""
src="//www.googleadservices.com/pagead/conversion/959290965/?value=100&amp;label=n6GICNu3-AIQ1by2yQM&amp;guid=ON&amp;script=0"/>
</div>
</noscript>
<!-- Google Code for &#35746;&#21333;&#23436;&#25104;&#39029;-&#25628;&#32034; Conversion Page -->
<script type="text/javascript">
/* <![CDATA[ */
var google_conversion_id = 991392201;
var google_conversion_language = "en";
var google_conversion_format = "2";
var google_conversion_color = "ffffff";
var google_conversion_label = "asUdCK_i0AQQyePd2AM";
var google_conversion_value = 0;
/* ]]> */
</script>
<script type="text/javascript" src="//www.googleadservices.com/pagead/conversion.js"></script>
<script type="text/javascript">
_ozprm = "orderid={{order_code}}";
</script>
<noscript>
<div style="display:inline;">
<img height="1" width="1" style="border-style:none;" alt=""
src="//www.googleadservices.com/pagead/conversion/991392201/?value=0&amp;label=asUdCK_i0AQQyePd2AM&amp;guid=ON&amp;script=0"/>
</div>
</noscript>
<script type="text/javascript">
<!--
(function (d) {
window.bd_cpro_rtid = "P1fsP10";
var s = d.createElement("script");
s.type = "text/javascript";
s.async = true;
s.src = location.protocol + "//cpro.baidu.com/cpro/ui/rt.js";
var s0 = d.getElementsByTagName("script")[0];
s0.parentNode.insertBefore(s, s0);
})(document);
//-->
</script>
{{> pay/box-analysis}}
{{> pay/box-buy-analysis}}
{{/ order}}
... ...
<div class="pay-wechatqrcode-page yoho-page clearfix">
<div class="pay-title">
<div class="step4"></div>
<ul>
<li><span>查看购物车</span></li>
<li><span>填写订单</span></li>
<li class="end"><span>付款,完成购买</span></li>
</ul>
</div>
{{# order}}
<div class="w-title">
<div class="w-left">
<h3>请您及时付款,以便订单尽快处理!订单号:{{order_code}}</h3>
<p>
请您提交订单
<span>2小时</span>
内完成,否则订单会自动取消。
</p>
</div>
<div class="w-right">
<p>应付金额<strong>{{payment_amount}}</strong></p>
<a href="#" class="w-odetail">订单详情
<i class="up"></i>
</a>
</div>
</div>
<div class="w-addrinfo">
<p>
收货地址: {{area}} {{address}}
<span>收货人:{{user_name}}</span>
{{mobile}}
</p>
{{#each order_goods}}
{{#if @first}}
<p>商品名称:{{product_name}}</p>
{{/if}}
{{/each}}
</div>
<div class="w-payment" data-order={{order_code}}>
<h2>微信支付</h2>
<div class="w-p-weixin">
<div class="w-p-erm" data-url="{{../qrcodeUrl}}"></div>
<div class="w-p-word">
<p>请使用微信扫一扫</p>
<p>扫描二维码支付</p>
</div>
</div>
<a href="{{../choosePayUrl}}" class="w-pay-change">
<i>&lt;</i>
选择其他支付方式
</a>
</div>
{{/ order}}
</div>
... ...
<script type="text/javascript">
var dataLayer = dataLayer || [];
dataLayer.push({userid: '{{uid}}'});
dataLayer.push({orderid: '{{order_code}}'});
dataLayer.push({ordersum: '{{payment_amount}}'});
dataLayer.push({ordercount: '{{ordersGoodsNums}}'});
/*单条订单中包含的真实订单数目*/
dataLayer.push({ordernew: {{#if isOldUser}}0{{else}}1{{/if}} })
/*是否新客单,是为1,不是为0*/
</script>
... ...
{{#if order_goods}}
<script type="text/javascript">
var ga = ga || function () {
(ga.q = ga.q || []).push(arguments)
};
ga('require', 'ecommerce', 'ecommerce.js'); //固定引用ecommerce.js
ga('ecommerce:addTransaction', { //收集订单数据
'id': '{{order_code}}', // Transaction ID. Required.
'affiliation': 'YOHOBUY', // Affiliation or store name.
'revenue': '{{payment_amount}}', // Grand Total.
'shipping': '1.0', // Shipping.
'tax': '0' // Tax.
});
{{#order_goods}}
ga('ecommerce:addItem', { //收集商品数据
'id': '{{../order_code}}', // Transaction ID. Required.
'name': '{{product_name}}', // Product name. Required.
'sku': '{{product_sku}}', // SKU/code.
'category': 'Olive Medium', // Category or variation.
'price': '{{goods_price}}', // Unit price.
'quantity': '{{buy_number}}' // Quantity.
});
{{/order_goods}}
ga('ecommerce:send'); //发送电子商务跟踪数据
ga('myTracker.ecommerce:send');
</script>
<script src="//static.yohobuy.com/js/AG_Tracking.js?v=20121102"></script>
<script type="text/javascript">
//请将js代码嵌入到html中body标签结束之前。(整个body部分最后边)
var _agq = _agq || [];
_agq.push(['_cid', '415']); //生成value
_agq.push(['_eid', '102']); //生成value
//以下参数需要客户配合填写。**为需要替代内容
_agq.push(['_orderSum', '{{payment_amount}}']);//订单金额,客户在页面填写
_agq.push(['_orderNo', '{{order_code}}']);//订单号,客户在页面填写
_agq.push(['_orderNew','{{#if isOldUser}}false{{else}}true{{/if}}']);//是否新客单,客户标记是为true否为false
_agq.push(['_orderCount', '{{ordersGoodsNums}}']);//订单货品数目,客户填写
ag_send(_agq);
var __order_code = '{{order_code}}';
var __order_amount = '{{payment_amount}}';
var __order_user = '{{#if isOldUser}}old{{else}}new{{/if}}';
var __order_uid = '{{uid}}';
var __order_goods_num = '{{ordersGoodsNums}}';
var __order_goods = '{{goodsDatas}}';
</script>
<script type="text/javascript">
var _mvq = window._mvq || [];
window._mvq = _mvq;
_mvq.push(['$setAccount', 'm-23428-1']);
_mvq.push(['$setGeneral', 'ordercreate', '', /*用户名*/ '', /*用户id*/ '{{uid}}']);
_mvq.push(['$logConversion']);
_mvq.push(['$addOrder', /*订单号*/ '{{order_code}}', /*订单金额*/ '{{payment_amount}}']);
_mvq.push(['$logData']);
</script>
{{/if}}
... ...
{{# criteo}}
<script type="text/javascript" src="//static.criteo.net/js/ld/ld.js" async="true"></script>
<script type="text/javascript">
window.criteo_q = window.criteo_q || [];
window.criteo_q.push(
{ event: "setAccount", account: [16184] },
{ event: "setSiteType", type: "d" },
{ event: "trackTransaction" , id: "{{order_code}}", item: [
{{#each items}}
{ id: "{{product_skn}}", price: "{{goods_price}}", quantity: "{{buy_number}}"}
{{#unless @last}}
,
{{/unless}}
{{/each}}
]}
);
</script>
{{/ criteo}}
... ...
{{# point}}
<script type="text/javascript">
window.onload = function () {
// 埋点
window._yas && window._yas.sendCustomInfo && window._yas.sendCustomInfo({
op: 'YB_SC_PAY_RES',
param: JSON.stringify({
C_ID: window._ChannelVary[window.cookie('_Channel')] || 1,
ORDER_CODE: "{{order_code}}",
PAY_RES: "{{payResult}}",
ORDER_AMOUNT: "{{amount}}",
PAY_STYLE: "{{payStyle}}",
PRD_SKN: "{{proSkn}}",
PRD_SKU: "{{proSku}}"
})
}, true);
}
</script>
{{/ point}}
... ...
... ... @@ -20,11 +20,13 @@ module.exports = {
singleApi: 'http://api-test3.yohops.com:9999/',
api: 'http://api-test3.yohops.com:9999/',
service: 'http://service-test3.yohops.com:9999/',
serviceNotify: 'http://service-test3.yohops.com:9999/',
// prod
// singleApi: 'http://single.yoho.cn/',
// api: 'http://api.yoho.cn/',
// service: 'http://service.yoho.cn/',
// serviceNotify: 'http://service.yoho.cn/',
// gray
// singleApi: 'http://single.gray.yohops.com/',
... ... @@ -34,6 +36,8 @@ module.exports = {
// dev
// api: 'http://dev-api.yohops.com:9999/',
// service: 'http://dev-service.yohops.com:9999/',
// serviceNotify: 'http://dev-service.yohops.com:9999/',
// singleApi: 'http://dev-api.yohops.com:9999/',
imSocket: 'ws://socket.yohobuy.com:10240',
imCs: 'http://im.yohobuy.com/api',
... ... @@ -135,6 +139,7 @@ if (isProduction) {
api: 'http://api.yoho.yohoops.org/',
service: 'http://service.yoho.yohoops.org/',
search: 'http://search.yohoops.org/yohosearch/',
serviceNotify: 'http://service.yoho.cn/',
imSocket: 'ws://imsocket.yohobuy.com:10000',
imCs: 'https://imhttp.yohobuy.com/api',
platformApi: 'http://api.platform.yohoops.org',
... ... @@ -166,6 +171,7 @@ if (isProduction) {
api: process.env.TEST_API || 'http://testapi.yoho.cn:28078/',
service: process.env.TEST_SERVICE || 'http://testservice.yoho.cn:28077/',
search: process.env.TEST_SEARCH || 'http://192.168.102.216:8080/yohosearch/',
serviceNotify: process.env.TEST_SERVICE || 'http://testservice.yoho.cn:28077/',
imSocket: 'ws://socket.yohobuy.com:10240',
imCs: 'http://im.yohobuy.com/api'
},
... ...
... ... @@ -22,6 +22,7 @@ module.exports = app => {
app.use('/shop', require('./apps/shop'));// 店铺
app.use(require('./apps/about')); // 关于有货
app.use('/download', require('./apps/download')); // 下载
app.use('/shopping', require('./apps/shopping')); // 支付中心
// 第三方,如广告联盟
app.use('/3party', require('./apps/3party'));
... ...
{
"name": "yohobuy-node",
"version": "5.5.17",
"version": "5.5.18",
"private": true,
"description": "A New Yohobuy Project With Express",
"repository": {
... ...
{{#if bestForYou}}
<div class="top-title">
<span>为您优选</span>
<label class="change-btn">换一批</label>
</div>
<div class="product-wrap">
<ul class="clearfix">
{{# bestForYou}}
<li>
<a href="{{href}}" data-id="{{productId}}" target="_blank">
<img class="thumb" src="{{image thumb 190 256}}">
<p class="name">{{name}}</p>
<span class="price">¥{{price}}</span>
</a>
</li>
{{/ bestForYou}}
</ul>
</div>
{{/if}}
... ...
... ... @@ -5,9 +5,14 @@
*/
var $ = require('yoho-jquery');
var $body = $('body');
var _ChannelVary = {
boys: 1,
girls: 2,
kids: 3,
lifestyle: 4
};
function cookie(name) {
var re = new RegExp(name + '=([^;$]*)', 'i'),
... ... @@ -276,5 +281,7 @@ window.isIE8 = isIEVer('8.0');
window.once = once;
window.addPyEvent = addPyEvent;
window._ChannelVary = _ChannelVary;
require('./header');
require('./footer');
... ...
var $ = require('yoho-jquery');
var bestForYouPage = {},
$bestForYou = $('.best-for-you');
var bestForYouHbs = require('hbs/common/best-for-you.hbs');
bestForYouPage = {
init: function() {
if (!$bestForYou.length) {
return;
}
this.getRecommend();
},
getRecommend: function() {
var _this = this;
$.ajax({
url: '/common/getRecommend',
type: 'POST',
dataType: 'json',
data: {
recPos: 100004,
limit: 15
},
success: function(d) {
$bestForYou.html(bestForYouHbs({bestForYou: d}));
_this.changeNext();
}
});
},
// 换一批按钮
changeNext: function() {
var $box, boxInfo;
$box = $bestForYou.children('.product-wrap');
boxInfo = {
index: 0,
width: $box.find('li').width() + 10,
totalPage: Math.ceil(($box.find('li').length + 1) / 5)
};
if (boxInfo.totalPage > 1) {
boxInfo.totalPage = boxInfo.totalPage > 3 ? 3 : boxInfo.totalPage;
$bestForYou.find('.change-btn').show().click(function() {
boxInfo.index++;
$box.get(0).scrollLeft = (boxInfo.index % boxInfo.totalPage) * boxInfo.width * 5;
});
}
}
};
$(document).ready(function() {
bestForYouPage.init();
});
... ...
require('../simple-header');
... ...
var $ = require('yoho-jquery'),
dialog = require('../common/dialog'),
Alert = dialog.Alert;
var payPage = {};
var $btnby = $('input.btnby'),
$tabConbox = $('ul.tab-conbox'),
$payWay = $('.pay-way'),
$lightBox = $('.light-box'),
orderCode = $btnby.data('order'),
amount = $btnby.data('amount'),
$formGo = $('.form-go'),
C_ID;
require('../simple-header');
payPage = {
init: function() {
C_ID = window._ChannelVary[window.cookie('_Channel')] || 1;
this.setEvent();
this.goPay();
},
setEvent: function() {
// tab切 事件
$('ul.tabs').on('click', function(e) {
var $li = $(e.target).closest('li');
if ($li.length <= 0) {
return false;
}
$li.addClass('active').siblings().removeClass('active');
$tabConbox.find('li').eq($li.index()).removeClass('hide').siblings().addClass('hide');
});
// 支付方式选中事件
$tabConbox.on('click', '.mode', function() {
$(this).closest('.tab-conbox').find('.mode').removeClass('active');
$(this).addClass('active');
$payWay.find('img').attr('src', $(this).find('img').attr('src'));
$btnby.val('前往' + $(this).data('name'));
});
// 支付弹框隐藏
$lightBox.find('.close,.change').click(function() {
$lightBox.hide();
});
// 单击完成,发送支付确认
$lightBox.find('.over').on('click', function() {
$.post('//www.yohobuy.com/shopping/newpay/sendPayConfirm', {
code: orderCode,
payment: $tabConbox.find('.mode.active').data('id')
}, function() {
document.location.href = '//www.yohobuy.com/home/orders';
});
});
},
goPay: function() {
var payType, $open;
$btnby.on('click', function() {
var $this = $(this);
// 防止频繁点击
if ($this.data('use')) {
return false;
}
$this.data('use', true);
payType = $tabConbox.find('.mode.active').data('value');
// 埋点
window._yas && window._yas.sendCustomInfo && window._yas.sendCustomInfo({
op: 'YB_SC_PAYMENT_TOPAY_CLICK',
param: JSON.stringify({
C_ID: C_ID,
ORDER_CODE: orderCode,
ORDER_AMOUNT: amount,
PAY_STYLE: $tabConbox.find('.mode.active').data('id')
})
}, true);
$.ajax({
url: '//www.yohobuy.com/shopping/newpay/go',
type: 'POST',
dataType: 'json',
async: false,
timeout: 6000,
data: {
code: orderCode,
payType: payType
},
success: function(d) {
$this.data('use', false);
if (d.code !== 200) {
return new Alert(d.message).show();
}
d = d.data;
if (d.reqType) {
$lightBox.show();
$formGo.attr('action', d.reqType);
$.each(d, function(key, val) {
if (key === 'reqType') {
return true;
}
$formGo.append('<input type="text" name="' + key + '" value="' + val + '" />');
});
$formGo.submit();
setTimeout(function() {
$formGo.attr('action', '');
$formGo.html('');
}, 10);
return true;
} else if (!d.href) {
return new Alert('订单信息获取失败!').show();
}
$lightBox.show();
$open = window.open();
$open.location = d.href;
},
error: function() {
$this.data('use', false);
}
});
});
}
};
$(function() {
payPage.init();
// 默认埋点
window._yas && window._yas.sendCustomInfo && window._yas.sendCustomInfo({
op: 'YB_SC_PAYMENT',
param: JSON.stringify({
C_ID: C_ID,
ORDER_CODE: orderCode,
ORDER_AMOUNT: amount
})
}, true);
});
... ...
/**
* 支付成功页
*/
require('../common/best-for-you');
require('../simple-header');
... ...
var $ = require('yoho-jquery'),
dialog = require('../common/dialog');
var wxPage = {}, inter;
var $wOdetail = $('.w-odetail'),
$wPayment = $('.w-payment'),
$wAddrinfo = $('.w-addrinfo'),
$wPerm = $('.w-p-erm'),
orderCode = $wPayment.data('order');
require('../simple-header');
require('yoho-jquery-qrcode');
wxPage = {
init: function() {
$wPerm.qrcode({
render: 'table', // 显示方式,canvas,image和div
text: $wPerm.data('url'), // 二维码的内容
size: 250
});
this.setEvent();
inter = setInterval(this.checkPayStatus, 3000);
},
setEvent: function() {
$wOdetail.on('click', function() {
$wAddrinfo.slideToggle('slow');
if ($(this).find('i').hasClass('up')) {
$(this).html('收起详情<i class="down"></i>');
} else {
$(this).html('订单详情<i class="up"></i>');
}
});
},
checkPayStatus: function() {
$.ajax({
url: '//www.yohobuy.com/shopping/newpay/weixin/state',
dataType: 'json',
type: 'post',
data: {
code: orderCode
},
success: function(d) {
if (d.code === 401) {
clearInterval(inter);
return new dialog.Dialog({
content: d.message,
closeIcon: false,
className: 'alert-dialog',
btns: [{
id: 'alert-sure',
btnClass: ['alert-sure'],
name: '查看我的订单',
cb: function() {
window.location.href = '//www.yohobuy.com/home/orders';
}
}]
}).show();
} else if (d.code === 200) {
clearInterval(inter);
window.location.href = d.data.href;
}
}
});
}
};
$(function() {
wxPage.init();
});
... ...
... ... @@ -36,7 +36,7 @@
.btn {
display: inline-block;
width: 56px;
padding: 0 15px;
height: 26px;
line-height: 26px;
text-align: center;
... ...
.shopping-cashondelivery-page {
width: 860px;
margin: 0 auto;
font-family: arial,"Microsoft YaHei";
font-size: 12px;
text-align: left;
line-height: 150%;
.cart-order {
width: 860px;
margin-top: 70px;
h1 {
height: 70px;
line-height: 40px;
color: #333;
text-align: center;
font-size: 20px;
font-family: Arial,helvetica,sans-serif;
}
}
.ok-br {
width: 30px;
height: 30px;
background: resolve(pay/ok.png) no-repeat;
display: inline-block;
vertical-align: middle;
}
.list-box {
border: 1px #dadada solid;
border-top: 10px #000 solid;
border-bottom: 0px;
margin-bottom: 20px;
font-size: 14px;
}
.list-t {
height: 36px;
line-height: 36px;
background: #f3f3f3;
text-align: center;
color: #333;
border-bottom: 1px #dadada solid;
.yoho-coin {
width: 14px;
height: 14px;
display: inline-block;
background: url(cart/yoho-coin.png);
vertical-align: middle;
margin-top: -2px;
margin-right: 4px;
}
}
.li-1 {
width: 170px;
height: 36px;
border-right: 1px #dadada solid;
font-weight: bold;
float: left;
a{
text-decoration: none;
color: #468fa2;
outline: none;
}
}
.li-2 {
width: 170px;
height: 36px;
border-right: 1px #dadada solid;
float: left;
}
.li-3 {
width: 170px;
height: 36px;
border-right: 1px #dadada solid;
float: left;
}
.li-4{
width: 170px;
height: 36px;
border-right: 1px #dadada solid;
float: left;
}
.li-5 {
width: 170px;
height: 36px;
float: left;
}
.list {
height: 36px;
line-height: 36px;
background: #fff;
text-align: center;
border-bottom: 1px #dadada solid;
font-size: 14px;
}
.f-rz {
font-weight: bold;
font-size: 14px;
color: #e8044f;
}
.f-e {
color: #468fa2;
}
.f-a {
color: #e8044f;
}
.list-b {
border: 1px #fdcf74 solid;
background: #fcfbdd;
color: #976637;
padding: 20px;
line-height: 1.8;
margin-bottom: 20px;
font-family: Arial,helvetica,sans-serif;
a {
text-decoration: none;
color: #468fa2;
outline: none;
}
b {
color:#c00;
}
}
.pay-mode{
color: #666;
}
.btns {
text-align: center;
padding: 20px 0;
margin-bottom: 150px;
a {
display: inline-block;
height: 33px;
line-height: 33px;
text-align: center;
font-size: 14px;
font-weight: bold;
cursor: pointer;
border-radius: 4px;
}
.check-order {
background: #da034a;
color: #fff;
border: 1px solid #9d0134;
width: 134px;
margin-right: 15px;
}
.return-home {
background: #eee;
color: #000;
border: 1px solid #b0b0b0;
width: 97px;
}
}
}
... ...
@import "pay";
@import "wxpay";
@import "cashondelivery";
@import "wechatqrcodereturn";
@import "notice";
... ...
.pay-notice-page {
width: 990px;
margin: 0 auto;
padding: 30px 0;
font-size: 14px;
color: #444;
.red {
color: #ce0b24;
}
.order-wrap {
padding: 40px 50px;
background-color: #f5f5f5;
border: 1px solid #e0e0e0;
> h1 {
font-size: 28px;
line-height: 1;
.pay-sure-icon {
display: inline-block;
width: 32px;
height: 32px;
margin-right: 20px;
background: resolve('pay/pay-sure-icon.png');
vertical-align: text-bottom;
}
}
}
.order-info {
margin-top: 40px;
border-top: 1px solid #e0e0e0;
padding-top: 30px;
position: relative;
li {
padding-bottom: 18px;
.l-b {
display: inline-block;
width: 200px;
}
.back-yoho-coin:after {
content: '';
display: inline-block;
width: 14px;
height: 14px;
background: resolve('cart/yoho-coin.png');
margin-left: 6px;
vertical-align: bottom;
}
.notice-link {
color: #0883d1;
}
}
.opt-btns {
padding-top: 10px;
padding-bottom: 0;
> a {
width: 120px;
height: 32px;
line-height: 32px;
color: #fff;
background-color: #3a3a3a;
display: inline-block;
text-align: center;
margin-right: 54px;
}
}
&:after {
content: '';
width: 450px;
height: 170px;
background: resolve('pay/qr-img.png');
position: absolute;
top: 30px;
right: 0;
}
}
.extra-wrap {
padding: 30px 40px;
line-height: 2;
color: #bbb;
border: 1px solid #e0e0e0;
margin-top: 30px;
.notice-link {
color: #0883d1;
}
}
.best-for-you {
margin-top: 30px;
.top-title {
font-weight: 300;
border-bottom: 1px solid #e0e0e0;
span {
font-size: 18px;
display: inline-block;
padding: 0 4px;
height: 40px;
border-bottom: 3px solid #4a4a4a;
}
.change-btn {
float: right;
font-size: 16px;
line-height: 18px;
cursor: pointer;
display: none;
&:after {
content: '';
width: 13px;
height: 13px;
margin-left: 8px;
display: inline-block;
vertical-align: middle;
background: resolve('pay/change-icon.png');
}
}
}
.product-wrap {
margin-top: 30px;
overflow: hidden;
ul {
width: 3010px;
height: 307px;
overflow: hidden;
}
li {
width: 190px;
margin-right: 10px;
font-size: 12px;
font-weight: bold;
line-height: 1.5;
float: left;
text-align: center;
}
.thumb {
height: 256px;
}
.name {
padding: 0 10px;
margin-top: 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
}
... ...
.shopping-pay-page {
margin: 25px auto;
.pay-page {
width: 100%;
position: relative;
}
.not-pay {
width: 680px;
height: 400px;
margin: 0 auto;
overflow: hidden;
padding-top: 100px;
padding-left: 200px;
p {
padding-left: 30px;
line-height: 32px;
}
.success {
background: resolve("pay/success.png") no-repeat center left;
}
a{
margin-top: 40px;
margin-left: 140px;
float: left;
color: #c5c5c5;
}
}
.pay-title {
width: 980px;
height: 52px;
overflow: hidden;
padding: 20px 0px 0px 0px;
margin: 0px auto;
border-bottom: 2px solid #000000;
ul {
width: 446px;
height: 12px;
float: right;
list-style: none;
padding: 0;
margin: 0;
background: resolve("pay/pay-list.png") no-repeat top right;
}
li {
width: 176px;
height: 12px;
text-align: center;
color: #999;
float: left;
span {
display: block;
height: 15px;
padding: 15px 0px 0px 0px;
line-height: 15px;
font-size: 12px;
}
}
.end {
width: 93px;
height: 18px;
color: #000;
span {
text-align: right;
}
}
}
.step4 {
height: 24px;
width: 99px;
overflow: hidden;
background-image: resolve("pay/pay-title.png");
float: left;
}
.step5 {
height: 31px;
width: 117px;
overflow: hidden;
background-image: resolve("pay/bc.png");
float: left;
}
.cart-pay {
width: 980px;
margin: 25px auto;
h2 {
width: 950px;
height: 40px;
height: 40px;
padding: 0px 0px 0px 30px;
line-height: 40px;
color: #000;
font-size: 20px;
font-family: Arial,helvetica,sans-serif;
background: resolve("pay/cat-pay.png") no-repeat 0px 11px;
font-weight: normal;
}
h3 {
height: 40px;
line-height: 40px;
font-weight: normal;
color: #666;
font-size: 12px;
margin: 0;
strong {
color: #E8044F;
font-size: 14px;
font-weight: bold;
}
}
h4 {
height: 30px;
line-height: 30px;
color: #000;
font-size: 14px;
display: block;
margin: 0;
}
}
.wrapper {
width: 980px;
margin: 25px auto;
overflow: hidden;
border-top: 1px solid #d9d9d9;
padding-top: 19px;
}
.pay-way {
width: 980px;
height: 32px;
margin-bottom: 27px;
overflow: hidden;
margin: 30 auto;
}
.word {
display: block;
float: left;
line-height: 32px;
font-size: 16px;
margin-right: 10px;
}
.pay-type-img {
height: 30px;
float: left;
vertical-align: middle;
}
#tab-box {
width: 980px;
margin-top: 30px;
}
.tab-conbox {
border-bottom: 1px solid #d9d9d9;
}
.tabs {
height: 40px;
padding-left: 20px;
background: #ffffff;
border-bottom: 1px solid #d9d9d9;
li {
height: 40px;
width: 85px;
line-height: 40px;
float: left;
margin-bottom: -1px;
background: #ededed;
overflow: hidden;
position: relative;
margin-left: 20px;
font-size: 12px;
text-align: center;
cursor: pointer;
&.active {
background: #ffffff;
border-bottom: 1px solid #ffffff;
border: 1px solid #d9d9d9;
border-bottom:none;
}
a {
display: block;
outline: none;
font-size: 12px;
text-align: center;
}
}
}
.tab-con {
padding-top: 30px;
font-size: 14px;
width: 1020px;
overflow: hidden;
}
.none{
display: none;
}
.mode {
width: 210px;
height: 50px;
border: 1px solid #d9d9d9;
margin-right: 45px;
margin-bottom: 30px;
float: left;
box-sizing: border-box;
text-align: center;
position: relative;
line-height: 44px;
cursor: pointer;
img{
vertical-align: middle;
outline: none;
}
&:hover {
border: 1px solid red;
}
}
.tab-con .active {
border: 2px solid red;
.choosed-tag {
background-image: resolve("pay/mode-top.png");
height: 22px;
width: 23px;
position: absolute;
top: 0;
right: 0;
display: block;
}
}
.choosed-tag {
display: none;
}
.btnby {
margin-top: 25px;
margin-bottom: 55px;
background: resolve("pay/pay-btn.png") no-repeat top right;
background-repeat: no-repeat;
background-position: 191px center;
float: right;
width: 230px;
height: 40px;
line-height: 40px;
background-color: #da0040;
color: #fff;
font-size: 16px;
border: none;
font-weight: bold;
font-family: arial,"Microsoft YaHei" ! important;
cursor: pointer;
}
.light-box {
position: fixed;
width: 100%;
height: 100%;
z-index: 3;
top: 0;
left: 0;
font-family: "Microsoft Yahei";
display: none;
}
.opacity {
width: 100%;
height: 1000px;
background: #000;
filter: Alpha(Opacity=50);
opacity: 0.50;
overflow: hidden;
position: absolute;
top: 0;
left: 0;
}
.content {
margin-left: -203px;
margin-top: -124px;
padding: 50px 40px;
background-color: #FFFFFF;
position: absolute;
top: 50%;
left: 50%;
box-shadow: 0 0 8px #e8e8e8;
}
.notice {
padding: 26px 14px;
line-height: 20px;
font-size: 13px;
color: #9f9f9f;
}
.btns a {
width: 134px;
height: 38px;
line-height: 38px;
color: #FFFFFF;
font-size: 14px;
margin: 0 14px;
display: inline-block;
text-align: center;
text-decoration: none;
}
.change {
background: #bdbdbd;
}
.over {
background: #da0040;
}
.close a {
width: 30px;
height: 30px;
line-height: 30px;
position: absolute;
top: 0;
right: 0;
font-size: 16px;
font-family: arial;
text-align: center;
text-decoration: none;
color: #666;
outline: none;
}
.close {
width: 30px;
height: 30px;
line-height: 30px;
position: absolute;
top: 0;
right: 0;
font-size: 16px;
font-family: arial;
text-align: center;
}
}
... ...
.wechatqrcodereturn {
width: 990px;
margin: 0 auto;
font-size: 12px;
font-family: Arial,helvetica,sans-serif;
.pay-title {
height: 65px;
overflow: hidden;
padding: 20px 0px 0px 0px;
margin: 0px auto;
border-bottom: 2px solid #000000;
ul {
width: 446px;
height: 12px;
float: right;
list-style: none;
padding: 0;
margin: 0;
background: resolve(pay/pay-list.png) no-repeat top right;
}
li {
width: 176px;
height: 12px;
text-align: center;
color: #999;
float: left;
span {
display: block;
height: 15px;
padding: 15px 0px 0px 0px;
line-height: 15px;
}
}
.end {
width: 93px;
height: 18px;
color: #000;
span {
text-align: right;
}
}
}
.step5 {
height: 33px;
width: 97px;
overflow: hidden;
background-image: resolve(pay/finsh.png);
float: left;
}
.pay-wechat-return {
overflow: hidden;
padding-top: 10px;
}
.payerror {
margin: 50px 0 0 300px;
font-size: 14px;
font-weight: bold;
color: #000;
padding-left: 25px;
line-height: 21px;
background: resolve(pay/pay-fail.png) no-repeat;
}
.arrival-time {
margin: 10px 0 0 325px;
color: #666;
}
.tell-phone {
color: #e8044f;
font-weight: bold;
font-size: 16px;
}
.cart-bigbtns {
span {
margin-right: 5px;
}
}
.btn-type {
display: inline-block;
height: 35px;
padding: 0 0 0 2px;
overflow: hidden;
font-size: 14px;
margin: 40px 0 0 320px;
a {
display: inline-block;
height: 35px;
line-height: 32px;
padding: 0 20px;
background: resolve(pay/btnby.png) no-repeat;
border: none;
overflow: visible;
cursor: pointer;
margin: 0;
color: #666;
}
}
.we-font {
margin: 20px 0 0 320px;
height: 36px;
line-height: 36px;
padding-left: 16px;
color: #999;
display: block;
background: resolve(pay/pay-plaint.png) no-repeat 1px;
}
}
... ...
.pay-wechatqrcode-page {
width: 990px;
margin: 0 auto;
font-size: 12px;
font-family:arial, "Microsoft YaHei";
.pay-title {
height: 52px;
overflow: hidden;
padding: 20px 0px 0px 0px;
margin: 0px auto;
border-bottom: 2px solid #000000;
ul {
width: 446px;
height: 12px;
float: right;
list-style: none;
padding: 0;
margin: 0;
background: resolve(pay/pay-list.png) no-repeat top right;
}
li {
width: 176px;
height: 12px;
text-align: center;
color: #999;
float: left;
span {
display: block;
height: 15px;
padding: 15px 0px 0px 0px;
line-height: 15px;
}
}
.end {
width: 93px;
height: 18px;
color: #000;
span {
text-align: right;
}
}
}
.step4 {
height: 24px;
width: 99px;
overflow: hidden;
background-image: resolve(pay/pay-title.png);
float: left;
}
.w-title {
padding: 25px 0 12px;
overflow: hidden;
}
.w-left {
width: 670px;
float: left;
h3 {
line-height: 26px;
height: 26px;
margin-bottom: 4px;
overflow: hidden;
font-size: 14px;
font-weight: normal;
}
p {
height: 22px;
line-height: 22px;
color: #9b9b9b;
span {
color: red;
}
}
}
.w-right {
margin-left: 670px;
overflow: hidden;
text-align: right;
p {
line-height: 26px;
height: 26px;
margin-bottom: 4px;
overflow: hidden;
font-size: 14px;
strong {
color: #ff5d5b;
font-size: 18px;
margin: 0 3px;
font-weight: bold;
}
}
a {
color: #2ea7e7;
padding-right: 14px;
position: relative;
display: inline-block;
height: 22px;
line-height: 22px;
i {
width: 0;
height: 0;
font-size: 0;
position: absolute;
top: 9px;
right: 4px;
z-index: 1;
cursor: pointer;
}
}
}
.up {
float: right;
border-width: 4px 3px 0;
border-style: solid dashed dashed;
border-color: #2ea7e7 transparent transparent;
}
.down {
float: right;
border-width: 0 3px 4px;
border-style: dashed dashed solid;
border-color: transparent transparent #2ea7e7;
}
.w-addrinfo {
padding: 12px 0;
color: #9b9b9b;
line-height: 22px;
border-top: 1px solid #e4e5eb;
display: none;
span {
padding: 0 20px;
}
}
.w-payment {
border: 1px solid #e5e5e5;
border-top: 3px solid #4b5b78;
background-color: #fff;
padding: 26px 30px 30px;
margin-top: 6px;
margin-bottom: 50px;
h2 {
font-size: 18px;
font-weight: normal;
display: block;
}
}
.w-p-weixin {
width: 300px;
height: 380px;
padding: 20px 370px 30px 0;
margin: 0 auto;
overflow: hidden;
background: resolve(pay/w-p-phone.png) no-repeat top right;
}
.w-p-erm {
width: 250px;
height: 250px;
padding: 20px;
margin-bottom: 20px;
border: 1px solid #ddd;
overflow: hidden;
}
.w-p-word {
height: 44px;
padding: 8px 0 8px 125px;
background: resolve(pay/w-p-word.png) no-repeat 50px 8px #090909;
p {
margin: 0;
font-size: 14px;
line-height: 22px;
color: #fff;
font-weight: 700;
}
}
.w-pay-change {
display: block;
height: 30px;
line-height: 30px;
margin-top: 50px;
color: #0aaefa;
cursor
font-size: 14px;
i {
float: left;
margin-right: 14px;
font-family: "arial";
font-style: normal;
font-size: 16px;
}
}
}
... ...