```
feat(commission): 添加分账成功后佣金处理功能 添加了新的方法来处理分账成功后的佣金结算: - 新增 runCommissionRewardByOrderWithoutWallet 方法用于分账成功时标记已结算 - 新增 runCommissionRewardWithoutWallet 方法处理不入余额的佣金奖励 - 避免在分账成功时重复将佣金计入用户余额 feat(regional_agent): 添加区域代理分账处理逻辑 - 新增 settleByRegionalOrderWithoutWallet 方法处理区域代理分账 - 新增 settleRewardWithoutWallet 方法处理不入钱包的奖励结算 - 完善区域代理佣金处理流程 refactor(split): 优化分账执行器逻辑 - 修改 SplitExecutor 类以支持延迟钱包结算 - 添加异常处理和事务管理 - 支持根据支付网关类型决定是否延迟钱包结算 feat(split): 实现分账完成后钱包结算机制 - 添加 SplitWalletSettlement 类来管理分账与钱包结算的协调 - 支持在分账成功后延迟钱包入账,失败时回退到钱包 - 修复汇付分账与佣金结算的时间冲突问题 refactor(hook): 调整分账钩子事件处理 - 修改 SplitHook 类的事件参数传递 - 更新各个订单状态变更事件的分账触发逻辑 - 确保分账执行时能正确获取事件类型 docs(tests): 更新分账佣金验证说明 - 更新测试文件中的注释说明 - 明确汇付/微信分账成功后的佣金处理方式 ```
这个提交包含在:
@@ -91,6 +91,79 @@ class Reward
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分账成功:标记已结算,累计收益,不入余额
|
||||
*/
|
||||
public function runCommissionRewardByOrderWithoutWallet($event, $commissionOrder)
|
||||
{
|
||||
if (is_numeric($commissionOrder)) {
|
||||
$commissionOrder = OrderModel::get($commissionOrder);
|
||||
}
|
||||
if (!$commissionOrder) {
|
||||
return false;
|
||||
}
|
||||
if ($commissionOrder['commission_reward_status'] !== self::COMMISSION_REWARD_STATUS_WAITING) {
|
||||
return false;
|
||||
}
|
||||
$commissionEvent = $commissionOrder['commission_event'];
|
||||
if ($commissionEvent !== $event && $event !== 'admin') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$commissionOrder->commission_reward_status = self::COMMISSION_REWARD_STATUS_ACCOUNTED;
|
||||
$commissionOrder->commission_time = time();
|
||||
$commissionOrder->save();
|
||||
|
||||
$commissionRewards = RewardModel::all([
|
||||
'commission_order_id' => $commissionOrder['id'],
|
||||
'status' => self::COMMISSION_REWARD_STATUS_WAITING,
|
||||
]);
|
||||
if (!$commissionRewards) {
|
||||
return false;
|
||||
}
|
||||
foreach ($commissionRewards as $commissionReward) {
|
||||
$this->runCommissionRewardWithoutWallet($event, $commissionReward);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function runCommissionRewardWithoutWallet($event, $commissionReward)
|
||||
{
|
||||
if (is_numeric($commissionReward)) {
|
||||
$commissionReward = RewardModel::get($commissionReward);
|
||||
}
|
||||
if (!$commissionReward || $commissionReward->status != self::COMMISSION_REWARD_STATUS_WAITING) {
|
||||
return false;
|
||||
}
|
||||
if ($this->isRepurchaseSelfReward($commissionReward)) {
|
||||
$user = UserModel::get($commissionReward->agent_id);
|
||||
if (!$user) {
|
||||
return false;
|
||||
}
|
||||
$commissionReward->status = self::COMMISSION_REWARD_STATUS_ACCOUNTED;
|
||||
$commissionReward->save();
|
||||
Log::write($commissionReward->agent_id, 'reward', [
|
||||
'action' => $event,
|
||||
'reward' => $commissionReward,
|
||||
'wallet_skipped' => 'gateway_split',
|
||||
], $this->oper);
|
||||
return true;
|
||||
}
|
||||
$rewardAgent = new Agent($commissionReward->agent_id);
|
||||
if ($rewardAgent && $rewardAgent->isAgentAvaliable()) {
|
||||
$rewardAgent->agent->setInc('total_income', $commissionReward->commission);
|
||||
$commissionReward->status = self::COMMISSION_REWARD_STATUS_ACCOUNTED;
|
||||
$commissionReward->save();
|
||||
Log::write($rewardAgent->user->id, 'reward', [
|
||||
'action' => $event,
|
||||
'reward' => $commissionReward,
|
||||
'wallet_skipped' => 'gateway_split',
|
||||
], $this->oper);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行奖金计划,直接派发佣金
|
||||
*
|
||||
@@ -140,7 +213,6 @@ class Reward
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 扣除/取消 分销订单
|
||||
*
|
||||
|
||||
@@ -8,6 +8,8 @@ use addons\shopro\model\regional_agent\Agent as AgentModel;
|
||||
use addons\shopro\model\regional_agent\Level as LevelModel;
|
||||
use addons\shopro\model\regional_agent\Order as RegionalOrderModel;
|
||||
use addons\shopro\model\regional_agent\Reward as RewardModel;
|
||||
use addons\shopro\library\split\SplitWalletSettlement;
|
||||
use addons\shopro\library\split\SplitWalletSettlement;
|
||||
|
||||
/**
|
||||
* 区域代理分佣
|
||||
@@ -291,7 +293,9 @@ class Commission
|
||||
$agent->setInc('order_count', 1);
|
||||
|
||||
if ($this->_config->getCommissionEvent() === 'payed') {
|
||||
(new Reward())->settleByRegionalOrder($regionalOrder->id, 'payed');
|
||||
if (!SplitWalletSettlement::shouldDeferRegionalWallet($order, 'payed')) {
|
||||
(new Reward())->settleByRegionalOrder($regionalOrder->id, 'payed');
|
||||
}
|
||||
}
|
||||
|
||||
return $regionalOrder;
|
||||
|
||||
@@ -38,6 +38,28 @@ class Reward
|
||||
return true;
|
||||
}
|
||||
|
||||
public function settleByRegionalOrderWithoutWallet($regionalOrderId, $event)
|
||||
{
|
||||
$regionalOrder = RegionalOrderModel::get($regionalOrderId);
|
||||
if (!$regionalOrder || $regionalOrder['commission_reward_status'] !== self::STATUS_WAITING) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$regionalOrder->commission_reward_status = self::STATUS_ACCOUNTED;
|
||||
$regionalOrder->commission_time = time();
|
||||
$regionalOrder->save();
|
||||
|
||||
$rewards = RewardModel::where('regional_order_id', $regionalOrderId)
|
||||
->where('status', self::STATUS_WAITING)
|
||||
->select();
|
||||
|
||||
foreach ($rewards as $reward) {
|
||||
$this->settleRewardWithoutWallet($reward, $event);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function settleReward($reward, $event)
|
||||
{
|
||||
if ($reward['status'] !== self::STATUS_WAITING) {
|
||||
@@ -68,6 +90,28 @@ class Reward
|
||||
}
|
||||
}
|
||||
|
||||
public function settleRewardWithoutWallet($reward, $event)
|
||||
{
|
||||
if ($reward['status'] !== self::STATUS_WAITING) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$agent = AgentModel::get($reward['agent_id']);
|
||||
if (!$agent || $agent['status'] !== AgentModel::STATUS_NORMAL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$agentUser = UserModel::get($reward['agent_user_id']);
|
||||
if (!$agentUser) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$agent->setInc('total_income', $reward['commission']);
|
||||
$reward->status = self::STATUS_ACCOUNTED;
|
||||
$reward->save();
|
||||
return true;
|
||||
}
|
||||
|
||||
public function backByRegionalOrder($regionalOrderId, $event)
|
||||
{
|
||||
$regionalOrder = RegionalOrderModel::get($regionalOrderId);
|
||||
|
||||
@@ -22,93 +22,106 @@ class SplitExecutor
|
||||
|
||||
public function executeByOrderId($orderId, $event = 'payed')
|
||||
{
|
||||
if (!$this->config->isEnable()) {
|
||||
return false;
|
||||
}
|
||||
$order = Order::get($orderId);
|
||||
$deferWallet = $order && SplitWalletSettlement::shouldDeferForGatewaySplit($order, $event);
|
||||
$ok = false;
|
||||
|
||||
if (class_exists('\\addons\\shopro_huifu\\library\\Bridge')) {
|
||||
$hookParams = [
|
||||
'order_id' => $orderId,
|
||||
'event' => $event,
|
||||
];
|
||||
$handled = \think\Hook::listen('shopro_split_execute', $hookParams, null, true);
|
||||
if ($handled === true) {
|
||||
try {
|
||||
if (!$this->config->isEnable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (class_exists('\\addons\\shopro_huifu\\library\\Bridge')) {
|
||||
$hookParams = [
|
||||
'order_id' => $orderId,
|
||||
'event' => $event,
|
||||
];
|
||||
$handled = \think\Hook::listen('shopro_split_execute', $hookParams, null, true);
|
||||
if ($handled === true) {
|
||||
$ok = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$orderCheck = Order::get($orderId);
|
||||
if ($orderCheck && $orderCheck['pay_type'] === 'huifu_wechat') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$exists = SplitOrder::where('order_id', $orderId)->where('status', 'in', [1, 2])->find();
|
||||
if ($exists) {
|
||||
$ok = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$orderCheck = Order::get($orderId);
|
||||
if ($orderCheck && $orderCheck['pay_type'] === 'huifu_wechat') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$exists = SplitOrder::where('order_id', $orderId)->where('status', 'in', [1, 2])->find();
|
||||
if ($exists) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$order = Order::get($orderId);
|
||||
if (!$order || empty($order['transaction_id'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$items = $this->calculator->calculate($orderId);
|
||||
if (empty($items)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$outOrderNo = 'PS' . date('YmdHis') . $orderId;
|
||||
$splitAmount = array_sum(array_column($items, 'amount'));
|
||||
|
||||
Db::startTrans();
|
||||
try {
|
||||
$splitOrder = SplitOrder::create([
|
||||
'order_id' => $orderId,
|
||||
'order_sn' => $order['order_sn'],
|
||||
'transaction_id' => $order['transaction_id'],
|
||||
'out_order_no' => $outOrderNo,
|
||||
'total_amount' => $order['pay_fee'],
|
||||
'split_amount' => $splitAmount,
|
||||
'status' => 1,
|
||||
]);
|
||||
|
||||
$receivers = [];
|
||||
foreach ($items as $item) {
|
||||
SplitOrderReceiver::create([
|
||||
'split_order_id' => $splitOrder->id,
|
||||
'receiver_id' => $item['receiver_id'],
|
||||
'role_type' => $item['role_type'],
|
||||
'amount' => $item['amount'],
|
||||
'description' => $item['description'],
|
||||
'status' => 0,
|
||||
]);
|
||||
$receivers[] = [
|
||||
'type' => $item['receiver_type'],
|
||||
'account' => $item['receiver_account'],
|
||||
'name' => $item['receiver_name'] ?? '',
|
||||
'amount' => intval(round($item['amount'] * 100)),
|
||||
'description' => $item['description'],
|
||||
];
|
||||
$order = Order::get($orderId);
|
||||
if (!$order || empty($order['transaction_id'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = $this->service->createOrder([
|
||||
'transaction_id' => $order['transaction_id'],
|
||||
'out_order_no' => $outOrderNo,
|
||||
'receivers' => $receivers,
|
||||
'unfreeze_unsplit' => true,
|
||||
]);
|
||||
$items = $this->calculator->calculate($orderId);
|
||||
if (empty($items)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$splitOrder->wx_result = is_array($result) ? json_encode($result, JSON_UNESCAPED_UNICODE) : json_encode($result);
|
||||
$splitOrder->status = 2;
|
||||
$splitOrder->save();
|
||||
$outOrderNo = 'PS' . date('YmdHis') . $orderId;
|
||||
$splitAmount = array_sum(array_column($items, 'amount'));
|
||||
|
||||
SplitOrderReceiver::where('split_order_id', $splitOrder->id)->update(['status' => 1]);
|
||||
Db::commit();
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
$this->markFailed($orderId, $outOrderNo ?? ('PS' . $orderId), $order, $items ?? [], $e->getMessage());
|
||||
return false;
|
||||
Db::startTrans();
|
||||
try {
|
||||
$splitOrder = SplitOrder::create([
|
||||
'order_id' => $orderId,
|
||||
'order_sn' => $order['order_sn'],
|
||||
'transaction_id' => $order['transaction_id'],
|
||||
'out_order_no' => $outOrderNo,
|
||||
'total_amount' => $order['pay_fee'],
|
||||
'split_amount' => $splitAmount,
|
||||
'status' => 1,
|
||||
]);
|
||||
|
||||
$receivers = [];
|
||||
foreach ($items as $item) {
|
||||
SplitOrderReceiver::create([
|
||||
'split_order_id' => $splitOrder->id,
|
||||
'receiver_id' => $item['receiver_id'],
|
||||
'role_type' => $item['role_type'],
|
||||
'amount' => $item['amount'],
|
||||
'description' => $item['description'],
|
||||
'status' => 0,
|
||||
]);
|
||||
$receivers[] = [
|
||||
'type' => $item['receiver_type'],
|
||||
'account' => $item['receiver_account'],
|
||||
'name' => $item['receiver_name'] ?? '',
|
||||
'amount' => intval(round($item['amount'] * 100)),
|
||||
'description' => $item['description'],
|
||||
];
|
||||
}
|
||||
|
||||
$result = $this->service->createOrder([
|
||||
'transaction_id' => $order['transaction_id'],
|
||||
'out_order_no' => $outOrderNo,
|
||||
'receivers' => $receivers,
|
||||
'unfreeze_unsplit' => true,
|
||||
]);
|
||||
|
||||
$splitOrder->wx_result = is_array($result) ? json_encode($result, JSON_UNESCAPED_UNICODE) : json_encode($result);
|
||||
$splitOrder->status = 2;
|
||||
$splitOrder->save();
|
||||
|
||||
SplitOrderReceiver::where('split_order_id', $splitOrder->id)->update(['status' => 1]);
|
||||
Db::commit();
|
||||
$ok = true;
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
$this->markFailed($orderId, $outOrderNo ?? ('PS' . $orderId), $order, $items ?? [], $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
} finally {
|
||||
if ($deferWallet) {
|
||||
SplitWalletSettlement::finalizeAfterSplitAttempt($orderId, $event, $ok);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
namespace addons\shopro\library\split;
|
||||
|
||||
use addons\shopro\library\commission\Config as CommissionConfig;
|
||||
use addons\shopro\library\commission\Reward as CommissionRewardLibrary;
|
||||
use addons\shopro\library\regional_agent\Config as RegionalConfig;
|
||||
use addons\shopro\library\regional_agent\Reward as RegionalRewardLibrary;
|
||||
use addons\shopro\model\Order;
|
||||
use addons\shopro\model\commission\Order as CommissionOrderModel;
|
||||
use addons\shopro\model\regional_agent\Order as RegionalOrderModel;
|
||||
use addons\shopro\model\split\SplitOrder;
|
||||
|
||||
/**
|
||||
* 支付通道分账与钱包佣金互斥:分账成功则不入余额,失败则回退入余额
|
||||
*/
|
||||
class SplitWalletSettlement
|
||||
{
|
||||
public static function shouldDeferCommissionWallet($order, $event)
|
||||
{
|
||||
if (!self::shouldDeferForGatewaySplit($order, $event)) {
|
||||
return false;
|
||||
}
|
||||
$commissionEvent = (new CommissionConfig())->getCommissionEvent();
|
||||
return $commissionEvent === $event;
|
||||
}
|
||||
|
||||
public static function shouldDeferRegionalWallet($order, $event)
|
||||
{
|
||||
if (!self::shouldDeferForGatewaySplit($order, $event)) {
|
||||
return false;
|
||||
}
|
||||
$regionalEvent = (new RegionalConfig())->getCommissionEvent();
|
||||
return $regionalEvent === $event;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前订单是否应等分账结果再决定钱包入账
|
||||
*/
|
||||
public static function shouldDeferForGatewaySplit($order, $event)
|
||||
{
|
||||
if (is_numeric($order)) {
|
||||
$order = Order::get($order);
|
||||
}
|
||||
if (!$order) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$config = new Config();
|
||||
if (!$config->isEnable() || !$config->shouldSkipWallet()) {
|
||||
return false;
|
||||
}
|
||||
if ($config->getTiming() !== $event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (class_exists('\\addons\\shopro_huifu\\library\\Bridge')
|
||||
&& \addons\shopro_huifu\library\Bridge::shouldHandleSplit($order)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (in_array($config->getMode(), ['wechat', 'both'], true) && $order['pay_type'] === 'wechat') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function isSplitSuccessful($orderId)
|
||||
{
|
||||
return SplitOrder::where('order_id', $orderId)
|
||||
->where('status', 'in', [2, 3])
|
||||
->count() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分账尝试结束后结算佣金(成功=仅记账不入钱包,失败=入钱包)
|
||||
*/
|
||||
public static function finalizeAfterSplitAttempt($orderId, $event, $splitExecutedOk = false)
|
||||
{
|
||||
if (!self::shouldDeferForGatewaySplit($orderId, $event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self::isSplitSuccessful($orderId)) {
|
||||
self::settleOrderWithoutWallet($orderId, $event);
|
||||
} else {
|
||||
self::settleOrderToWallet($orderId, $event);
|
||||
}
|
||||
}
|
||||
|
||||
public static function settleOrderWithoutWallet($orderId, $event)
|
||||
{
|
||||
$commissionLib = new CommissionRewardLibrary();
|
||||
$commissionOrders = CommissionOrderModel::where('order_id', $orderId)
|
||||
->where('commission_reward_status', CommissionRewardLibrary::COMMISSION_REWARD_STATUS_WAITING)
|
||||
->select();
|
||||
foreach ($commissionOrders as $commissionOrder) {
|
||||
if ($commissionOrder['commission_event'] === $event || $event === 'admin') {
|
||||
$commissionLib->runCommissionRewardByOrderWithoutWallet($event, $commissionOrder);
|
||||
}
|
||||
}
|
||||
|
||||
$regionalLib = new RegionalRewardLibrary();
|
||||
$regionalOrders = RegionalOrderModel::where('order_id', $orderId)
|
||||
->where('commission_reward_status', RegionalRewardLibrary::STATUS_WAITING)
|
||||
->select();
|
||||
foreach ($regionalOrders as $regionalOrder) {
|
||||
if ($regionalOrder['commission_event'] === $event) {
|
||||
$regionalLib->settleByRegionalOrderWithoutWallet($regionalOrder->id, $event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function settleOrderToWallet($orderId, $event)
|
||||
{
|
||||
$commissionLib = new CommissionRewardLibrary();
|
||||
$commissionOrders = CommissionOrderModel::where('order_id', $orderId)
|
||||
->where('commission_reward_status', CommissionRewardLibrary::COMMISSION_REWARD_STATUS_WAITING)
|
||||
->select();
|
||||
foreach ($commissionOrders as $commissionOrder) {
|
||||
if ($commissionOrder['commission_event'] === $event || $event === 'admin') {
|
||||
$commissionLib->runCommissionRewardByOrder($event, $commissionOrder);
|
||||
}
|
||||
}
|
||||
|
||||
$regionalLib = new RegionalRewardLibrary();
|
||||
$regionalOrders = RegionalOrderModel::where('order_id', $orderId)
|
||||
->where('commission_reward_status', RegionalRewardLibrary::STATUS_WAITING)
|
||||
->select();
|
||||
foreach ($regionalOrders as $regionalOrder) {
|
||||
if ($regionalOrder['commission_event'] === $event) {
|
||||
$regionalLib->settleByRegionalOrder($regionalOrder->id, $event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ namespace addons\shopro\listener\commission;
|
||||
use addons\shopro\library\commission\Agent as AgentLibrary;
|
||||
use addons\shopro\library\commission\Commission as CommissionLibrary;
|
||||
use addons\shopro\library\commission\Reward as RewardLibrary;
|
||||
use addons\shopro\library\split\SplitWalletSettlement;
|
||||
use addons\shopro\model\Order;
|
||||
use addons\shopro\model\OrderItem;
|
||||
|
||||
@@ -48,8 +49,10 @@ class CommissionHook
|
||||
$commissionOrder = $commission->addCommissionOrder();
|
||||
// 执行奖金计划
|
||||
$commission->runCommissionPlan($commissionOrder);
|
||||
// 支付后拨款
|
||||
(new RewardLibrary())->runCommissionRewardByOrder('payed', $commissionOrder->id);
|
||||
// 支付后拨款(汇付分账同事件时延至分账结果后再结算)
|
||||
if (!SplitWalletSettlement::shouldDeferCommissionWallet($order, 'payed')) {
|
||||
(new RewardLibrary())->runCommissionRewardByOrder('payed', $commissionOrder->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace addons\shopro\listener\split;
|
||||
|
||||
use addons\shopro\library\split\Config;
|
||||
use addons\shopro\library\split\SplitExecutor;
|
||||
|
||||
class SplitHook
|
||||
{
|
||||
protected function shouldRun($event)
|
||||
@@ -21,7 +20,7 @@ class SplitHook
|
||||
if (!$this->shouldRun('payed')) {
|
||||
return;
|
||||
}
|
||||
$this->runSplit($params);
|
||||
$this->runSplit($params, 'payed');
|
||||
}
|
||||
|
||||
public function orderConfirmAfter(&$params)
|
||||
@@ -29,7 +28,7 @@ class SplitHook
|
||||
if (!$this->shouldRun('confirm')) {
|
||||
return;
|
||||
}
|
||||
$this->runSplit($params);
|
||||
$this->runSplit($params, 'confirm');
|
||||
}
|
||||
|
||||
public function orderFinish(&$params)
|
||||
@@ -37,7 +36,7 @@ class SplitHook
|
||||
if (!$this->shouldRun('finish')) {
|
||||
return;
|
||||
}
|
||||
$this->runSplit($params);
|
||||
$this->runSplit($params, 'finish');
|
||||
}
|
||||
|
||||
public function orderRefundAfter(&$params)
|
||||
@@ -52,12 +51,12 @@ class SplitHook
|
||||
}
|
||||
}
|
||||
|
||||
protected function runSplit($params)
|
||||
protected function runSplit($params, $event)
|
||||
{
|
||||
$order = $params['order'] ?? null;
|
||||
if (!$order) {
|
||||
return;
|
||||
}
|
||||
(new SplitExecutor())->executeByOrderId($order['id']);
|
||||
(new SplitExecutor())->executeByOrderId($order['id'], $event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ function printSummary()
|
||||
echo " · 网关分账金额来自 commission/regional reward 或 split_rule\n";
|
||||
echo " · 汇付:推广员/区域 huifu_id 收 div_amt,余款进 platform_huifu_id 或主商户 huifu_id\n";
|
||||
echo " · 业务佣金结算仍写 shopro_user_wallet_log(commission_income / regional_agent_income)\n";
|
||||
echo " · Config::shouldSkipWallet() 未接入 Reward,分账开启时仍可能同时入账钱包 → 用 anomalies 命令排查\n";
|
||||
echo " · 汇付/微信分账成功:佣金标记已结算且不入 user.money;分账失败则回退入钱包\n";
|
||||
|
||||
$since = time() - 90 * 86400;
|
||||
$stats = Db::name('shopro_split_order')->alias('so')
|
||||
|
||||
在新工单中引用
屏蔽一个用户