文件
xionggeshop/addons/shopro/library/split/SplitWalletSettlement.php
可乐加冰 73d65c3f0c ```
feat(commission): 添加分账成功后佣金处理功能

添加了新的方法来处理分账成功后的佣金结算:
- 新增 runCommissionRewardByOrderWithoutWallet 方法用于分账成功时标记已结算
- 新增 runCommissionRewardWithoutWallet 方法处理不入余额的佣金奖励
- 避免在分账成功时重复将佣金计入用户余额

feat(regional_agent): 添加区域代理分账处理逻辑

- 新增 settleByRegionalOrderWithoutWallet 方法处理区域代理分账
- 新增 settleRewardWithoutWallet 方法处理不入钱包的奖励结算
- 完善区域代理佣金处理流程

refactor(split): 优化分账执行器逻辑

- 修改 SplitExecutor 类以支持延迟钱包结算
- 添加异常处理和事务管理
- 支持根据支付网关类型决定是否延迟钱包结算

feat(split): 实现分账完成后钱包结算机制

- 添加 SplitWalletSettlement 类来管理分账与钱包结算的协调
- 支持在分账成功后延迟钱包入账,失败时回退到钱包
- 修复汇付分账与佣金结算的时间冲突问题

refactor(hook): 调整分账钩子事件处理

- 修改 SplitHook 类的事件参数传递
- 更新各个订单状态变更事件的分账触发逻辑
- 确保分账执行时能正确获取事件类型

docs(tests): 更新分账佣金验证说明

- 更新测试文件中的注释说明
- 明确汇付/微信分账成功后的佣金处理方式
```
2026-09-29 12:37:53 +08:00

138 行
4.9 KiB
PHP

<?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);
}
}
}
}