|
@@ -5,6 +5,7 @@ const _ = require('lodash');
|
|
|
const assert = require('assert');
|
|
|
const moment = require('moment');
|
|
|
const { ObjectId } = require('mongoose').Types;
|
|
|
+const Transaction = require('mongoose-transactions');
|
|
|
//
|
|
|
class PayOrderService extends CrudService {
|
|
|
constructor(ctx) {
|
|
@@ -19,82 +20,51 @@ class PayOrderService extends CrudService {
|
|
|
this.coachModel = this.ctx.model.User.Coach;
|
|
|
this.rcsModel = this.ctx.model.Relation.RelationCoachSchool;
|
|
|
this.rssModel = this.ctx.model.Relation.RelationStudentSchool;
|
|
|
-
|
|
|
this.billModel = this.ctx.model.Business.Bill;
|
|
|
+ this.tran = new Transaction();
|
|
|
}
|
|
|
-
|
|
|
- async beforeCreate(data) {
|
|
|
- if (!_.get(data, 'order_no')) data.order_no = this.getOrderNo();
|
|
|
- const { data: nd, next } = await this.checkSurplus(data);
|
|
|
- if (!next) throw new BusinessError(0, '扣除余额成功', nd);
|
|
|
- data = nd;
|
|
|
- return data;
|
|
|
- }
|
|
|
- // 检查是否扣除余额
|
|
|
- async checkSurplus(data) {
|
|
|
- const pay_for = _.get(data, 'pay_for');
|
|
|
- // 充值不检查余额
|
|
|
- if (pay_for && pay_for === 'Bill') return { data, next: true };
|
|
|
- const payer_id = _.get(data, 'payer_id');
|
|
|
- const payer_role = _.get(data, 'payer_role');
|
|
|
- const school_id = _.get(data, 'school_id');
|
|
|
- let billData;
|
|
|
- let relation;
|
|
|
- // 没有要支付的人及其角色,那就找不到余额,返回下单
|
|
|
- if (!(payer_id && payer_role)) return { data, next: true };
|
|
|
- // 有支付的人,可以查查这个人的余额
|
|
|
- if (payer_role === 'Student') relation = await this.rssModel.findOne({ student_id: payer_id, school_id });
|
|
|
- else if (payer_role === 'Coach') relation = await this.rcsModel.findOne({ coach_id: payer_id, school_id });
|
|
|
- // 没找到关系,那就直接返回正常下单缴费
|
|
|
- if (!relation) return { data, next: true };
|
|
|
- // 有关系,找余额
|
|
|
- const { money: surplus } = relation;
|
|
|
- const { money } = data;
|
|
|
- // 没有余额,或者余额没钱,返回正常下单缴费
|
|
|
- if (surplus && surplus <= 0) return { data, next: true };
|
|
|
- // 有余额,看余额够不够
|
|
|
- if (this.ctx.minus(surplus, money) >= 0) {
|
|
|
- try {
|
|
|
- // 余额够, 无需生成订单,直接去使用余额缴费
|
|
|
- const bill = _.pick(data, [ 'school_id', 'payer_id', 'payer_role', 'pay_for', 'from_id' ]);
|
|
|
- // 本次扣除余额的金额就是本次需要支付的金额
|
|
|
- bill.money = money;
|
|
|
- bill.type = '-2';
|
|
|
- bill.is_pay = '1';
|
|
|
- billData = await this.billModel.create({ ...bill, time: moment().format('YYYY-MM-DD HH:mm:ss') });
|
|
|
- // 余额需要扣除本次支付的费用
|
|
|
- relation.money = surplus - money;
|
|
|
- await relation.save();
|
|
|
- // 前端生成报名数据
|
|
|
- return { data: billData, next: false };
|
|
|
- } catch (error) {
|
|
|
- // 抓取数据库创建和修改的异常,
|
|
|
- // 如果 billData没有值,说明是创建消费记录时发生的错误,不需要做回滚处理;如果有值,那就删除
|
|
|
- if (billData) {
|
|
|
- await this.billModel.deleteOne({ _id: billData._id });
|
|
|
- }
|
|
|
- // 如果是余额修改错误,上面的回滚删除就足够了.因为保存新余额发生错误,余额不会保存,只要把消费记录删了,就回到原样了
|
|
|
- }
|
|
|
- } else if (surplus !== 0) {
|
|
|
- // 余额不足且不为0,在config里记录部分使用了余额,再进行下单,下单完后,生成余额的扣款
|
|
|
- const needPay = this.ctx.minus(money, surplus);
|
|
|
- const bill = _.pick(data, [ 'school_id', 'payer_id', 'payer_role', 'pay_for', 'from_id' ]);
|
|
|
- bill.money = surplus;
|
|
|
- bill.type = '-2';
|
|
|
- if (!data.config) data.config = {};
|
|
|
- // 添加余额的设置, 等支付成功后,再生成余额的消费记录
|
|
|
- data.config.useSurplus = true;
|
|
|
- data.config.bill = bill;
|
|
|
- data.money = needPay;
|
|
|
+ /**
|
|
|
+ * 处理支付回调
|
|
|
+ * @param {Object} body 参数体
|
|
|
+ */
|
|
|
+ async payCallBack({ result }) {
|
|
|
+ const { out_trade_no, payer } = result;
|
|
|
+ // 没有需要报警,没有订单号就出问题了
|
|
|
+ if (!out_trade_no) {
|
|
|
+ console.error('没有支付订单号');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const openid = _.get(payer, 'openid');
|
|
|
+ const query = { order_no: out_trade_no, openid };
|
|
|
+ let payOrder = await this.model.findOne(query);
|
|
|
+ // 没找到订单也是有问题的,需要报警
|
|
|
+ if (!payOrder) {
|
|
|
+ console.error('没有找到付款单');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ payOrder = JSON.parse(JSON.stringify(payOrder));
|
|
|
+ const config = _.get(payOrder, 'config', {});
|
|
|
+ // 修改信息
|
|
|
+ config.pay = result;
|
|
|
+ const update = { config, status: _.get(result, 'trade_state') === 'SUCCESS' ? '1' : '-1' };
|
|
|
+ try {
|
|
|
+ this.tran.update('PayOrder', payOrder._id, update);
|
|
|
+ // 生成账单
|
|
|
+ const billData = _.pick(payOrder, [ 'school_id', 'payer_id', 'payer_role', 'pay_for', 'from_id' ]);
|
|
|
+ // 充值为1,直接支付为-1
|
|
|
+ if (billData.pay_for && _.lowerCase(billData.pay_for) === 'charge') billData.type = '1';
|
|
|
+ else billData.type = '-1';
|
|
|
+ billData.pay_id = payOrder._id;
|
|
|
+ billData.is_pay = update.status;
|
|
|
+ billData.time = moment().format('YYYY-MM-DD HH:mm:ss');
|
|
|
+ this.tran.insert('Bill', billData);
|
|
|
+ await this.tran.run();
|
|
|
+ } catch (error) {
|
|
|
+ await this.tran.rollback();
|
|
|
+ console.log(error);
|
|
|
+ } finally {
|
|
|
+ this.tran.clean();
|
|
|
}
|
|
|
-
|
|
|
- return { data, next: true };
|
|
|
- }
|
|
|
-
|
|
|
- async afterCreate(body, data) {
|
|
|
- // await this.syncData(data);
|
|
|
- const wxSign = await this.payService.create(data);
|
|
|
- return { data, wxSign };
|
|
|
}
|
|
|
|
|
|
async afterUpdate(filter, body, data) {
|
|
@@ -157,7 +127,6 @@ class PayOrderService extends CrudService {
|
|
|
wxBill = await this.billModel.create(obj);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
// 使用余额的处理
|
|
|
if (_.get(config, 'useSurplus')) {
|
|
|
const { bill } = config;
|
|
@@ -178,12 +147,6 @@ class PayOrderService extends CrudService {
|
|
|
await relation.save();
|
|
|
}
|
|
|
}
|
|
|
- // 账单的退款是退款,支付是支付,各自生成数据,不需要修改
|
|
|
- // else {
|
|
|
- // // 已经有数据了, 修改账单.并根据is_pay去做相应的处理
|
|
|
- // await this.billModel.updateOne({ _id: data.config.bill }, { is_pay });
|
|
|
- // billData = await this.billModel.findById(data.config.bill);
|
|
|
- // }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -208,13 +171,14 @@ class PayOrderService extends CrudService {
|
|
|
} else if (_.get(wxOrder, 'trade_state') === 'USERPAYING') {
|
|
|
throw new BusinessError(ErrorCode.SERVICE_FAULT, '订单支付中');
|
|
|
} else {
|
|
|
- // 其他情况就当订单被关闭了.直接新订单
|
|
|
- const order_no = this.getOrderNo();
|
|
|
- data.order_no = order_no;
|
|
|
+ await this.payService.close(order_no);
|
|
|
+ // 其他情况就关闭订单.直接新订单
|
|
|
+ const newNo = this.getOrderNo();
|
|
|
+ data.order_no = newNo;
|
|
|
await data.save();
|
|
|
wxSign = await this.payService.create(data);
|
|
|
}
|
|
|
- return { data, wxSign };
|
|
|
+ return { pay_id: id, wxSign };
|
|
|
}
|
|
|
|
|
|
/**
|