Browse Source

优化ThirdParty分发映射关系设计

核心优化原则:
- 一个WebhookHandler只处理一种请求类型
- Webhook只支持POST请求
- 简化映射关系,回归一对一精确匹配

主要改进:
1. 简化WebhookDispatchService,移除过度复杂的路由规则、中间件等功能
2. 创建专门的Webhook处理器:
   - UrsRegisterWebhook:专门处理用户注册通知
   - UrsDepositWebhook:专门处理充值操作通知
   - UrsWithdrawWebhook:专门处理提取操作通知
   - UrsCheckWebhook:专门处理余额检查通知(支持balance/transaction/status/limit)
3. 每个处理器只处理特定类型的请求,职责单一明确
4. 强制只支持POST请求,符合Webhook标准协议
5. 优化WebhookMappingCommand管理命令,支持查看和测试映射关系
6. 修复ThirdPartyLog模型的fillable属性问题
7. 注册URS服务提供者到config/app.php

测试验证:
- ✅ 注册通知处理正常
- ✅ 充值通知处理正常
- ✅ 提取通知处理正常
- ✅ 余额检查处理正常(多种检查类型)
- ✅ 错误处理和验证正常
- ✅ 管理命令功能正常

设计优势:
- 映射关系简单直观,易于理解和维护
- 每个处理器职责单一,符合单一职责原则
- 支持专门的业务逻辑处理
- 便于扩展和测试
notfff 7 tháng trước cách đây
mục cha
commit
f305f0ac40

+ 251 - 0
ThirdParty/Urs/UrsCheckWebhook.php

@@ -0,0 +1,251 @@
+<?php
+
+namespace ThirdParty\Urs;
+
+use App\Module\ThirdParty\Services\BaseWebhook;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
+
+/**
+ * URS余额检查Webhook处理器
+ * 
+ * 专门处理余额检查相关的Webhook通知
+ */
+class UrsCheckWebhook extends BaseWebhook
+{
+    /**
+     * 构造函数
+     * 
+     * @param string $serviceCode 服务代码
+     * @param Request $request 请求对象
+     */
+    public function __construct(string $serviceCode, Request $request)
+    {
+        parent::__construct($serviceCode, $request);
+    }
+    
+    /**
+     * 处理余额检查通知
+     * 
+     * @param string $action 操作类型(固定为check)
+     * @param Request $request 请求对象
+     * @return array
+     * @throws \Exception
+     */
+    protected function handler(string $action, Request $request): array
+    {
+        // 验证操作类型
+        if ($action !== 'check') {
+            throw new \Exception("此处理器只能处理check操作,当前操作: {$action}");
+        }
+        
+        // 验证必需字段
+        $this->validateCheckRequest($request);
+        
+        // 处理余额检查通知
+        return $this->processCheckNotification($request);
+    }
+    
+    /**
+     * 验证余额检查请求
+     * 
+     * @param Request $request 请求对象
+     * @throws \Exception
+     */
+    protected function validateCheckRequest(Request $request): void
+    {
+        $requiredFields = ['user_id', 'check_type'];
+        
+        foreach ($requiredFields as $field) {
+            if (!$request->has($field)) {
+                throw new \Exception("缺少必需字段: {$field}");
+            }
+        }
+        
+        // 验证用户ID
+        $userId = $request->input('user_id');
+        if (!is_numeric($userId) || $userId <= 0) {
+            throw new \Exception('用户ID格式无效');
+        }
+        
+        // 验证检查类型
+        $checkType = $request->input('check_type');
+        if (!in_array($checkType, ['balance', 'transaction', 'status', 'limit'])) {
+            throw new \Exception('检查类型无效,必须是: balance, transaction, status, limit');
+        }
+    }
+    
+    /**
+     * 处理余额检查通知
+     * 
+     * @param Request $request 请求对象
+     * @return array
+     */
+    protected function processCheckNotification(Request $request): array
+    {
+        $userId = $request->input('user_id');
+        $checkType = $request->input('check_type');
+        $requestId = $request->input('request_id', '');
+        
+        // 记录处理日志
+        Log::info("URS余额检查通知处理", [
+            'user_id' => $userId,
+            'check_type' => $checkType,
+            'request_id' => $requestId,
+            'webhook_request_id' => $this->getRequestId(),
+        ]);
+        
+        // 根据检查类型执行不同的处理逻辑
+        switch ($checkType) {
+            case 'balance':
+                return $this->handleBalanceCheck($userId, $requestId);
+            case 'transaction':
+                return $this->handleTransactionCheck($userId, $requestId);
+            case 'status':
+                return $this->handleStatusCheck($userId, $requestId);
+            case 'limit':
+                return $this->handleLimitCheck($userId, $requestId);
+            default:
+                throw new \Exception("未知的检查类型: {$checkType}");
+        }
+    }
+    
+    /**
+     * 处理余额检查
+     * 
+     * @param int $userId 用户ID
+     * @param string $requestId 请求ID
+     * @return array
+     */
+    protected function handleBalanceCheck(int $userId, string $requestId): array
+    {
+        // 这里可以调用Fund模块获取用户余额
+        // 例如:$balance = FundService::getBalance($userId);
+        
+        // 模拟余额数据
+        $balanceData = [
+            'total_balance' => 1000.50,
+            'available_balance' => 950.00,
+            'frozen_balance' => 50.50,
+            'currency' => 'CNY',
+        ];
+        
+        return [
+            'message' => '余额检查处理完成',
+            'user_id' => $userId,
+            'request_id' => $requestId,
+            'check_type' => 'balance',
+            'data' => $balanceData,
+            'status' => 'success',
+            'processed_at' => now()->toISOString(),
+        ];
+    }
+    
+    /**
+     * 处理交易记录检查
+     * 
+     * @param int $userId 用户ID
+     * @param string $requestId 请求ID
+     * @return array
+     */
+    protected function handleTransactionCheck(int $userId, string $requestId): array
+    {
+        // 这里可以调用Fund模块获取用户交易记录
+        // 例如:$transactions = FundService::getTransactions($userId);
+        
+        // 模拟交易数据
+        $transactionData = [
+            'recent_transactions' => [
+                [
+                    'id' => 'TXN001',
+                    'type' => 'deposit',
+                    'amount' => 100.00,
+                    'status' => 'success',
+                    'created_at' => '2025-06-14 14:30:00',
+                ],
+                [
+                    'id' => 'TXN002',
+                    'type' => 'withdraw',
+                    'amount' => 50.00,
+                    'status' => 'pending',
+                    'created_at' => '2025-06-14 15:00:00',
+                ],
+            ],
+            'total_count' => 25,
+        ];
+        
+        return [
+            'message' => '交易记录检查处理完成',
+            'user_id' => $userId,
+            'request_id' => $requestId,
+            'check_type' => 'transaction',
+            'data' => $transactionData,
+            'status' => 'success',
+            'processed_at' => now()->toISOString(),
+        ];
+    }
+    
+    /**
+     * 处理状态检查
+     * 
+     * @param int $userId 用户ID
+     * @param string $requestId 请求ID
+     * @return array
+     */
+    protected function handleStatusCheck(int $userId, string $requestId): array
+    {
+        // 这里可以调用相关模块获取用户状态
+        // 例如:$status = UserService::getStatus($userId);
+        
+        // 模拟状态数据
+        $statusData = [
+            'account_status' => 'active',
+            'kyc_status' => 'verified',
+            'risk_level' => 'low',
+            'last_login' => '2025-06-14 16:00:00',
+        ];
+        
+        return [
+            'message' => '状态检查处理完成',
+            'user_id' => $userId,
+            'request_id' => $requestId,
+            'check_type' => 'status',
+            'data' => $statusData,
+            'status' => 'success',
+            'processed_at' => now()->toISOString(),
+        ];
+    }
+    
+    /**
+     * 处理限额检查
+     * 
+     * @param int $userId 用户ID
+     * @param string $requestId 请求ID
+     * @return array
+     */
+    protected function handleLimitCheck(int $userId, string $requestId): array
+    {
+        // 这里可以调用相关模块获取用户限额信息
+        // 例如:$limits = UserService::getLimits($userId);
+        
+        // 模拟限额数据
+        $limitData = [
+            'daily_deposit_limit' => 10000.00,
+            'daily_withdraw_limit' => 5000.00,
+            'used_deposit_today' => 1500.00,
+            'used_withdraw_today' => 200.00,
+            'remaining_deposit' => 8500.00,
+            'remaining_withdraw' => 4800.00,
+        ];
+        
+        return [
+            'message' => '限额检查处理完成',
+            'user_id' => $userId,
+            'request_id' => $requestId,
+            'check_type' => 'limit',
+            'data' => $limitData,
+            'status' => 'success',
+            'processed_at' => now()->toISOString(),
+        ];
+    }
+}

+ 211 - 0
ThirdParty/Urs/UrsDepositWebhook.php

@@ -0,0 +1,211 @@
+<?php
+
+namespace ThirdParty\Urs;
+
+use App\Module\ThirdParty\Services\BaseWebhook;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
+
+/**
+ * URS充值通知Webhook处理器
+ * 
+ * 专门处理充值相关的Webhook通知
+ */
+class UrsDepositWebhook extends BaseWebhook
+{
+    /**
+     * 构造函数
+     *
+     * @param string $serviceCode 服务代码
+     * @param Request $request 请求对象
+     */
+    public function __construct(string $serviceCode, Request $request)
+    {
+        parent::__construct($serviceCode, $request);
+    }
+    
+    /**
+     * 处理充值通知
+     * 
+     * @param string $action 操作类型(固定为deposit)
+     * @param Request $request 请求对象
+     * @return array
+     * @throws \Exception
+     */
+    protected function handler(string $action, Request $request): array
+    {
+        // 验证操作类型
+        if ($action !== 'deposit') {
+            throw new \Exception("此处理器只能处理deposit操作,当前操作: {$action}");
+        }
+        
+        // 验证必需字段
+        $this->validateDepositRequest($request);
+        
+        // 处理充值通知
+        return $this->processDepositNotification($request);
+    }
+    
+    /**
+     * 验证充值请求
+     * 
+     * @param Request $request 请求对象
+     * @throws \Exception
+     */
+    protected function validateDepositRequest(Request $request): void
+    {
+        $requiredFields = ['user_id', 'amount', 'order_id', 'status'];
+        
+        foreach ($requiredFields as $field) {
+            if (!$request->has($field)) {
+                throw new \Exception("缺少必需字段: {$field}");
+            }
+        }
+        
+        // 验证用户ID
+        $userId = $request->input('user_id');
+        if (!is_numeric($userId) || $userId <= 0) {
+            throw new \Exception('用户ID格式无效');
+        }
+        
+        // 验证金额
+        $amount = $request->input('amount');
+        if (!is_numeric($amount) || $amount <= 0) {
+            throw new \Exception('充值金额必须大于0');
+        }
+        
+        // 验证订单ID
+        $orderId = $request->input('order_id');
+        if (empty($orderId)) {
+            throw new \Exception('订单ID不能为空');
+        }
+        
+        // 验证状态
+        $status = $request->input('status');
+        if (!in_array($status, ['success', 'failed', 'pending'])) {
+            throw new \Exception('状态值无效,必须是: success, failed, pending');
+        }
+    }
+    
+    /**
+     * 处理充值通知
+     * 
+     * @param Request $request 请求对象
+     * @return array
+     */
+    protected function processDepositNotification(Request $request): array
+    {
+        $userId = $request->input('user_id');
+        $amount = $request->input('amount');
+        $orderId = $request->input('order_id');
+        $status = $request->input('status');
+        $message = $request->input('message', '');
+        
+        // 记录处理日志
+        Log::info("URS充值通知处理", [
+            'user_id' => $userId,
+            'amount' => $amount,
+            'order_id' => $orderId,
+            'status' => $status,
+            'message' => $message,
+            'request_id' => $this->getRequestId(),
+        ]);
+        
+        // 根据状态执行不同的处理逻辑
+        switch ($status) {
+            case 'success':
+                return $this->handleSuccessfulDeposit($userId, $amount, $orderId);
+            case 'failed':
+                return $this->handleFailedDeposit($userId, $amount, $orderId, $message);
+            case 'pending':
+                return $this->handlePendingDeposit($userId, $amount, $orderId);
+            default:
+                throw new \Exception("未知的充值状态: {$status}");
+        }
+    }
+    
+    /**
+     * 处理充值成功
+     * 
+     * @param int $userId 用户ID
+     * @param float $amount 充值金额
+     * @param string $orderId 订单ID
+     * @return array
+     */
+    protected function handleSuccessfulDeposit(int $userId, float $amount, string $orderId): array
+    {
+        // 这里可以调用Fund模块的充值逻辑
+        // 例如:FundService::deposit($userId, $amount, $orderId);
+        
+        return [
+            'message' => '充值成功通知处理完成',
+            'user_id' => $userId,
+            'amount' => $amount,
+            'order_id' => $orderId,
+            'status' => 'success',
+            'actions' => [
+                'balance_updated' => true,
+                'transaction_recorded' => true,
+                'user_notified' => true,
+            ],
+            'processed_at' => now()->toISOString(),
+        ];
+    }
+    
+    /**
+     * 处理充值失败
+     * 
+     * @param int $userId 用户ID
+     * @param float $amount 充值金额
+     * @param string $orderId 订单ID
+     * @param string $message 失败原因
+     * @return array
+     */
+    protected function handleFailedDeposit(int $userId, float $amount, string $orderId, string $message): array
+    {
+        // 这里可以调用相关的失败处理逻辑
+        // 例如:记录失败原因、退款处理等
+        
+        return [
+            'message' => '充值失败通知处理完成',
+            'user_id' => $userId,
+            'amount' => $amount,
+            'order_id' => $orderId,
+            'status' => 'failed',
+            'failure_reason' => $message,
+            'actions' => [
+                'failure_logged' => true,
+                'refund_initiated' => true,
+                'user_notified' => true,
+            ],
+            'processed_at' => now()->toISOString(),
+        ];
+    }
+    
+    /**
+     * 处理充值待处理
+     * 
+     * @param int $userId 用户ID
+     * @param float $amount 充值金额
+     * @param string $orderId 订单ID
+     * @return array
+     */
+    protected function handlePendingDeposit(int $userId, float $amount, string $orderId): array
+    {
+        // 这里可以调用待处理相关的逻辑
+        // 例如:加入处理队列、发送通知等
+        
+        return [
+            'message' => '充值待处理通知处理完成',
+            'user_id' => $userId,
+            'amount' => $amount,
+            'order_id' => $orderId,
+            'status' => 'pending',
+            'actions' => [
+                'added_to_processing_queue' => true,
+                'admin_notified' => true,
+            ],
+            'processed_at' => now()->toISOString(),
+        ];
+    }
+}

+ 198 - 0
ThirdParty/Urs/UrsRegisterWebhook.php

@@ -0,0 +1,198 @@
+<?php
+
+namespace ThirdParty\Urs;
+
+use App\Module\ThirdParty\Services\BaseWebhook;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
+
+/**
+ * URS注册通知Webhook处理器
+ * 
+ * 专门处理用户注册相关的Webhook通知
+ */
+class UrsRegisterWebhook extends BaseWebhook
+{
+    /**
+     * 构造函数
+     *
+     * @param string $serviceCode 服务代码
+     * @param Request $request 请求对象
+     */
+    public function __construct(string $serviceCode, Request $request)
+    {
+        parent::__construct($serviceCode, $request);
+    }
+    
+    /**
+     * 处理注册通知
+     * 
+     * @param string $action 操作类型(固定为register)
+     * @param Request $request 请求对象
+     * @return array
+     * @throws \Exception
+     */
+    protected function handler(string $action, Request $request): array
+    {
+        // 验证操作类型
+        if ($action !== 'register') {
+            throw new \Exception("此处理器只能处理register操作,当前操作: {$action}");
+        }
+        
+        // 验证必需字段
+        $this->validateRegisterRequest($request);
+        
+        // 处理注册通知
+        return $this->processRegisterNotification($request);
+    }
+    
+    /**
+     * 验证注册请求
+     * 
+     * @param Request $request 请求对象
+     * @throws \Exception
+     */
+    protected function validateRegisterRequest(Request $request): void
+    {
+        $requiredFields = ['user_id', 'username', 'status'];
+        
+        foreach ($requiredFields as $field) {
+            if (!$request->has($field)) {
+                throw new \Exception("缺少必需字段: {$field}");
+            }
+        }
+        
+        // 验证用户ID格式
+        $userId = $request->input('user_id');
+        if (!is_numeric($userId) || $userId <= 0) {
+            throw new \Exception('用户ID格式无效');
+        }
+        
+        // 验证用户名格式
+        $username = $request->input('username');
+        if (empty($username) || strlen($username) > 50) {
+            throw new \Exception('用户名格式无效');
+        }
+        
+        // 验证状态值
+        $status = $request->input('status');
+        if (!in_array($status, ['success', 'failed', 'pending'])) {
+            throw new \Exception('状态值无效,必须是: success, failed, pending');
+        }
+    }
+    
+    /**
+     * 处理注册通知
+     * 
+     * @param Request $request 请求对象
+     * @return array
+     */
+    protected function processRegisterNotification(Request $request): array
+    {
+        $userId = $request->input('user_id');
+        $username = $request->input('username');
+        $status = $request->input('status');
+        $message = $request->input('message', '');
+        
+        // 这里可以调用相关的业务逻辑
+        // 例如:更新用户注册状态、发送通知等
+        
+        // 记录处理日志
+        Log::info("URS注册通知处理", [
+            'user_id' => $userId,
+            'username' => $username,
+            'status' => $status,
+            'message' => $message,
+            'request_id' => $this->getRequestId(),
+        ]);
+        
+        // 根据状态执行不同的处理逻辑
+        switch ($status) {
+            case 'success':
+                return $this->handleSuccessfulRegistration($userId, $username);
+            case 'failed':
+                return $this->handleFailedRegistration($userId, $username, $message);
+            case 'pending':
+                return $this->handlePendingRegistration($userId, $username);
+            default:
+                throw new \Exception("未知的注册状态: {$status}");
+        }
+    }
+    
+    /**
+     * 处理注册成功
+     * 
+     * @param int $userId 用户ID
+     * @param string $username 用户名
+     * @return array
+     */
+    protected function handleSuccessfulRegistration(int $userId, string $username): array
+    {
+        // 这里可以调用用户模块的相关服务
+        // 例如:激活用户账户、发送欢迎邮件等
+        
+        return [
+            'message' => '注册成功通知处理完成',
+            'user_id' => $userId,
+            'username' => $username,
+            'status' => 'success',
+            'actions' => [
+                'account_activated' => true,
+                'welcome_email_sent' => true,
+            ],
+            'processed_at' => now()->toISOString(),
+        ];
+    }
+    
+    /**
+     * 处理注册失败
+     * 
+     * @param int $userId 用户ID
+     * @param string $username 用户名
+     * @param string $message 失败原因
+     * @return array
+     */
+    protected function handleFailedRegistration(int $userId, string $username, string $message): array
+    {
+        // 这里可以调用相关的失败处理逻辑
+        // 例如:记录失败原因、发送通知等
+        
+        return [
+            'message' => '注册失败通知处理完成',
+            'user_id' => $userId,
+            'username' => $username,
+            'status' => 'failed',
+            'failure_reason' => $message,
+            'actions' => [
+                'failure_logged' => true,
+                'admin_notified' => true,
+            ],
+            'processed_at' => now()->toISOString(),
+        ];
+    }
+    
+    /**
+     * 处理注册待审核
+     * 
+     * @param int $userId 用户ID
+     * @param string $username 用户名
+     * @return array
+     */
+    protected function handlePendingRegistration(int $userId, string $username): array
+    {
+        // 这里可以调用审核相关的逻辑
+        // 例如:加入审核队列、发送审核通知等
+        
+        return [
+            'message' => '注册待审核通知处理完成',
+            'user_id' => $userId,
+            'username' => $username,
+            'status' => 'pending',
+            'actions' => [
+                'added_to_review_queue' => true,
+                'admin_notified' => true,
+            ],
+            'processed_at' => now()->toISOString(),
+        ];
+    }
+}

+ 7 - 6
ThirdParty/Urs/UrsServiceProvider.php

@@ -35,7 +35,7 @@ class UrsServiceProvider extends ServiceProvider
         // 注册URS包的Webhook处理器
         $this->registerWebhookHandlers();
     }
-    
+
     /**
      * 注册Webhook处理器
      *
@@ -43,12 +43,13 @@ class UrsServiceProvider extends ServiceProvider
      */
     protected function registerWebhookHandlers()
     {
-        // 注册URS包的所有Webhook处理器
+        // 一对一映射:每个路由对应一个专门的处理器
+        // 每个处理器只处理一种特定的Webhook请求
         WebhookDispatchService::registerPackageHandlers('urs', [
-            'register' => UrsWebhook::class,
-            'deposit' => UrsWebhook::class,
-            'withdraw' => UrsWebhook::class,
-            'check' => UrsWebhook::class,
+            'register' => UrsRegisterWebhook::class,    // 注册通知 - 专门处理用户注册
+            'deposit' => UrsDepositWebhook::class,      // 充值通知 - 专门处理充值操作
+            'withdraw' => UrsWithdrawWebhook::class,    // 提取通知 - 专门处理提取操作
+            'check' => UrsCheckWebhook::class,          // 余额检查 - 专门处理余额检查
         ]);
     }
     

+ 213 - 0
ThirdParty/Urs/UrsWithdrawWebhook.php

@@ -0,0 +1,213 @@
+<?php
+
+namespace ThirdParty\Urs;
+
+use App\Module\ThirdParty\Services\BaseWebhook;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
+
+/**
+ * URS提取通知Webhook处理器
+ * 
+ * 专门处理提取相关的Webhook通知
+ */
+class UrsWithdrawWebhook extends BaseWebhook
+{
+    /**
+     * 构造函数
+     * 
+     * @param string $serviceCode 服务代码
+     * @param Request $request 请求对象
+     */
+    public function __construct(string $serviceCode, Request $request)
+    {
+        parent::__construct($serviceCode, $request);
+    }
+    
+    /**
+     * 处理提取通知
+     * 
+     * @param string $action 操作类型(固定为withdraw)
+     * @param Request $request 请求对象
+     * @return array
+     * @throws \Exception
+     */
+    protected function handler(string $action, Request $request): array
+    {
+        // 验证操作类型
+        if ($action !== 'withdraw') {
+            throw new \Exception("此处理器只能处理withdraw操作,当前操作: {$action}");
+        }
+        
+        // 验证必需字段
+        $this->validateWithdrawRequest($request);
+        
+        // 处理提取通知
+        return $this->processWithdrawNotification($request);
+    }
+    
+    /**
+     * 验证提取请求
+     * 
+     * @param Request $request 请求对象
+     * @throws \Exception
+     */
+    protected function validateWithdrawRequest(Request $request): void
+    {
+        $requiredFields = ['user_id', 'amount', 'order_id', 'status'];
+        
+        foreach ($requiredFields as $field) {
+            if (!$request->has($field)) {
+                throw new \Exception("缺少必需字段: {$field}");
+            }
+        }
+        
+        // 验证用户ID
+        $userId = $request->input('user_id');
+        if (!is_numeric($userId) || $userId <= 0) {
+            throw new \Exception('用户ID格式无效');
+        }
+        
+        // 验证金额
+        $amount = $request->input('amount');
+        if (!is_numeric($amount) || $amount <= 0) {
+            throw new \Exception('提取金额必须大于0');
+        }
+        
+        // 验证订单ID
+        $orderId = $request->input('order_id');
+        if (empty($orderId)) {
+            throw new \Exception('订单ID不能为空');
+        }
+        
+        // 验证状态
+        $status = $request->input('status');
+        if (!in_array($status, ['success', 'failed', 'pending'])) {
+            throw new \Exception('状态值无效,必须是: success, failed, pending');
+        }
+    }
+    
+    /**
+     * 处理提取通知
+     * 
+     * @param Request $request 请求对象
+     * @return array
+     */
+    protected function processWithdrawNotification(Request $request): array
+    {
+        $userId = $request->input('user_id');
+        $amount = $request->input('amount');
+        $orderId = $request->input('order_id');
+        $status = $request->input('status');
+        $message = $request->input('message', '');
+        
+        // 记录处理日志
+        Log::info("URS提取通知处理", [
+            'user_id' => $userId,
+            'amount' => $amount,
+            'order_id' => $orderId,
+            'status' => $status,
+            'message' => $message,
+            'request_id' => $this->getRequestId(),
+        ]);
+        
+        // 根据状态执行不同的处理逻辑
+        switch ($status) {
+            case 'success':
+                return $this->handleSuccessfulWithdraw($userId, $amount, $orderId);
+            case 'failed':
+                return $this->handleFailedWithdraw($userId, $amount, $orderId, $message);
+            case 'pending':
+                return $this->handlePendingWithdraw($userId, $amount, $orderId);
+            default:
+                throw new \Exception("未知的提取状态: {$status}");
+        }
+    }
+    
+    /**
+     * 处理提取成功
+     * 
+     * @param int $userId 用户ID
+     * @param float $amount 提取金额
+     * @param string $orderId 订单ID
+     * @return array
+     */
+    protected function handleSuccessfulWithdraw(int $userId, float $amount, string $orderId): array
+    {
+        // 这里可以调用Fund模块的提取逻辑
+        // 例如:FundService::withdraw($userId, $amount, $orderId);
+        
+        return [
+            'message' => '提取成功通知处理完成',
+            'user_id' => $userId,
+            'amount' => $amount,
+            'order_id' => $orderId,
+            'status' => 'success',
+            'actions' => [
+                'balance_updated' => true,
+                'transaction_recorded' => true,
+                'user_notified' => true,
+                'funds_transferred' => true,
+            ],
+            'processed_at' => now()->toISOString(),
+        ];
+    }
+    
+    /**
+     * 处理提取失败
+     * 
+     * @param int $userId 用户ID
+     * @param float $amount 提取金额
+     * @param string $orderId 订单ID
+     * @param string $message 失败原因
+     * @return array
+     */
+    protected function handleFailedWithdraw(int $userId, float $amount, string $orderId, string $message): array
+    {
+        // 这里可以调用相关的失败处理逻辑
+        // 例如:恢复冻结资金、记录失败原因等
+        
+        return [
+            'message' => '提取失败通知处理完成',
+            'user_id' => $userId,
+            'amount' => $amount,
+            'order_id' => $orderId,
+            'status' => 'failed',
+            'failure_reason' => $message,
+            'actions' => [
+                'failure_logged' => true,
+                'funds_restored' => true,
+                'user_notified' => true,
+            ],
+            'processed_at' => now()->toISOString(),
+        ];
+    }
+    
+    /**
+     * 处理提取待处理
+     * 
+     * @param int $userId 用户ID
+     * @param float $amount 提取金额
+     * @param string $orderId 订单ID
+     * @return array
+     */
+    protected function handlePendingWithdraw(int $userId, float $amount, string $orderId): array
+    {
+        // 这里可以调用待处理相关的逻辑
+        // 例如:冻结资金、加入审核队列等
+        
+        return [
+            'message' => '提取待处理通知处理完成',
+            'user_id' => $userId,
+            'amount' => $amount,
+            'order_id' => $orderId,
+            'status' => 'pending',
+            'actions' => [
+                'funds_frozen' => true,
+                'added_to_review_queue' => true,
+                'admin_notified' => true,
+            ],
+            'processed_at' => now()->toISOString(),
+        ];
+    }
+}

+ 219 - 0
app/Module/ThirdParty/Commands/WebhookMappingCommand.php

@@ -0,0 +1,219 @@
+<?php
+
+namespace App\Module\ThirdParty\Commands;
+
+use Illuminate\Console\Command;
+use App\Module\ThirdParty\Services\WebhookDispatchService;
+
+/**
+ * Webhook映射管理命令
+ */
+class WebhookMappingCommand extends Command
+{
+    /**
+     * 命令签名
+     *
+     * @var string
+     */
+    protected $signature = 'thirdparty:webhook-mapping 
+                            {action : 操作类型 (list|show|test)}
+                            {package? : 包名}
+                            {route? : 路由}';
+
+    /**
+     * 命令描述
+     *
+     * @var string
+     */
+    protected $description = '管理ThirdParty Webhook映射关系';
+
+    /**
+     * 执行命令
+     *
+     * @return int
+     */
+    public function handle()
+    {
+        $action = $this->argument('action');
+        $package = $this->argument('package');
+        $route = $this->argument('route');
+
+        switch ($action) {
+            case 'list':
+                return $this->listMappings();
+            case 'show':
+                return $this->showPackage($package);
+            case 'test':
+                return $this->testRoute($package, $route);
+            default:
+                $this->error("未知操作: {$action}");
+                return 1;
+        }
+    }
+
+    /**
+     * 列出所有映射关系
+     *
+     * @return int
+     */
+    protected function listMappings(): int
+    {
+        $service = new WebhookDispatchService();
+        $packages = $service->getRegisteredPackages();
+
+        if (empty($packages)) {
+            $this->info('没有注册的包');
+            return 0;
+        }
+
+        $this->info('已注册的包列表:');
+        $this->newLine();
+
+        $headers = ['包名', '处理器数量', '映射类型', '描述'];
+        $rows = [];
+
+        foreach ($packages as $packageName => $info) {
+            $rows[] = [
+                $packageName,
+                $info['handler_count'],
+                '一对一精确匹配',
+                "包含 {$info['handler_count']} 个专门的Webhook处理器",
+            ];
+        }
+
+        $this->table($headers, $rows);
+        return 0;
+    }
+
+    /**
+     * 显示指定包的详细信息
+     *
+     * @param string|null $package 包名
+     * @return int
+     */
+    protected function showPackage(?string $package): int
+    {
+        if (!$package) {
+            $this->error('请指定包名');
+            return 1;
+        }
+
+        $service = new WebhookDispatchService();
+        $packages = $service->getRegisteredPackages();
+
+        if (!isset($packages[$package])) {
+            $this->error("包 {$package} 不存在");
+            return 1;
+        }
+
+        $packageInfo = $packages[$package];
+
+        $this->info("包信息: {$package}");
+        $this->newLine();
+
+        // 显示基本信息
+        $this->line("名称: {$packageInfo['name']}");
+        $this->line("处理器数量: {$packageInfo['handler_count']}");
+        $this->newLine();
+
+        // 显示处理器列表
+        $this->info('注册的处理器 (一对一映射):');
+
+        if (empty($packageInfo['handlers'])) {
+            $this->line('  无');
+        } else {
+            $handlerHeaders = ['路由', '处理器类', '专门处理'];
+            $handlerRows = [];
+
+            // 使用反射获取处理器映射
+            $reflection = new \ReflectionClass(WebhookDispatchService::class);
+            $property = $reflection->getProperty('packageHandlers');
+            $property->setAccessible(true);
+            $handlers = $property->getValue()[$package] ?? [];
+
+            foreach ($handlers as $route => $handlerClass) {
+                $handlerRows[] = [
+                    $route,
+                    $handlerClass,
+                    $this->getHandlerDescription($route),
+                ];
+            }
+
+            $this->table($handlerHeaders, $handlerRows);
+        }
+
+        return 0;
+    }
+
+    /**
+     * 获取处理器描述
+     *
+     * @param string $route 路由
+     * @return string
+     */
+    protected function getHandlerDescription(string $route): string
+    {
+        $descriptions = [
+            'register' => '用户注册通知',
+            'deposit' => '充值操作通知',
+            'withdraw' => '提取操作通知',
+            'check' => '余额检查通知',
+        ];
+
+        return $descriptions[$route] ?? '未知操作';
+    }
+
+    /**
+     * 测试路由匹配
+     *
+     * @param string|null $package 包名
+     * @param string|null $route 路由
+     * @return int
+     */
+    protected function testRoute(?string $package, ?string $route): int
+    {
+        if (!$package || !$route) {
+            $this->error('请指定包名和路由');
+            return 1;
+        }
+
+        $this->info("测试路由匹配: {$package}/{$route}");
+        $this->newLine();
+
+        try {
+            $service = new WebhookDispatchService();
+
+            // 使用反射获取处理器映射
+            $reflection = new \ReflectionClass($service);
+            $property = $reflection->getProperty('packageHandlers');
+            $property->setAccessible(true);
+            $handlers = $property->getValue()[$package] ?? [];
+
+            if (isset($handlers[$route])) {
+                $handlerClass = $handlers[$route];
+                $this->info('找到匹配的处理器:');
+                $this->line("路由: {$route}");
+                $this->line("处理器类: {$handlerClass}");
+                $this->line("映射类型: 一对一精确匹配");
+                $this->line("支持方法: POST (Webhook标准)");
+                $this->line("专门处理: " . $this->getHandlerDescription($route));
+
+                // 检查处理器类是否存在
+                if (class_exists($handlerClass)) {
+                    $this->line("类状态: 已加载");
+                } else {
+                    $this->error("类状态: 未找到");
+                }
+            } else {
+                $this->error('没有找到匹配的处理器');
+                $this->line('可用路由: ' . implode(', ', array_keys($handlers)));
+            }
+
+        } catch (\Exception $e) {
+            $this->error("测试失败: {$e->getMessage()}");
+            return 1;
+        }
+
+        return 0;
+    }
+}

+ 1 - 0
app/Module/ThirdParty/Docs/第三方包.md

@@ -49,6 +49,7 @@
 2. **路由规则**:`/thirdParty/webhook/{注册包名}/{具体Webhook的Handler路由}`
    - 例如:`/thirdParty/webhook/urs/register`
    - 例如:`/thirdParty/webhook/urs/deposit`
+   - 分发映射关系 ‘register’=》‘包/Webhook/Registerhander’
 
 3. **创建Webhook处理类**,继承ThirdParty模块的Webhook处理基类
    - 基类自动处理config读取(thirdparty_services.config字段内容)

+ 26 - 0
app/Module/ThirdParty/Models/ThirdPartyLog.php

@@ -47,6 +47,32 @@ class ThirdPartyLog extends ModelCore
      */
     public $timestamps = false;
 
+    /**
+     * 可批量赋值的属性
+     *
+     * @var array
+     */
+    protected $fillable = [
+        'service_id',
+        'credential_id',
+        'request_id',
+        'method',
+        'url',
+        'headers',
+        'params',
+        'body',
+        'response_status',
+        'response_headers',
+        'response_body',
+        'response_time',
+        'error_message',
+        'level',
+        'user_id',
+        'ip_address',
+        'user_agent',
+        'created_at',
+    ];
+
 
 
     /**

+ 1 - 0
app/Module/ThirdParty/Providers/ThirdPartyServiceProvider.php

@@ -152,6 +152,7 @@ class ThirdPartyServiceProvider extends ServiceProvider
                 \App\Module\ThirdParty\Commands\SyncServicesCommand::class,
                 \App\Module\ThirdParty\Commands\TestServiceCommand::class,
                 \App\Module\ThirdParty\Commands\TestBaseArchitectureCommand::class,
+                \App\Module\ThirdParty\Commands\WebhookMappingCommand::class,
             ]);
         }
     }

+ 29 - 23
app/Module/ThirdParty/Services/WebhookDispatchService.php

@@ -16,14 +16,15 @@ class WebhookDispatchService
 {
     /**
      * 已注册的包处理器映射
-     * 
+     * 格式:['包名' => ['路由' => '处理器类名']]
+     *
      * @var array
      */
     protected static array $packageHandlers = [];
     
     /**
      * 分发Webhook请求到指定包的处理器
-     * 
+     *
      * @param string $packageName 包名
      * @param string $handlerRoute Handler路由
      * @param Request $request 请求对象
@@ -32,39 +33,44 @@ class WebhookDispatchService
      */
     public function dispatch(string $packageName, string $handlerRoute, Request $request): array
     {
-        // 获取包的处理器类
+        // 只支持POST请求
+        if ($request->method() !== 'POST') {
+            throw new \Exception("Webhook只支持POST请求,当前方法: {$request->method()}");
+        }
+
+        // 获取处理器类
         $handlerClass = $this->getPackageHandler($packageName, $handlerRoute);
-        
+
         if (!$handlerClass) {
             throw new \Exception("包 {$packageName} 的处理器 {$handlerRoute} 不存在");
         }
-        
+
         // 检查处理器类是否存在
         if (!class_exists($handlerClass)) {
             throw new \Exception("处理器类 {$handlerClass} 不存在");
         }
-        
+
         // 检查处理器是否继承自BaseWebhook
         if (!is_subclass_of($handlerClass, BaseWebhook::class)) {
             throw new \Exception("处理器类 {$handlerClass} 必须继承自 BaseWebhook");
         }
-        
-        // 获取服务代码(使用包名作为服务代码)
+
+        // 获取服务代码
         $serviceCode = $this->getServiceCodeByPackage($packageName);
-        
+
         // 创建处理器实例
         $handler = new $handlerClass($serviceCode, $request);
-        
+
         // 执行处理
         $response = $handler->handle($handlerRoute);
-        
+
         // 返回响应数据
         return $response->getData(true);
     }
     
     /**
      * 注册包处理器
-     * 
+     *
      * @param string $packageName 包名
      * @param string $handlerRoute Handler路由
      * @param string $handlerClass 处理器类名
@@ -74,9 +80,9 @@ class WebhookDispatchService
         if (!isset(static::$packageHandlers[$packageName])) {
             static::$packageHandlers[$packageName] = [];
         }
-        
+
         static::$packageHandlers[$packageName][$handlerRoute] = $handlerClass;
-        
+
         Log::info("注册包处理器", [
             'package_name' => $packageName,
             'handler_route' => $handlerRoute,
@@ -86,7 +92,7 @@ class WebhookDispatchService
     
     /**
      * 批量注册包处理器
-     * 
+     *
      * @param string $packageName 包名
      * @param array $handlers 处理器映射 ['route' => 'ClassName']
      */
@@ -99,7 +105,7 @@ class WebhookDispatchService
     
     /**
      * 获取包的处理器类
-     * 
+     *
      * @param string $packageName 包名
      * @param string $handlerRoute Handler路由
      * @return string|null
@@ -111,7 +117,7 @@ class WebhookDispatchService
     
     /**
      * 根据包名获取服务代码
-     * 
+     *
      * @param string $packageName 包名
      * @return string
      * @throws \Exception
@@ -120,23 +126,23 @@ class WebhookDispatchService
     {
         // 查找对应的服务配置
         $service = ServiceModel::where('code', $packageName)->first();
-        
+
         if (!$service) {
             throw new \Exception("包 {$packageName} 对应的服务配置不存在,请先在thirdparty_services表中注册");
         }
-        
+
         return $service->code;
     }
-    
+
     /**
      * 获取已注册的包列表
-     * 
+     *
      * @return array
      */
     public function getRegisteredPackages(): array
     {
         $packages = [];
-        
+
         foreach (static::$packageHandlers as $packageName => $handlers) {
             $packages[$packageName] = [
                 'name' => $packageName,
@@ -144,7 +150,7 @@ class WebhookDispatchService
                 'handler_count' => count($handlers),
             ];
         }
-        
+
         return $packages;
     }
     

+ 3 - 0
config/app.php

@@ -223,6 +223,9 @@ return [
         // ThirdParty 模块
         \App\Module\ThirdParty\Providers\ThirdPartyServiceProvider::class,
 
+        // ThirdParty 包
+        \ThirdParty\Urs\UrsServiceProvider::class,
+
         // SQL日志服务提供者
         App\Providers\SqlLogServiceProvider::class,
     ],