Merge branch 'dev' into release
This commit is contained in:
commit
c743ae77d3
|
|
@ -44,7 +44,7 @@ const attrUpdateMatrix = {
|
|||
actions: ['refundPartially', 'refundAll'],
|
||||
},
|
||||
refundable: {
|
||||
actions: ['succeedPaying', 'closeRefund'],
|
||||
actions: ['succeedPaying', 'closeRefund', 'stopRefunding', 'refundPartially'],
|
||||
},
|
||||
forbidRefundAt: {
|
||||
actions: ['succeedPaying'],
|
||||
|
|
|
|||
|
|
@ -798,7 +798,9 @@ const i18ns = [
|
|||
},
|
||||
"refund": {
|
||||
"create": {
|
||||
"hasAnotherRefunding": "您有一笔退款正在进行中"
|
||||
"hasAnotherRefunding": "您有一笔退款正在进行中",
|
||||
"exceedMax": "退款额度大于可用值",
|
||||
"payUnrefundable": "支付已经不可退款"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@
|
|||
},
|
||||
"refund": {
|
||||
"create": {
|
||||
"hasAnotherRefunding": "您有一笔退款正在进行中"
|
||||
"hasAnotherRefunding": "您有一笔退款正在进行中",
|
||||
"exceedMax": "退款额度大于可用值",
|
||||
"payUnrefundable": "支付已经不可退款"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,8 +44,7 @@ async function changeOrderStateByPay(filter, context, option) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (paid && iState === 'paid') {
|
||||
//已支付完成的订单的paid
|
||||
if (paid) { //对iState是否为paid的判断会影响退款,先去掉
|
||||
payPaid += paid;
|
||||
}
|
||||
if (refunded) {
|
||||
|
|
@ -72,7 +71,7 @@ async function changeOrderStateByPay(filter, context, option) {
|
|||
}
|
||||
}
|
||||
else if (hasRefunding) {
|
||||
assert(!hasPaying && payPaid === orderPrice && payPaid === orderPaid && payRefunded < orderPrice);
|
||||
assert(!hasPaying && payPaid === orderPrice && payRefunded < orderPrice);
|
||||
if (orderIState !== 'refunding' || orderRefunded !== payRefunded) {
|
||||
await context.operate('order', {
|
||||
id: await generateNewIdAsync(),
|
||||
|
|
@ -504,17 +503,6 @@ const triggers = [
|
|||
action: 'create',
|
||||
}
|
||||
];
|
||||
await context.operate('deposit', {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'succeed',
|
||||
data: {
|
||||
accountOper$entity: accountOpers,
|
||||
},
|
||||
filter: {
|
||||
id: depositId,
|
||||
},
|
||||
}, {});
|
||||
cnt++;
|
||||
if (loss > 0) {
|
||||
// 如果有loss就充入system的account账户
|
||||
const [account] = await context.select('account', {
|
||||
|
|
@ -539,6 +527,17 @@ const triggers = [
|
|||
});
|
||||
cnt++;
|
||||
}
|
||||
await context.operate('deposit', {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'succeed',
|
||||
data: {
|
||||
accountOper$entity: accountOpers,
|
||||
},
|
||||
filter: {
|
||||
id: depositId,
|
||||
},
|
||||
}, {});
|
||||
cnt++;
|
||||
}
|
||||
return cnt;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { generateNewId, generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
|
|||
import { getAccountEntity, getPayClazz } from '../utils/payClazz';
|
||||
import assert from 'assert';
|
||||
import { updateWithdrawState } from './withdraw';
|
||||
import { RefundExceedMax, PayUnRefundable } from '../types/Exception';
|
||||
/**
|
||||
* 开始退款的逻辑
|
||||
* @param context
|
||||
|
|
@ -15,6 +16,9 @@ async function startRefunding(context, data) {
|
|||
paid: 1,
|
||||
refunded: 1,
|
||||
iState: 1,
|
||||
entity: 1,
|
||||
entityId: 1,
|
||||
refundable: 1,
|
||||
deposit: {
|
||||
id: 1,
|
||||
accountId: 1,
|
||||
|
|
@ -29,10 +33,32 @@ async function startRefunding(context, data) {
|
|||
}
|
||||
}, { dontCollect: true });
|
||||
const { paid, refunded, deposit, order } = pay;
|
||||
assert(paid - refunded >= data.price);
|
||||
if (paid - refunded < data.price) {
|
||||
throw new RefundExceedMax();
|
||||
}
|
||||
if (!pay.refundable) {
|
||||
throw new PayUnRefundable();
|
||||
}
|
||||
if (deposit) {
|
||||
// 是提现,其Account相应的计算在withdraw进行
|
||||
assert(data.withdrawId);
|
||||
// 充值不可能从account渠道支付
|
||||
assert(pay.entity !== 'account');
|
||||
if (!data.withdrawId && !order?.id) {
|
||||
//充值退款需创建关联的accountOper,若为提现则在withdraw中创建
|
||||
data.accountOper$entity = [
|
||||
{
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'create',
|
||||
data: {
|
||||
id: await generateNewIdAsync(),
|
||||
accountId: deposit.accountId,
|
||||
type: 'refund',
|
||||
totalPlus: -data.price,
|
||||
availPlus: -data.price,
|
||||
refundablePlus: -data.price,
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert(order);
|
||||
|
|
@ -121,24 +147,45 @@ async function succeedRefunding(context, refundId) {
|
|||
id: pay.id,
|
||||
}
|
||||
}, {});
|
||||
const payClazz = await getPayClazz(entity, entityId, context);
|
||||
// 实际执行的退款的额度应该是price - loss
|
||||
const [delta, sysAccountEntity, sysAccountEntityId] = payClazz.calcRefundTax(refundPrice - refundLoss);
|
||||
// sysAccount上减掉实际退款的额度-税费
|
||||
await context.operate('sysAccountOper', {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'create',
|
||||
data: {
|
||||
let d = undefined; //退回至account的退款无渠道退款补偿
|
||||
if (entity === 'account') {
|
||||
//退回至account中的退款,创建accountOper,更新account余额
|
||||
await context.operate('accountOper', {
|
||||
id: await generateNewIdAsync(),
|
||||
delta: refundLoss - refundPrice - delta,
|
||||
entity: sysAccountEntity,
|
||||
entityId: sysAccountEntityId,
|
||||
refundId: refund.id,
|
||||
type: 'refund',
|
||||
}
|
||||
}, {});
|
||||
action: 'create',
|
||||
data: {
|
||||
id: await generateNewIdAsync(),
|
||||
accountId: pay.entityId,
|
||||
entity: 'refund',
|
||||
entityId: refund.id,
|
||||
type: 'consumeBack',
|
||||
totalPlus: refundPrice - refundLoss,
|
||||
availPlus: refundPrice - refundLoss,
|
||||
}
|
||||
}, {});
|
||||
}
|
||||
else {
|
||||
//订单退回至非account的退款会使得系统对应账户的资金发生流出
|
||||
const payClazz = await getPayClazz(entity, entityId, context);
|
||||
// 实际执行的退款的额度应该是price - loss
|
||||
const [delta, sysAccountEntity, sysAccountEntityId] = payClazz.calcRefundTax(refundPrice - refundLoss);
|
||||
// sysAccount上减掉实际退款的额度-税费
|
||||
await context.operate('sysAccountOper', {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'create',
|
||||
data: {
|
||||
id: await generateNewIdAsync(),
|
||||
delta: refundLoss - refundPrice - delta,
|
||||
entity: sysAccountEntity,
|
||||
entityId: sysAccountEntityId,
|
||||
refundId: refund.id,
|
||||
type: 'refund',
|
||||
}
|
||||
}, {});
|
||||
d = delta;
|
||||
}
|
||||
let cnt = 2;
|
||||
if (refundLoss || delta) {
|
||||
if (refundLoss || d) {
|
||||
// 如果有退回或者要缴纳的税费,进入system相关联的account账户
|
||||
const [account] = await context.select('account', {
|
||||
data: {
|
||||
|
|
@ -149,16 +196,16 @@ async function succeedRefunding(context, refundId) {
|
|||
entityId: application.systemId,
|
||||
},
|
||||
}, { dontCollect: true });
|
||||
if (delta) {
|
||||
if (d) {
|
||||
await context.operate('accountOper', {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'create',
|
||||
data: {
|
||||
id: await generateNewIdAsync(),
|
||||
accountId: account.id,
|
||||
type: delta < 0 ? 'taxRefund' : 'tax',
|
||||
totalPlus: -delta,
|
||||
availPlus: -delta,
|
||||
type: d < 0 ? 'taxRefund' : 'tax',
|
||||
totalPlus: -d,
|
||||
availPlus: -d,
|
||||
entity: 'refund',
|
||||
entityId: refund.id,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@ export declare class ExternalPayUtilException<ED extends EntityDict> extends Oak
|
|||
export declare class RefundExceedMax<ED extends EntityDict> extends OakException<ED> {
|
||||
constructor(message?: string);
|
||||
}
|
||||
export declare class PayUnRefundable<ED extends EntityDict> extends OakException<ED> {
|
||||
constructor(message?: string);
|
||||
}
|
||||
export declare class StartPayFailure<ED extends EntityDict> extends OakException<ED> {
|
||||
constructor(message: string);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,12 @@ export class ExternalPayUtilException extends OakException {
|
|||
}
|
||||
export class RefundExceedMax extends OakException {
|
||||
constructor(message) {
|
||||
super(message || '可退款的总额不足');
|
||||
super(message || 'error::refund.create.exceedMax');
|
||||
}
|
||||
}
|
||||
export class PayUnRefundable extends OakException {
|
||||
constructor(message) {
|
||||
super(message || 'error::refund.create.payUnrefundable');
|
||||
}
|
||||
}
|
||||
export class StartPayFailure extends OakException {
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ const attrUpdateMatrix = {
|
|||
actions: ['refundPartially', 'refundAll'],
|
||||
},
|
||||
refundable: {
|
||||
actions: ['succeedPaying', 'closeRefund'],
|
||||
actions: ['succeedPaying', 'closeRefund', 'stopRefunding', 'refundPartially'],
|
||||
},
|
||||
forbidRefundAt: {
|
||||
actions: ['succeedPaying'],
|
||||
|
|
|
|||
|
|
@ -800,7 +800,9 @@ const i18ns = [
|
|||
},
|
||||
"refund": {
|
||||
"create": {
|
||||
"hasAnotherRefunding": "您有一笔退款正在进行中"
|
||||
"hasAnotherRefunding": "您有一笔退款正在进行中",
|
||||
"exceedMax": "退款额度大于可用值",
|
||||
"payUnrefundable": "支付已经不可退款"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@
|
|||
},
|
||||
"refund": {
|
||||
"create": {
|
||||
"hasAnotherRefunding": "您有一笔退款正在进行中"
|
||||
"hasAnotherRefunding": "您有一笔退款正在进行中",
|
||||
"exceedMax": "退款额度大于可用值",
|
||||
"payUnrefundable": "支付已经不可退款"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,8 +47,7 @@ async function changeOrderStateByPay(filter, context, option) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (paid && iState === 'paid') {
|
||||
//已支付完成的订单的paid
|
||||
if (paid) { //对iState是否为paid的判断会影响退款,先去掉
|
||||
payPaid += paid;
|
||||
}
|
||||
if (refunded) {
|
||||
|
|
@ -75,7 +74,7 @@ async function changeOrderStateByPay(filter, context, option) {
|
|||
}
|
||||
}
|
||||
else if (hasRefunding) {
|
||||
(0, assert_1.default)(!hasPaying && payPaid === orderPrice && payPaid === orderPaid && payRefunded < orderPrice);
|
||||
(0, assert_1.default)(!hasPaying && payPaid === orderPrice && payRefunded < orderPrice);
|
||||
if (orderIState !== 'refunding' || orderRefunded !== payRefunded) {
|
||||
await context.operate('order', {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
|
|
@ -507,17 +506,6 @@ const triggers = [
|
|||
action: 'create',
|
||||
}
|
||||
];
|
||||
await context.operate('deposit', {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
action: 'succeed',
|
||||
data: {
|
||||
accountOper$entity: accountOpers,
|
||||
},
|
||||
filter: {
|
||||
id: depositId,
|
||||
},
|
||||
}, {});
|
||||
cnt++;
|
||||
if (loss > 0) {
|
||||
// 如果有loss就充入system的account账户
|
||||
const [account] = await context.select('account', {
|
||||
|
|
@ -542,6 +530,17 @@ const triggers = [
|
|||
});
|
||||
cnt++;
|
||||
}
|
||||
await context.operate('deposit', {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
action: 'succeed',
|
||||
data: {
|
||||
accountOper$entity: accountOpers,
|
||||
},
|
||||
filter: {
|
||||
id: depositId,
|
||||
},
|
||||
}, {});
|
||||
cnt++;
|
||||
}
|
||||
return cnt;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ const uuid_1 = require("oak-domain/lib/utils/uuid");
|
|||
const payClazz_1 = require("../utils/payClazz");
|
||||
const assert_1 = tslib_1.__importDefault(require("assert"));
|
||||
const withdraw_1 = require("./withdraw");
|
||||
const Exception_1 = require("../types/Exception");
|
||||
/**
|
||||
* 开始退款的逻辑
|
||||
* @param context
|
||||
|
|
@ -18,6 +19,9 @@ async function startRefunding(context, data) {
|
|||
paid: 1,
|
||||
refunded: 1,
|
||||
iState: 1,
|
||||
entity: 1,
|
||||
entityId: 1,
|
||||
refundable: 1,
|
||||
deposit: {
|
||||
id: 1,
|
||||
accountId: 1,
|
||||
|
|
@ -32,10 +36,32 @@ async function startRefunding(context, data) {
|
|||
}
|
||||
}, { dontCollect: true });
|
||||
const { paid, refunded, deposit, order } = pay;
|
||||
(0, assert_1.default)(paid - refunded >= data.price);
|
||||
if (paid - refunded < data.price) {
|
||||
throw new Exception_1.RefundExceedMax();
|
||||
}
|
||||
if (!pay.refundable) {
|
||||
throw new Exception_1.PayUnRefundable();
|
||||
}
|
||||
if (deposit) {
|
||||
// 是提现,其Account相应的计算在withdraw进行
|
||||
(0, assert_1.default)(data.withdrawId);
|
||||
// 充值不可能从account渠道支付
|
||||
(0, assert_1.default)(pay.entity !== 'account');
|
||||
if (!data.withdrawId && !order?.id) {
|
||||
//充值退款需创建关联的accountOper,若为提现则在withdraw中创建
|
||||
data.accountOper$entity = [
|
||||
{
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
action: 'create',
|
||||
data: {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
accountId: deposit.accountId,
|
||||
type: 'refund',
|
||||
totalPlus: -data.price,
|
||||
availPlus: -data.price,
|
||||
refundablePlus: -data.price,
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
else {
|
||||
(0, assert_1.default)(order);
|
||||
|
|
@ -124,24 +150,45 @@ async function succeedRefunding(context, refundId) {
|
|||
id: pay.id,
|
||||
}
|
||||
}, {});
|
||||
const payClazz = await (0, payClazz_1.getPayClazz)(entity, entityId, context);
|
||||
// 实际执行的退款的额度应该是price - loss
|
||||
const [delta, sysAccountEntity, sysAccountEntityId] = payClazz.calcRefundTax(refundPrice - refundLoss);
|
||||
// sysAccount上减掉实际退款的额度-税费
|
||||
await context.operate('sysAccountOper', {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
action: 'create',
|
||||
data: {
|
||||
let d = undefined; //退回至account的退款无渠道退款补偿
|
||||
if (entity === 'account') {
|
||||
//退回至account中的退款,创建accountOper,更新account余额
|
||||
await context.operate('accountOper', {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
delta: refundLoss - refundPrice - delta,
|
||||
entity: sysAccountEntity,
|
||||
entityId: sysAccountEntityId,
|
||||
refundId: refund.id,
|
||||
type: 'refund',
|
||||
}
|
||||
}, {});
|
||||
action: 'create',
|
||||
data: {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
accountId: pay.entityId,
|
||||
entity: 'refund',
|
||||
entityId: refund.id,
|
||||
type: 'consumeBack',
|
||||
totalPlus: refundPrice - refundLoss,
|
||||
availPlus: refundPrice - refundLoss,
|
||||
}
|
||||
}, {});
|
||||
}
|
||||
else {
|
||||
//订单退回至非account的退款会使得系统对应账户的资金发生流出
|
||||
const payClazz = await (0, payClazz_1.getPayClazz)(entity, entityId, context);
|
||||
// 实际执行的退款的额度应该是price - loss
|
||||
const [delta, sysAccountEntity, sysAccountEntityId] = payClazz.calcRefundTax(refundPrice - refundLoss);
|
||||
// sysAccount上减掉实际退款的额度-税费
|
||||
await context.operate('sysAccountOper', {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
action: 'create',
|
||||
data: {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
delta: refundLoss - refundPrice - delta,
|
||||
entity: sysAccountEntity,
|
||||
entityId: sysAccountEntityId,
|
||||
refundId: refund.id,
|
||||
type: 'refund',
|
||||
}
|
||||
}, {});
|
||||
d = delta;
|
||||
}
|
||||
let cnt = 2;
|
||||
if (refundLoss || delta) {
|
||||
if (refundLoss || d) {
|
||||
// 如果有退回或者要缴纳的税费,进入system相关联的account账户
|
||||
const [account] = await context.select('account', {
|
||||
data: {
|
||||
|
|
@ -152,16 +199,16 @@ async function succeedRefunding(context, refundId) {
|
|||
entityId: application.systemId,
|
||||
},
|
||||
}, { dontCollect: true });
|
||||
if (delta) {
|
||||
if (d) {
|
||||
await context.operate('accountOper', {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
action: 'create',
|
||||
data: {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
accountId: account.id,
|
||||
type: delta < 0 ? 'taxRefund' : 'tax',
|
||||
totalPlus: -delta,
|
||||
availPlus: -delta,
|
||||
type: d < 0 ? 'taxRefund' : 'tax',
|
||||
totalPlus: -d,
|
||||
availPlus: -d,
|
||||
entity: 'refund',
|
||||
entityId: refund.id,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@ export declare class ExternalPayUtilException<ED extends EntityDict> extends Oak
|
|||
export declare class RefundExceedMax<ED extends EntityDict> extends OakException<ED> {
|
||||
constructor(message?: string);
|
||||
}
|
||||
export declare class PayUnRefundable<ED extends EntityDict> extends OakException<ED> {
|
||||
constructor(message?: string);
|
||||
}
|
||||
export declare class StartPayFailure<ED extends EntityDict> extends OakException<ED> {
|
||||
constructor(message: string);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.makeException = exports.StartPayFailure = exports.RefundExceedMax = exports.ExternalPayUtilException = void 0;
|
||||
exports.makeException = exports.StartPayFailure = exports.PayUnRefundable = exports.RefundExceedMax = exports.ExternalPayUtilException = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const types_1 = require("oak-domain/lib/types");
|
||||
const DependentExceptions_1 = tslib_1.__importDefault(require("./DependentExceptions"));
|
||||
|
|
@ -21,10 +21,16 @@ class ExternalPayUtilException extends types_1.OakException {
|
|||
exports.ExternalPayUtilException = ExternalPayUtilException;
|
||||
class RefundExceedMax extends types_1.OakException {
|
||||
constructor(message) {
|
||||
super(message || '可退款的总额不足');
|
||||
super(message || 'error::refund.create.exceedMax');
|
||||
}
|
||||
}
|
||||
exports.RefundExceedMax = RefundExceedMax;
|
||||
class PayUnRefundable extends types_1.OakException {
|
||||
constructor(message) {
|
||||
super(message || 'error::refund.create.payUnrefundable');
|
||||
}
|
||||
}
|
||||
exports.PayUnRefundable = PayUnRefundable;
|
||||
class StartPayFailure extends types_1.OakException {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "oak-pay-business",
|
||||
"version": "2.5.1",
|
||||
"version": "2.5.2",
|
||||
"description": "",
|
||||
"files": [
|
||||
"lib/**/*",
|
||||
|
|
@ -29,9 +29,9 @@
|
|||
"dependencies": {
|
||||
"classnames": "^2.3.1",
|
||||
"dayjs": "^1.11.5",
|
||||
"oak-domain": "^5.1.2",
|
||||
"oak-frontend-base": "^5.3.10",
|
||||
"oak-general-business": "~5.5.1",
|
||||
"oak-domain": "^5.1.5",
|
||||
"oak-frontend-base": "^5.3.13",
|
||||
"oak-general-business": "~5.5.3",
|
||||
"wechat-pay-nodejs": "^0.2.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ const attrUpdateMatrix: AttrUpdateMatrix<EntityDict> = {
|
|||
actions: ['refundPartially', 'refundAll'],
|
||||
},
|
||||
refundable: {
|
||||
actions: ['succeedPaying', 'closeRefund'],
|
||||
actions: ['succeedPaying', 'closeRefund', 'stopRefunding', 'refundPartially'],
|
||||
},
|
||||
forbidRefundAt: {
|
||||
actions: ['succeedPaying'],
|
||||
|
|
|
|||
|
|
@ -800,7 +800,9 @@ const i18ns: I18n[] = [
|
|||
},
|
||||
"refund": {
|
||||
"create": {
|
||||
"hasAnotherRefunding": "您有一笔退款正在进行中"
|
||||
"hasAnotherRefunding": "您有一笔退款正在进行中",
|
||||
"exceedMax": "退款额度大于可用值",
|
||||
"payUnrefundable": "支付已经不可退款"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@
|
|||
},
|
||||
"refund": {
|
||||
"create": {
|
||||
"hasAnotherRefunding": "您有一笔退款正在进行中"
|
||||
"hasAnotherRefunding": "您有一笔退款正在进行中",
|
||||
"exceedMax": "退款额度大于可用值",
|
||||
"payUnrefundable": "支付已经不可退款"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -56,8 +56,7 @@ async function changeOrderStateByPay(
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (paid && iState === 'paid') {
|
||||
//已支付完成的订单的paid
|
||||
if (paid) { //对iState是否为paid的判断会影响退款,先去掉
|
||||
payPaid += paid;
|
||||
}
|
||||
if (refunded) {
|
||||
|
|
@ -85,7 +84,7 @@ async function changeOrderStateByPay(
|
|||
}
|
||||
}
|
||||
else if (hasRefunding) {
|
||||
assert(!hasPaying && payPaid === orderPrice && payPaid === orderPaid && payRefunded < orderPrice);
|
||||
assert(!hasPaying && payPaid === orderPrice && payRefunded < orderPrice);
|
||||
if (orderIState !== 'refunding' || orderRefunded !== payRefunded) {
|
||||
await context.operate('order', {
|
||||
id: await generateNewIdAsync(),
|
||||
|
|
@ -292,7 +291,7 @@ const triggers: Trigger<EntityDict, 'pay', BRC>[] = [
|
|||
priority: 99,
|
||||
fn: async ({ operation }, context, option) => {
|
||||
const { data, filter, action, id } = operation as EntityDict['pay']['Update'];
|
||||
|
||||
|
||||
const pays = await context.select('pay', {
|
||||
data: {
|
||||
id: 1,
|
||||
|
|
@ -313,10 +312,10 @@ const triggers: Trigger<EntityDict, 'pay', BRC>[] = [
|
|||
},
|
||||
filter,
|
||||
}, { dontCollect: true });
|
||||
|
||||
|
||||
for (const pay of pays) {
|
||||
const { orderId, depositId, iState, deposit, application } = pay;
|
||||
|
||||
|
||||
context.saveOperationToEvent(id, `${DATA_SUBSCRIBER_KEYS.payStateChanged}-${filter!.id!}`);
|
||||
if (orderId) {
|
||||
await changeOrderStateByPay({ id: orderId }, context, option);
|
||||
|
|
@ -366,11 +365,11 @@ const triggers: Trigger<EntityDict, 'pay', BRC>[] = [
|
|||
for (const pay of pays) {
|
||||
const { applicationId, entity, entityId, iState, depositId } = pay;
|
||||
assert(iState === 'unpaid' || iState === 'paying');
|
||||
|
||||
|
||||
if (iState === 'paying') {
|
||||
const payClazz = await getPayClazz(entity!, entityId!, context);
|
||||
await payClazz.close(pay as EntityDict['pay']['OpSchema']);
|
||||
|
||||
|
||||
cnt++;
|
||||
}
|
||||
if (depositId) {
|
||||
|
|
@ -552,18 +551,7 @@ const triggers: Trigger<EntityDict, 'pay', BRC>[] = [
|
|||
action: 'create',
|
||||
}
|
||||
];
|
||||
await context.operate('deposit', {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'succeed',
|
||||
data: {
|
||||
accountOper$entity: accountOpers,
|
||||
},
|
||||
filter: {
|
||||
id: depositId,
|
||||
},
|
||||
}, {});
|
||||
|
||||
cnt++;
|
||||
if (loss > 0) {
|
||||
// 如果有loss就充入system的account账户
|
||||
const [account] = await context.select('account', {
|
||||
|
|
@ -589,6 +577,20 @@ const triggers: Trigger<EntityDict, 'pay', BRC>[] = [
|
|||
|
||||
cnt++;
|
||||
}
|
||||
|
||||
await context.operate('deposit', {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'succeed',
|
||||
data: {
|
||||
accountOper$entity: accountOpers,
|
||||
},
|
||||
filter: {
|
||||
id: depositId,
|
||||
},
|
||||
}, {});
|
||||
|
||||
cnt++;
|
||||
|
||||
}
|
||||
|
||||
return cnt;
|
||||
|
|
@ -673,7 +675,7 @@ const triggers: Trigger<EntityDict, 'pay', BRC>[] = [
|
|||
availPlus: pay.paid!,
|
||||
},
|
||||
}, {});
|
||||
cnt ++;
|
||||
cnt++;
|
||||
}
|
||||
else {
|
||||
cnt += await tryCompleteAccountPay(pay.id!, context);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { BRC } from '../types/RuntimeCxt';
|
|||
import { getAccountEntity, getPayClazz } from '../utils/payClazz';
|
||||
import assert from 'assert';
|
||||
import { updateWithdrawState } from './withdraw';
|
||||
|
||||
import { RefundExceedMax, PayUnRefundable } from '@project/types/Exception';
|
||||
/**
|
||||
* 开始退款的逻辑
|
||||
* @param context
|
||||
|
|
@ -21,6 +21,9 @@ async function startRefunding(context: BRC, data: EntityDict['refund']['CreateSi
|
|||
paid: 1,
|
||||
refunded: 1,
|
||||
iState: 1,
|
||||
entity: 1,
|
||||
entityId: 1,
|
||||
refundable: 1,
|
||||
deposit: {
|
||||
id: 1,
|
||||
accountId: 1,
|
||||
|
|
@ -36,10 +39,32 @@ async function startRefunding(context: BRC, data: EntityDict['refund']['CreateSi
|
|||
}, { dontCollect: true });
|
||||
|
||||
const { paid, refunded, deposit, order } = pay;
|
||||
assert(paid! - refunded! >= data.price!);
|
||||
if (paid! - refunded! < data.price!) {
|
||||
throw new RefundExceedMax();
|
||||
}
|
||||
if (!pay.refundable) {
|
||||
throw new PayUnRefundable();
|
||||
}
|
||||
if (deposit) {
|
||||
// 是提现,其Account相应的计算在withdraw进行
|
||||
assert(data.withdrawId!);
|
||||
// 充值不可能从account渠道支付
|
||||
assert(pay.entity !== 'account');
|
||||
if (!data.withdrawId && !order?.id) {
|
||||
//充值退款需创建关联的accountOper,若为提现则在withdraw中创建
|
||||
data.accountOper$entity = [
|
||||
{
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'create',
|
||||
data: {
|
||||
id: await generateNewIdAsync(),
|
||||
accountId: deposit.accountId,
|
||||
type: 'refund',
|
||||
totalPlus: -data.price!,
|
||||
availPlus: -data.price!,
|
||||
refundablePlus: -data.price!,
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert(order);
|
||||
|
|
@ -138,26 +163,46 @@ async function succeedRefunding(context: BRC, refundId: string) {
|
|||
}
|
||||
}, {});
|
||||
|
||||
const payClazz = await getPayClazz(entity!, entityId!, context);
|
||||
// 实际执行的退款的额度应该是price - loss
|
||||
const [delta, sysAccountEntity, sysAccountEntityId] = payClazz.calcRefundTax(refundPrice - refundLoss!);
|
||||
// sysAccount上减掉实际退款的额度-税费
|
||||
await context.operate('sysAccountOper', {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'create',
|
||||
data: {
|
||||
let d = undefined; //退回至account的退款无渠道退款补偿
|
||||
if (entity === 'account') {
|
||||
//退回至account中的退款,创建accountOper,更新account余额
|
||||
await context.operate('accountOper', {
|
||||
id: await generateNewIdAsync(),
|
||||
delta: refundLoss! - refundPrice! - delta!,
|
||||
entity: sysAccountEntity,
|
||||
entityId: sysAccountEntityId,
|
||||
refundId: refund.id,
|
||||
type: 'refund',
|
||||
}
|
||||
}, {});
|
||||
action: 'create',
|
||||
data: {
|
||||
id: await generateNewIdAsync(),
|
||||
accountId: pay!.entityId!,
|
||||
entity: 'refund',
|
||||
entityId: refund.id,
|
||||
type: 'consumeBack',
|
||||
totalPlus: refundPrice! - refundLoss!,
|
||||
availPlus: refundPrice! - refundLoss!,
|
||||
}
|
||||
}, {});
|
||||
} else {
|
||||
//订单退回至非account的退款会使得系统对应账户的资金发生流出
|
||||
const payClazz = await getPayClazz(entity!, entityId!, context);
|
||||
// 实际执行的退款的额度应该是price - loss
|
||||
const [delta, sysAccountEntity, sysAccountEntityId] = payClazz.calcRefundTax(refundPrice - refundLoss!);
|
||||
// sysAccount上减掉实际退款的额度-税费
|
||||
await context.operate('sysAccountOper', {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'create',
|
||||
data: {
|
||||
id: await generateNewIdAsync(),
|
||||
delta: refundLoss! - refundPrice! - delta!,
|
||||
entity: sysAccountEntity,
|
||||
entityId: sysAccountEntityId,
|
||||
refundId: refund.id,
|
||||
type: 'refund',
|
||||
}
|
||||
}, {});
|
||||
d = delta;
|
||||
}
|
||||
|
||||
let cnt = 2;
|
||||
|
||||
if (refundLoss || delta) {
|
||||
if (refundLoss || d) {
|
||||
// 如果有退回或者要缴纳的税费,进入system相关联的account账户
|
||||
const [account] = await context.select('account', {
|
||||
data: {
|
||||
|
|
@ -168,16 +213,16 @@ async function succeedRefunding(context: BRC, refundId: string) {
|
|||
entityId: application!.systemId!,
|
||||
},
|
||||
}, { dontCollect: true });
|
||||
if (delta) {
|
||||
if (d) {
|
||||
await context.operate('accountOper', {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'create',
|
||||
data: {
|
||||
id: await generateNewIdAsync(),
|
||||
accountId: account!.id,
|
||||
type: delta < 0 ? 'taxRefund' : 'tax',
|
||||
totalPlus: -delta,
|
||||
availPlus: -delta,
|
||||
type: d < 0 ? 'taxRefund' : 'tax',
|
||||
totalPlus: -d,
|
||||
availPlus: -d,
|
||||
entity: 'refund',
|
||||
entityId: refund.id!,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -20,7 +20,13 @@ export class ExternalPayUtilException<ED extends EntityDict> extends OakExceptio
|
|||
|
||||
export class RefundExceedMax<ED extends EntityDict> extends OakException<ED> {
|
||||
constructor(message?: string) {
|
||||
super(message || '可退款的总额不足');
|
||||
super(message || 'error::refund.create.exceedMax');
|
||||
}
|
||||
}
|
||||
|
||||
export class PayUnRefundable<ED extends EntityDict> extends OakException<ED> {
|
||||
constructor(message?: string) {
|
||||
super(message || 'error::refund.create.payUnrefundable');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue