Authored by 郝肖肖

微信支付界面

... ... @@ -60,7 +60,7 @@ const online = (req, res, next) => {
});
res.render('pay-success', {
content: {
cost: order.payment_amount,
amount: order.payment_amount,
orderNum: order.order_code,
coin: coin,
orderHref: helpers.urlFormat('/me/order/detail', {
... ... @@ -114,8 +114,9 @@ const toPay = (req, res, next) => {
*/
const weixinQr = (req, res, next) => {
let code = req.query.code;
let url = req.query.url;
let qrcodeUrl = req.query.url;
let uid = req.user.uid;
let header = headerModel.setSimpleHeaderData() || {};
if (!integerTest.test(code)) {
// 不合法订单号
... ... @@ -129,41 +130,54 @@ const weixinQr = (req, res, next) => {
return {};
}
}).then(order => {
res.display('weixin-pay', {
defaultHeader: false,
bcNavFocus: 3,
res.render('weixin-pay', {
module: 'shopping',
page: 'wxpay',
title: '微信扫码支付页面',
code: code,
url: url,
simpleHeader: header,
choosePayUrl: helpers.urlFormat('/shopping/pay', {
order_code: order.order_code
}),
qrcodeUrl: qrcodeUrl,
order: order
});
}).catch(next);
};
const weixinPayState = (req, res) => {
let code = req.query.code;
let code = req.body.code;
let uid = req.user.uid;
if (!integerTest.test(code)) {
return res.json({});
}
PayData.orderDetail(uid, code).then(result => {
if (result && result.data && result.data.payment_status === 'Y') {
let data = {};
result = result && result.data || {};
if (result.is_cancel === 'Y') {
data = {
code: 401,
message: '订单已取消'
};
} else if (result.payment_status === 'Y') {
let payParams = {
orderCode: code,
totalFee: _.round(parseFloat(result.data.payment_amount), 2)
totalFee: _.round(parseFloat(result.payment_amount), 2)
};
res.json({
data = {
code: 200,
data: {
href: helpers.urlFormat('/shopping/pay/callback/wechat', Object.assign(payParams, {
sign: md5(paySign.raw(Object.assign({tradeStatus: 'Y'}, payParams)))
}))
}
});
} else {
return res.json({});
};
}
return res.json(data);
}).catch(() => {
return res.json({});
});
... ... @@ -196,7 +210,7 @@ const callback = (req, res, next) => {
}
});
res.display('pay-success', {
res.render('pay-success', {
defaultHeader: false,
bcNavFocus: 3,
content: {
... ... @@ -210,7 +224,7 @@ const callback = (req, res, next) => {
}
});
} else {
res.display('pay-fail', {
res.render('pay-fail', {
defaultHeader: false,
payName: result.payName,
bcNavFocus: 3
... ...
... ... @@ -29,9 +29,9 @@ const Alibank = {
service: 'create_direct_pay_by_user',
partner: payParams.merchant_id,
_input_charset: 'utf-8',
notify_url: config.pay.serviceNotify + 'payment/alipay_notify',
notify_url: config.domains.serviceNotify + 'payment/alipay_notify',
return_url: protocol + ':' + helpers.urlFormat('/shopping/pay/callback/alibank'),
subject: 'BLK订单号:' + order.order_code,
subject: '有货订单号:' + order.order_code,
out_trade_no: order.order_code,
it_b_pay: common.getPayExpireMin(order.pay_expire) + 'm',
total_fee: order.payment_amount,
... ...
... ... @@ -27,9 +27,9 @@ const Alipay = {
service: 'create_direct_pay_by_user',
partner: payParams.merchant_id,
_input_charset: 'utf-8',
notify_url: config.pay.serviceNotify + 'payment/alipay_notify',
notify_url: config.domains.serviceNotify + 'payment/alipay_notify',
return_url: protocol + ':' + helpers.urlFormat('/shopping/pay/callback/alipay'),
subject: 'BLK订单号:' + order.order_code,
subject: '有货订单号:' + order.order_code,
out_trade_no: order.order_code,
it_b_pay: common.getPayExpireMin(order.pay_expire) + 'm',
total_fee: order.payment_amount,
... ...
... ... @@ -13,10 +13,10 @@ const Wechat = {
return ServiceAPI.get('payment/weixin_data', {
order_code: order.order_code,
payment_code: info.id,
app_key: 'blkpc'
app_key: 'yohopc'
}).then(result => {
if (result && result.code === 200 && result.data) {
let url = `/shopping/pay/online/weixin?url=${result.data.codeUrl}&code=${order.order_code}`;
let url = `/shopping/pay/weixin?url=${result.data.codeUrl}&code=${order.order_code}`;
return {
code: 200,
... ...
/**
* 各种支付的入口
*
* @author: jiangfeng<jeff.jiang@yoho.cn>
* @author: xiaoxiao.hao<xiaoxiao.hao@yoho.cn>
* @date: 16/7/22
*/
... ...
... ... @@ -13,11 +13,10 @@ const pay = require(`${cRoot}/pay`); // 支付
// 支付
router.get('/pay', auth, pay.online);
router.get('/pay/online', auth, pay.online);
router.get('/pay/online/weixin', auth, pay.weixinQr);
router.get('/pay/online/weixin/state', auth, pay.weixinPayState);
router.post('/pay/online/go', auth, pay.toPay);
router.post('/pay/online/sendPayConfirm', auth, pay.sendPayConfirm);
router.get('/pay/weixin', auth, pay.weixinQr);
router.post('/pay/weixin/state', auth, pay.weixinPayState);
router.post('/pay/go', auth, pay.toPay);
router.post('/pay/sendPayConfirm', auth, pay.sendPayConfirm);
// 支付回调
router.get('/pay/callback/:type', auth, pay.callback);
... ...
... ... @@ -34,7 +34,7 @@
{{# 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}}">
<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>
... ... @@ -49,7 +49,6 @@
</div>
</div>
<div class="light-box">
<div class="opacity" id="fade"></div>
<div class="content" id="light">
... ... @@ -59,7 +58,7 @@
<p>完成付款后请根据您的情况点击下面的按钮</p>
</div>
<div class="btns">
<a href="javascript:void(0);" data-url = "{{ordersUrl}}"class="pay-over over">已完成付款</a>
<a href="javascript:void(0);" data-url = "{{ordersUrl}}"class="over">已完成付款</a>
<a href="#" class="change">更换支付方式</a>
</div>
<a href="#" class="close">x</a>
... ...
{{> settle-header}}
<div class="center-content pay-online-wrapper">
{{> bc-nav}}
<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="title">
<div class="content">
<span class="desc left">订单已提交成功,请您尽快付款!订单编号:{{orderCode}}</span>
<span class="cash right">应付金额:{{paymentAmount}}</span>
</div>
<div class="footer">
<span class="desc pay-notice left">{{../username}}如果<span class="blue">2小时</span>内您无法完成付款,系统会将您的订单取消</span>
<span id="order-detail-ctrl" class="blue right order-detail-ctrl">
收起详情<i class="iconfont up">&#xe617;</i>
</span>
</div>
<div class="w-title">
<div class="w-left">
<h3>请您及时付款,以便订单尽快处理!订单号:{{order_code}}</h3>
<p>
请您提交订单
<span>2小时</span>
内完成,否则订单会自动取消。
</p>
</div>
<div class="order-detail">
<div class="row">
<div class="item receiver-address">
<span class="label"> 收货地址:</span>
<span>{{area}} {{address}}</span>
</div>
</div>
<div class="row">
<div class="item">
<span class="label">&nbsp;&nbsp;&nbsp;&nbsp;人:</span>
<span>{{userName}}</span>
</div>
<div class="item">
<span class="label">联系方式:</span>
<span>{{mobile}}</span>
</div>
</div>
<div class="row">
<div class="item">
<span class="label">支付方式:</span>
<span>在线支付</span>
</div>
<div class="item">
<span class="label">送货时间:</span>
<span>{{deliveryTime}}</span>
</div>
</div>
<div class="w-right">
<p>应付金额<strong>{{payment_amount}}</strong></p>
<a href="#" class="w-odetail">订单详情
<i class="up"></i>
</a>
</div>
{{/order}}
</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="qr-content">
<h1>微信支付</h1>
<div class="qr-content-gruop">
<div class='qr-content-left'>
<div class="qr-code" data-qr="{{url}}" data-code="{{order.orderCode}}"></div>
<div class="qr-content-footer">
<p>请使用微信扫一扫</p>
<p>扫描二维码支付</p>
</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>
<h3>
<a href="/shopping/pay/online?code={{order.orderCode}}" class="blue w-pay-change">
<i>&lt;</i>
选择其他支付方式
</a>
</h3>
</div><!--/qr-content-->
<a href="{{../choosePayUrl}}" class="w-pay-change">
<i>&lt;</i>
选择其他支付方式
</a>
</div>
{{/ order}}
</div>
... ...
... ... @@ -25,6 +25,8 @@ module.exports = {
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/',
... ... @@ -133,6 +135,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'
... ... @@ -163,6 +166,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_SEARCH || 'http://testservice.yoho.cn:28077/',
imSocket: 'ws://socket.yohobuy.com:10240',
imCs: 'http://im.yohobuy.com/api'
},
... ...
var $ = require('yoho-jquery');
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');
require('../common');
... ... @@ -10,6 +15,7 @@ require('../common');
payPage = {
init: function() {
this.setEvent();
this.goPay();
},
setEvent: function() {
// tab切 事件
... ... @@ -25,12 +31,52 @@ payPage = {
});
// 支付方式选中事件
$('ul.tab-conbox').on('click', '.mode', function() {
$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/pay/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() {
payType = $tabConbox.find('.mode.active').data('value');
$.ajax({
url: '//www.yohobuy.com/shopping/pay/go',
type: 'POST',
dataType: 'json',
data: {
code: orderCode,
payType: payType
},
success: function(d) {
if (d.code !== 200) {
return new Alert(d.message).show();
}
$open = window.open();
$open.location = d.data.href;
$lightBox.show();
}
});
});
}
};
... ...
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('../common');
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/pay/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,
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;
... ...
@import "pay";
@import "wxpay";
@import "cashondelivery";
... ...
.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;
}
}
}
... ...