const wxpay = require('../pay/wechat_pay'); const sysUser = require('../db/fuxi/sys_user'); const course = require('../db/models/course'); const order = require('../db/models/order'); const inviter = require('../db/models/inviter'); const sseClient = require('./sse_client'); const { onError, createTradeNo, onSuccess, fixPrice } = require('../utils'); const { isProd, host, ORDER_STATUS } = require('../server/config'); const { Op } = require('sequelize'); const _ = require('lodash'); const API = { async buyCourse(obj) { const { uid, cid, code = '' } = obj; const cdata = await course.findOne({ where: { id: cid } }); if (!cdata) { return onError('课程不存在'); } const edata = await order.findOne({ where: { cid, uid, status: { [Op.in]: [ORDER_STATUS.已支付, ORDER_STATUS.渠道] } }, }); if (edata) { return onError('课程已购买'); } const { title, oprice, detailimg, recordId } = cdata; let { price } = cdata; let discount = ''; if (code) { const idata = await inviter.findOne({ where: { code } }); if (idata) { price = fixPrice(price * idata.discount); discount = idata.discount; } } const id = createTradeNo(); const odata = await order.create({ id, cid, uid, title, detailimg, price, recordId, discount, code, }); if (!parseFloat(price)) { await API.buySuccess( { trade_state: 'SUCCESS', out_trade_no: id, }, false ); return onSuccess({ id }); } const wdata = await wxpay.transactions_native({ description: title, out_trade_no: id, amount: { total: isProd() ? Math.ceil(price * 100) : 1, }, notify_url: `${host}/external/pay/notice`, // total: 1, }); if (!wdata.code_url) { return onError(wdata); } return onSuccess({ id, url: wdata.code_url, }); }, // 购买结果轮训 async buyCheck(oid) { const { data: odata } = await order.findOne({ id: oid }); if (!odata) { return onError('订单不存在'); } return onSuccess(odata.status === ORDER_STATUS.已支付); }, async buySuccess(obj, decode = true) { let data = obj; if (decode) { // eslint-disable-next-line camelcase const { original_type, algorithm, ciphertext, associated_data, nonce } = obj; data = wxpay.decipher_gcm(ciphertext, associated_data, nonce); } if (data.trade_state !== 'SUCCESS') { return; } const { out_trade_no: id } = data; const odata = await order.findOne({ where: { id } }); if (!odata || odata.payAt) { return; } await order.update( { payAt: new Date(), status: ORDER_STATUS.已支付, }, { where: { id } } ); if (sseClient[id]) { sseClient[id].send('done'); sseClient[id].close(); } }, async inviteCheck(obj) { const { code, cid } = obj; const idata = await inviter.findOne({ where: { code } }); if (!idata) { return onError('邀请码不存在'); } const cdata = await course.findOne({ where: { id: cid } }); const { price: oprice } = cdata; const price = fixPrice(oprice * idata.discount); const discountPrice = fixPrice(oprice - price); return onSuccess({ price, discountPrice, ..._.pick(idata, ['name', 'discount']), }); }, }; module.exports = API;