pay.js 6.63 KB
/**
 * 订单支付
 * @author: jiangfeng<jeff.jiang@yoho.cn>
 * @date: 2016/07/18
 */

'use strict';


const payApi = require('./pay-api');
const Promise = require('bluebird');
const co = Promise.coroutine;
const camelCase = global.yoho.camelCase;
const OrderData = require('./order');
const payHelpersBank = require('./../helpers/bank');
const logger = global.yoho.logger;


const _ = require('lodash');

const payments = {
    alipay: 33,
    wechat: 36,
    alibank: 44
};

/**
 * 获取在线支付方式
 * @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;
            }

            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 OrderData.orderDetail(uid, code).then(orderData => {
        if (orderData && orderData.data) {
            return camelCase(orderData.data);
        } else {
            return {};
        }
    });
};

/**
 * 获取订单支付银行信息
 * @param id
 */
const getBankByOrder = (id) => {
    return co(function *() {
        let data = yield payApi.getBankByOrder(id);

        if (data && data.code === 200 && data.data) {
            return camelCase(data.data);
        }
        return {};
    })();
};

/**
 * 获取支付页数据
 * @param uid
 * @param code
 */
const getPayInfo = (uid, code) => {
    return Promise.all([getOnlinePayProvider(), getOrderInfo(uid, code), getBankByOrder(code)])
        .then(payment => {
            let paymentId = parseInt(payment[2].payment || 0, 10);
            let findIndex;

            // 渲染选择的默认支付方式
            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;
            } 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;
            }

            return {
                pay: payment[0],
                order: payment[1]
            };
        });
};

/**
 * 获取支付方式的相关参数, (密钥等信息)
 * @param id
 */
const getPaymentInfo = (id) => {
    return co(function *() {
        let data = yield payApi.getPaymentInfo(id);

        if (data && data.code === 200 && data.data) {
            return camelCase(data.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 code
 * @param payment
 * @param bankCode
 */
const updateOrderPayBank = (code, payment, bankCode) => {
    return co(function *() {
        let data = yield payApi.updateOrderPayBank(code, payment, bankCode);

        return data;
    })();
};

/**
 * 支付确认
 * @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 payResult
 * @param uid
 */
const procOrderData = (payResult, uid) => {
    return co(function *() {
        let orderCode = payResult.orderCode;
        let result = {code: 400, message: ''};

        if (!orderCode) {
            result.message = '未查到订单信息,订单状态更新失败!';
            return result;
        }

        let orderInfo = yield OrderData.orderDetail(uid, orderCode);

        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;
    })();
};

module.exports = {
    getPayInfo,
    getPaymentInfo,
    getBankByOrder,
    setOrderPayBank,
    updateOrderPayBank,
    sendPayConfirm,
    procOrderData,
    payments
};