feat(commission): 添加分账成功后佣金处理功能 添加了新的方法来处理分账成功后的佣金结算: - 新增 runCommissionRewardByOrderWithoutWallet 方法用于分账成功时标记已结算 - 新增 runCommissionRewardWithoutWallet 方法处理不入余额的佣金奖励 - 避免在分账成功时重复将佣金计入用户余额 feat(regional_agent): 添加区域代理分账处理逻辑 - 新增 settleByRegionalOrderWithoutWallet 方法处理区域代理分账 - 新增 settleRewardWithoutWallet 方法处理不入钱包的奖励结算 - 完善区域代理佣金处理流程 refactor(split): 优化分账执行器逻辑 - 修改 SplitExecutor 类以支持延迟钱包结算 - 添加异常处理和事务管理 - 支持根据支付网关类型决定是否延迟钱包结算 feat(split): 实现分账完成后钱包结算机制 - 添加 SplitWalletSettlement 类来管理分账与钱包结算的协调 - 支持在分账成功后延迟钱包入账,失败时回退到钱包 - 修复汇付分账与佣金结算的时间冲突问题 refactor(hook): 调整分账钩子事件处理 - 修改 SplitHook 类的事件参数传递 - 更新各个订单状态变更事件的分账触发逻辑 - 确保分账执行时能正确获取事件类型 docs(tests): 更新分账佣金验证说明 - 更新测试文件中的注释说明 - 明确汇付/微信分账成功后的佣金处理方式 ```
138 行
4.9 KiB
PHP
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);
|
|
}
|
|
}
|
|
}
|
|
}
|