pay.js 9.15 KB
/**
 * 支付
 * @author: jing.li<jing.li@yoho.cn>
 * @date: 2016/10/25
 */

'use strict';

const api = global.yoho.API;
const serviceAPI = global.yoho.ServiceAPI;
const utils = '../../../utils';
const productProcess = require(`${utils}/product-process`);
const payApi = require('./pay-api');
const helpers = global.yoho.helpers;
const _ = require('lodash');
const co = require('bluebird').coroutine;
const logger = global.yoho.logger;

// 支付方式
const payments = {
    alipay: 33,
    wechat: 36,
    alibank: 42
};

// 资源位
const _getBanner = (param) => {
    return serviceAPI.get('operations/api/v5/resource/get', {
        content_code: param.contentCode
    }, {
        code: 200
    }).then((result) => {

        result = result.data;

        return result;
    });
};

// 购买此商品的用户也购买了
const _getOthersBuy2 = (param) => {
    return api.get('', {
        method: 'app.recommend.purchased',
        productSkn: param.skn,
        udid: param.uid,
        rec_pos: '100005',
        limit: 2,
        client_id: param.client_id
    }, {
        code: 200
    }).then((result) => {

        if (result && result.data && result.data.product_list) {
            return productProcess.processProductList(result.data.product_list);
        }

    });
};

// 订单信息
const _getOtherDetail = (param) => {
    return api.get('', {
        method: 'app.SpaceOrders.detail',
        uid: param.uid,
        order_code: param.orderCode,
        session_key: param.sessionKey
    }, {
        code: 200
    }).then((result) => {

        return result;

    });
};

// 购买此商品的用户也购买了,要先从订单详情获取商品skn
const _getOthersBuy = (param) => {
    return api.all([
        _getOtherDetail(param)
    ]).then((result) => {

        let goodSkn = '';

        if (result && result[0] && result[0].data && result[0].data.order_goods) {
            goodSkn = result[0].data.order_goods[0].product_skn;
        }

        return _getOthersBuy2(Object.assign(param, { skn: goodSkn }));

    }).then((result) => {

        return result;
    });
};

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

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

/**
 * 设置订单支付银行
 * @param code
 * @param payment
 * @param bankCode
 */
const setOrderPayBank = (code, payment, bankCode) => {
    return co(function*() {
        let data = yield payApi.setOrderPayBank(code, payment, bankCode);

        return data;
    })();
};

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

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

/**
 * 支付确认
 * @param code
 * @param payment
 * @param uid
 */
const sendPayConfirm = (code, payment, uid) => {
    return co(function*() {
        let data = yield payApi.sendPayConfirm(code, payment, uid);

        return data;
    })();
};

/**
 * 更新订单支付方式
 * @param code
 * @param payment
 * @param uid
 * @returns {*}
 */
const updateOrderPayment = (code, payment, uid) => {
    return api.get('', {
        method: 'app.SpaceOrders.updateOrdersPaymentByCode',
        order_code: code,
        payment: payment,
        uid: uid
    });
};

/**
 * 更新订单支付银行
 * @param code
 * @param payment
 * @param bankCode
 */
const updateOrderPayBank = (code, payment, bankCode) => {
    return co(function*() {
        let data = yield payApi.updateOrderPayBank(code, payment, bankCode);

        return data;
    })();
};

/**
 * 支付成功,前端回调时,处理订单信息
 * @param payResult
 * @param uid
 * @param sessionKey
 */
const procOrderData = (payResult, uid, sessionKey) => {
    return co(function*() {
        let orderCode = payResult.orderCode;
        let result = { code: 400, message: '' };

        if (!orderCode) {
            result.message = '未查到订单信息,订单状态更新失败!';
            return result;
        } else {
            let orderInfo = yield _getOtherDetail({
                uid: uid,
                orderCode: orderCode,
                sessionKey: sessionKey
            });

            if (orderInfo && orderInfo.data) {
                let order = orderInfo.data;
                let amount = order.payment_amount;

                if (order.is_cancel === 'Y') {
                    logger.warn('front pay success but order is cancel.', { payResult: payResult, order: order });

                    payApi.sendMessage(order.mobile, 'error_sms', '支付成功,但订单已取消,订单号为' + orderCode);
                    return { code: 417, message: '支付成功,但订单已取消,需联系客服!' };
                }

                if (order.payment_status === 'N') {
                    logger.warn('front pay success but may be notify fail');
                }

                if (_.round(parseFloat(amount), 2) !== _.round(parseFloat(payResult.totalFee), 2)) {
                    logger.warn('front pay success but the amount is not same.', { payResult: payResult, order: order });
                    return {
                        code: 415,
                        message: '支付金额与订单金额不一致,订单状态更新失败!'
                    };
                }

                return {
                    code: 200,
                    message: '支付成功,请等待发货',
                    data: {
                        order: order
                    }
                };

            } else {
                result.message = '未查到订单信息,订单状态更新失败!';
            }
        }

        return result;
    })();
};

/**
 * 支付相关的数据处理函数
 */
const payTool = {

    /**
     * 支持的支付方式列表
     * @returns {[*,*]}
     */
    payAppInfo(orderCode) {
        return [{
            appIcon: '',
            payLink: helpers.urlFormat('/cart/index/new/pay/goalipay', {
                payment: payments.alipay + '_platform',
                order_code: orderCode
            }),
            appId: 'alipay',
            app: '支付宝支付',
            hint: '支付宝钱包支付',
            subHint: '推荐支付宝用户使用'
        }, {
            appIcon: '',
            payLink: '',
            appId: 'weixin',
            app: '微信支付',
            hint: '推荐使用',
            subHint: ''
        }];
    },

    /**
     * 计算购买商品总数量
     * @param goodsArray
     * @returns {number}
     * @private
     */
    calBuyNumCount(goodsArray) {
        let buyNumCount = 0;

        if (_.isArray(goodsArray)) {
            _.forEach(goodsArray, value => {
                buyNumCount = value.buy_number ? parseInt(value.buy_number, 10) : 0;
            });
        }

        return buyNumCount;
    }
};

/**
 * 支付中心
 * @param params
 */
const payCenter = (params) => {

    return _getOtherDetail({
        uid: params.uid,
        orderCode: params.orderCode
    }).then(result => {
        return _.get(result, 'data', {});
    });
};

// 货到付款
const getPayCod = (param) => {
    return api.all([
        _getBanner(param),
        _getOthersBuy(param),
        _getOtherDetail(param)
    ]).then((result) => {

        let resu = {
            match: true,
            banner: [],
            othersBuy: []
        };

        if (result && result[0]) {
            resu.banner = result[0];
        }

        if (result && result[1]) {
            resu.othersBuy = result[1];
        }

        if (result && result[2] && result[2].data && result[2].data.payment_amount) {
            resu.payment = result[2].data.payment_amount;
        } else {
            resu.match = false;
        }

        resu.orderCode = param.orderCode;

        resu.orderUrl = '/home/orders/detail?order_code=' + param.orderCode;

        return resu;
    });
};

// 支付宝支付
const getPayAli = (param) => {
    return api.all([
        _getBanner(param),
        _getOthersBuy(param),
        _getOtherDetail(param)
    ]).then((result) => {

        let resu = {
            match: true,
            banner: [],
            othersBuy: []
        };

        if (result && result[0]) {
            resu.banner = result[0];
        }

        if (result && result[1]) {
            resu.othersBuy = result[1];
        }

        if (result && result[2] && result[2].data && result[2].data.payment_amount) {
            resu.payment = result[2].data.payment_amount;
        } else {
            resu.match = false;
        }

        resu.orderCode = param.orderCode;

        resu.orderUrl = '/home/orders/detail?order_code=' + param.orderCode;

        return resu;
    });
};

module.exports = {
    payments,
    getOtherDetail: _getOtherDetail,
    updateOrderPayment,
    updateOrderPayBank,
    getBankByOrder,
    getPaymentInfo,
    setOrderPayBank,
    sendPayConfirm,
    procOrderData,
    payCenter,
    payTool,
    getPayCod,
    getPayAli
};