payment.js 5.04 KB
/**
 * 各种支付的入口
 * TAR NOTE: 本项目中仅支持支付宝支付,微信支付,其他支付方式需调试
 * @author: jiangfeng<jeff.jiang@yoho.cn>
 * @date: 16/7/22
 */

'use strict';

const PayModel = require('../models/pay');
const Alipay = require('./pay/alipay');
const Wechat = require('./pay/wechat');
const Promise = require('bluebird');
const co = Promise.coroutine;
const logger = global.yoho.logger;
const common = require('./pay/common');

const Payment = {

    /**
     * 统一支付入口
     * reqParams: 需要从 controller 传递的参数,支付宝需要 req.protocol,微信需要 openId、ip
     */
    pay(user, order, payType, reqParams) {
        return co(function*() {
            let result = {
                code: 400,
                message: '获取支付方式信息失败'
            };
            let payInfo;
            let bankCode = '';

            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 = common.getPaymentCode(payType);

            if (!method) {
                logger.info('payCenter: payment no method params');
                return result;
            }

            if (method === PayModel.payments.wechat) {
                result = yield Wechat.pay(user, order, reqParams.openId, reqParams.ip);
            } else {
                payInfo = yield PayModel.getPaymentInfo(method);

                if (!payInfo.payParams) {
                    return result;
                }

                switch (payInfo.id) {
                    case PayModel.payments.alipay:
                        result = Alipay.pay(user, order, payInfo, reqParams.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([
            PayModel.updateOrderPayment(order.order_code, method, user.uid),
            PayModel.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 PayModel.updateOrderPayBank(order.order_code, method, bankCode);
            } else {
                return PayModel.setOrderPayBank(order.order_code, method, bankCode);
            }

        }).catch(e => {
            logger.error('update order pay info error.', e);

            return Promise.resolve({
                code: 400,
                message: '更新订单支付信息失败'
            });
        });
    },

    afterPay(query, payId, user, sessionKey) {
        return co(function*() {
            let payInfo = yield PayModel.getPaymentInfo(payId);
            let payResult = {};
            let payData = {};
            let payName = '';

            if (payId === PayModel.payments.alipay) {
                payResult = Alipay.notify(query, payInfo);
            }

            payResult.bankName = payName = payResult.bankName || payInfo.payName || '';
            payResult.bankCode = payResult.bankCode || payInfo.pay_code || '';

            // 记录日志
            logger.info(`\r\n\r\n pay back confirmreq = ${JSON.stringify({
                query: query,
                payId: payId,
                user: user,
                payResult: payResult
            })}`);

            if (payResult && payResult.payResult === 200) {
                if (payResult.orderCode) {
                    logger.info('pay back confirm');
                    yield PayModel.sendPayConfirm(payResult.orderCode, payId, user.uid);
                }

                payData = yield PayModel.procOrderData(payResult, user.uid, sessionKey);
            } else {
                payData = {
                    code: 500,
                    message: '支付失败'
                };
            }

            payData.payName = payName;

            return payData;
        })();
    }
};

module.exports = Payment;