urs对接ThirdParty文档.md 23 KB

URS对接ThirdParty模块方案

概述

本文档描述如何将现有的URS(用户推广系统)功能对接到 ThirdParty 模块中,实现统一的第三方服务管理。URS系统提供用户信息查询、推广关系管理和资金操作等功能,通过ThirdParty模块可以实现更好的服务管理、监控和安全控制。

当前URS系统分析

核心功能

  1. API接口

    • 获取用户信息(用户ID、昵称)
    • 获取用户上级关系链表(各个等级的用户ID)
    • 获取下级人数统计(直推/团队3代)
  2. Webhook机制

    • 注册通知:传入uid和三级上级
    • 出包操作:用户ID、USDT数量、交易ID
    • 入包操作:用户ID、USDT数量、交易ID
    • 入包检查:用户ID、USDT数量验证
  3. 核心流程

    • URS应用访问农场客户端携带ukey
    • 农场使用ukey获取urs_uid
    • 创建农场用户并建立关联
    • 同步推广关系到UrsPromotion模块
    • 通过webhook进行钻石充值和提取

技术特点

  • 加密通信:使用AES-256-CBC加密算法
  • 签名验证:SHA256签名确保数据完整性
  • 时间戳验证:5分钟有效期防止重放攻击
  • 专属资金账户:使用专属用户ID进行资金操作

对接方案设计

1. 服务类型定义

在ThirdParty模块中,URS属于第三方平台类服务,具体分类为:

  • 服务类型:SOCIAL(社交平台)
  • 认证类型:SIGNATURE(签名认证)
  • 主要功能:用户关系管理、资金操作

2. 服务配置结构

2.1 第三方服务配置(kku_thirdparty_services表)

[
    'name' => 'URS用户推广系统',
    'code' => 'URS_PROMOTION',
    'provider' => 'URS',
    'service_type' => 'SOCIAL',
    'version' => 'v1',
    'base_url' => 'https://urs.example.com/api',
    'auth_type' => 'SIGNATURE',
    'status' => 'ACTIVE',
    'description' => 'URS用户推广关系管理和资金操作系统',
    'timeout' => 30,
    'retry_times' => 3,
    'retry_delay' => 1000,
    'health_check_url' => '/health',
    'health_check_interval' => 300,
    'webhook_url' => '/webhook/urs',
    'webhook_secret' => 'urs_webhook_secret_key',
    'priority' => 10,
    'config' => [
        'diamond_ratio' => 300,  // 1 USDT = 300 钻石
        'fund_user_id' => 15,    // 仓库账户用户ID
        'control_user_id' => 16, // 调控账户用户ID
        'currency_type' => 'DIAMOND', // 币种类型
        'precision' => 10,       // 小数精度
    ],
    'default_params' => [
        'format' => 'json',
        'version' => '1.0',
    ],
    'default_headers' => [
        'Content-Type' => 'application/json',
        'Accept' => 'application/json',
        'User-Agent' => 'KKU-Farm/1.0',
    ],
]

2.2 认证凭证配置(kku_thirdparty_credentials表)

[
    'service_id' => 1, // 对应URS服务ID
    'environment' => 'production',
    'auth_type' => 'SIGNATURE',
    'credentials' => [
        'app_key' => 'Hy0LmLKJSbDQY2oaaZOZKR1XKpFHSY8Y', // API通讯Key
        'timeout' => 300, // 签名有效期(秒)
        'algorithm' => 'AES-256-CBC', // 加密算法
        'hash_algorithm' => 'sha256', // 签名算法
    ],
    'is_active' => true,
    'expires_at' => null, // 永不过期
]

3. API接口映射

3.1 用户信息查询接口

原始接口POST /api/ecology/{ecology_id}/userInfo ThirdParty调用

ThirdPartyService::callApi('URS_PROMOTION', 'userInfo', [
    'userKey' => $userKey
], 'POST');

3.2 用户团队关系接口

原始接口POST /api/ecology/{ecology_id}/userTeam ThirdParty调用

ThirdPartyService::callApi('URS_PROMOTION', 'userTeam', [
    'userId' => $userId
], 'POST');

3.3 用户下级统计接口

原始接口POST /api/ecology/{ecology_id}/userLevelCount ThirdParty调用

ThirdPartyService::callApi('URS_PROMOTION', 'userLevelCount', [
    'userId' => $userId,
    'level' => $level // 1或3
], 'POST');

4. Webhook处理机制

4.1 Webhook路由配置

在ThirdParty模块中添加URS专用的Webhook处理路由:

// app/Module/ThirdParty/Routes/webhook.php
Route::post('/webhook/urs/{action}', [UrsWebhookController::class, 'handle'])
    ->name('urs.webhook')
    ->middleware(['throttle:60,1']);

4.2 Webhook处理器

创建专门的URS Webhook处理器:

// app/Module/ThirdParty/Controllers/UrsWebhookController.php
class UrsWebhookController extends Controller
{
    public function handle(Request $request, string $action)
    {
        // 验证签名
        $this->validateSignature($request);

        // 根据action分发处理
        switch ($action) {
            case 'register':
                return $this->handleRegister($request);
            case 'deposit':
                return $this->handleDeposit($request);
            case 'withdraw':
                return $this->handleWithdraw($request);
            case 'check':
                return $this->handleCheck($request);
            default:
                throw new BadRequestException('不支持的操作类型');
        }
    }
}

5. 加密服务集成

5.1 加密服务适配

将现有的URS CryptoService集成到ThirdParty模块:

// app/Module/ThirdParty/Services/Crypto/UrsCryptoService.php
class UrsCryptoService extends BaseCryptoService
{
    public function encrypt(array $data): array
    {
        // 使用URS的加密逻辑
        $iv = random_bytes(16);
        $timestamp = time();
        $json = json_encode($data, JSON_UNESCAPED_UNICODE);

        $encrypted = openssl_encrypt(
            $json,
            'AES-256-CBC',
            $this->key,
            OPENSSL_RAW_DATA,
            $iv
        );

        if ($encrypted === false) {
            throw new CryptoException('加密失败: ' . openssl_error_string());
        }

        $dataBase64 = base64_encode($encrypted);
        $ivBase64 = base64_encode($iv);

        return [
            'data' => $dataBase64,
            'iv' => $ivBase64,
            'timestamp' => $timestamp,
            'sign' => hash('sha256', $dataBase64 . $ivBase64 . $timestamp . $this->key)
        ];
    }

    public function decrypt(array $encryptedData): array
    {
        // 验证时间戳
        if (abs(time() - $encryptedData['timestamp']) > $this->timeout) {
            throw new CryptoException('请求已过期');
        }

        // 验证签名
        $sign = hash('sha256',
            $encryptedData['data'] .
            $encryptedData['iv'] .
            $encryptedData['timestamp'] .
            $this->key
        );

        if (!hash_equals($sign, $encryptedData['sign'])) {
            throw new CryptoException('签名验证失败');
        }

        // 解密数据
        $decrypted = openssl_decrypt(
            base64_decode($encryptedData['data']),
            'AES-256-CBC',
            $this->key,
            OPENSSL_RAW_DATA,
            base64_decode($encryptedData['iv'])
        );

        if ($decrypted === false) {
            throw new CryptoException('解密失败: ' . openssl_error_string());
        }

        $data = json_decode($decrypted, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new CryptoException('JSON解析失败: ' . json_last_error_msg());
        }

        return $data;
    }
}

5.2 认证头生成

在ThirdParty的认证系统中集成URS签名认证:

// app/Module/ThirdParty/Services/Auth/UrsAuthService.php
class UrsAuthService extends BaseAuthService
{
    public function generateAuthHeaders(array $data = []): array
    {
        $cryptoService = new UrsCryptoService($this->credential->getAppKey());
        $encryptedData = $cryptoService->encrypt($data);

        return [
            'X-Encrypted-Data' => json_encode($encryptedData),
            'X-Timestamp' => $encryptedData['timestamp'],
            'X-Signature' => $encryptedData['sign'],
        ];
    }
}

6. 业务逻辑层设计

6.1 URS服务类

创建专门的URS服务类,封装所有URS相关操作:

// app/Module/ThirdParty/Services/UrsService.php
class UrsService
{
    /**
     * 获取用户信息
     */
    public static function getUserInfo(string $userKey): array
    {
        return ThirdPartyService::callApi('URS_PROMOTION', 'userInfo', [
            'userKey' => $userKey
        ]);
    }

    /**
     * 获取用户团队关系
     */
    public static function getUserTeam(int $userId): array
    {
        return ThirdPartyService::callApi('URS_PROMOTION', 'userTeam', [
            'userId' => $userId
        ]);
    }

    /**
     * 获取用户下级统计
     */
    public static function getUserLevelCount(int $userId, int $level): array
    {
        if (!in_array($level, [1, 3])) {
            throw new InvalidArgumentException('level只能是1或3');
        }

        return ThirdPartyService::callApi('URS_PROMOTION', 'userLevelCount', [
            'userId' => $userId,
            'level' => $level
        ]);
    }

    /**
     * 处理注册通知
     */
    public static function handleRegisterNotification(int $uid, array $superiors): bool
    {
        // 记录日志
        ThirdPartyLog::create([
            'service_id' => static::getServiceId(),
            'request_type' => 'webhook',
            'endpoint' => 'register',
            'request_data' => compact('uid', 'superiors'),
            'status' => 'success',
        ]);

        return true;
    }

    /**
     * 处理出包操作
     */
    public static function handleWithdraw(int $userId, float $usdtAmount, string $transactionId): array
    {
        try {
            // 防止重复处理
            if (static::isTransactionProcessed($transactionId)) {
                throw new DuplicateTransactionException('交易已处理');
            }

            // 计算钻石数量
            $diamondAmount = $usdtAmount * config('thirdparty.services.urs.diamond_ratio', 300);

            // 调用Fund模块进行资金操作
            $result = FundService::transfer(
                $userId,                    // 从用户账户
                config('thirdparty.services.urs.fund_user_id', 15), // 转到专属账户
                'DIAMOND',                  // 币种
                $diamondAmount,             // 数量
                'URS出包操作',              // 备注
                $transactionId              // 交易ID
            );

            // 记录成功日志
            static::logTransaction('withdraw', $userId, $usdtAmount, $transactionId, 'success', $result);

            return ['success' => true, 'data' => $result];

        } catch (Exception $e) {
            // 记录失败日志
            static::logTransaction('withdraw', $userId, $usdtAmount, $transactionId, 'failed', $e->getMessage());

            return ['success' => false, 'error' => $e->getMessage()];
        }
    }

    /**
     * 处理入包操作
     */
    public static function handleDeposit(int $userId, float $usdtAmount, string $transactionId): array
    {
        try {
            // 防止重复处理
            if (static::isTransactionProcessed($transactionId)) {
                throw new DuplicateTransactionException('交易已处理');
            }

            // 计算钻石数量
            $diamondAmount = $usdtAmount * config('thirdparty.services.urs.diamond_ratio', 300);

            // 调用Fund模块进行资金操作
            $result = FundService::transfer(
                config('thirdparty.services.urs.fund_user_id', 15), // 从专属账户
                $userId,                    // 转到用户账户
                'DIAMOND',                  // 币种
                $diamondAmount,             // 数量
                'URS入包操作',              // 备注
                $transactionId              // 交易ID
            );

            // 记录成功日志
            static::logTransaction('deposit', $userId, $usdtAmount, $transactionId, 'success', $result);

            return ['success' => true, 'data' => $result];

        } catch (Exception $e) {
            // 记录失败日志
            static::logTransaction('deposit', $userId, $usdtAmount, $transactionId, 'failed', $e->getMessage());

            return ['success' => false, 'error' => $e->getMessage()];
        }
    }

    /**
     * 处理入包检查
     */
    public static function handleDepositCheck(int $userId, float $usdtAmount): array
    {
        try {
            // 计算钻石数量
            $diamondAmount = $usdtAmount * config('thirdparty.services.urs.diamond_ratio', 300);

            // 获取用户钻石余额
            $balance = FundService::getBalance($userId, 'DIAMOND');

            // 检查是否允许操作(这里可以添加业务规则)
            $allowed = $balance >= $diamondAmount;

            // 计算费用(如果有手续费)
            $fee = 0; // 暂时无手续费
            $total = $diamondAmount + $fee;

            return [
                'allowed' => $allowed,
                'diamond_balance' => $balance,
                'principal_amount' => $diamondAmount,
                'fee_amount' => $fee,
                'total_required' => $total,
            ];

        } catch (Exception $e) {
            throw new ServiceException('入包检查失败: ' . $e->getMessage());
        }
    }

    /**
     * 检查交易是否已处理
     */
    private static function isTransactionProcessed(string $transactionId): bool
    {
        return ThirdPartyLog::where('transaction_id', $transactionId)
            ->where('status', 'success')
            ->exists();
    }

    /**
     * 记录交易日志
     */
    private static function logTransaction(string $type, int $userId, float $amount, string $transactionId, string $status, $result = null): void
    {
        ThirdPartyLog::create([
            'service_id' => static::getServiceId(),
            'request_type' => 'webhook',
            'endpoint' => $type,
            'request_data' => compact('userId', 'amount', 'transactionId'),
            'response_data' => $result,
            'status' => $status,
            'transaction_id' => $transactionId,
            'response_time' => 0, // Webhook无响应时间
        ]);
    }

    /**
     * 获取URS服务ID
     */
    private static function getServiceId(): int
    {
        static $serviceId = null;

        if ($serviceId === null) {
            $service = ThirdPartyService::where('code', 'URS_PROMOTION')->first();
            $serviceId = $service ? $service->id : 0;
        }

        return $serviceId;
    }
}

7. 配额管理配置

7.1 URS服务配额设置

// 在kku_thirdparty_quotas表中配置URS服务的调用配额
[
    'service_id' => 1, // URS服务ID
    'quota_type' => 'PER_MINUTE',
    'quota_limit' => 100,        // 每分钟100次
    'current_usage' => 0,
    'reset_at' => null,
    'is_active' => true,
],
[
    'service_id' => 1,
    'quota_type' => 'PER_DAY',
    'quota_limit' => 10000,      // 每天10000次
    'current_usage' => 0,
    'reset_at' => null,
    'is_active' => true,
],

8. 监控和告警配置

8.1 健康检查配置

// URS服务健康检查配置
'health_check' => [
    'enabled' => true,
    'interval' => 300,           // 5分钟检查一次
    'timeout' => 10,             // 10秒超时
    'retry_times' => 3,          // 重试3次
    'alert_threshold' => 3,      // 连续3次失败后告警
    'endpoints' => [
        'health' => '/health',   // 健康检查端点
        'status' => '/status',   // 状态检查端点
    ],
],

8.2 性能监控配置

// URS服务性能监控配置
'performance_monitor' => [
    'response_time_threshold' => 5000,  // 响应时间阈值(毫秒)
    'error_rate_threshold' => 0.05,     // 错误率阈值(5%)
    'availability_threshold' => 0.99,   // 可用性阈值(99%)
    'monitor_interval' => 60,           // 监控间隔(秒)
],

实施步骤

第一阶段:基础配置

  1. 服务注册

    • 在ThirdParty模块中注册URS服务
    • 配置基本信息和认证凭证
    • 设置服务状态为TESTING
  2. 加密服务集成

    • 将URS的CryptoService集成到ThirdParty模块
    • 创建URS专用的认证服务类
    • 测试加密解密功能
  3. API接口适配

    • 创建UrsService服务类
    • 实现用户信息、团队关系、下级统计接口
    • 进行接口调用测试

第二阶段:Webhook集成

  1. Webhook控制器开发

    • 创建UrsWebhookController
    • 实现注册、出包、入包、检查四个操作
    • 添加签名验证和安全检查
  2. 资金操作集成

    • 与Fund模块对接
    • 实现钻石充值和提取逻辑
    • 添加交易重复检查机制
  3. 异步处理优化

    • 使用队列处理资金操作
    • 添加失败重试机制
    • 实现操作状态跟踪

第三阶段:监控和优化

  1. 监控系统配置

    • 配置健康检查
    • 设置性能监控阈值
    • 实现告警通知
  2. 配额管理

    • 设置合理的调用配额
    • 实现配额超限处理
    • 添加配额使用统计
  3. 日志和审计

    • 完善调用日志记录
    • 实现敏感操作审计
    • 添加数据统计分析

第四阶段:后台管理

  1. 管理界面开发

    • URS服务配置管理
    • 调用日志查看
    • 监控数据展示
  2. 运维工具

    • 服务状态检查工具
    • 配额重置工具
    • 数据导出功能

技术要点

1. 安全考虑

  • 签名验证:所有API调用都必须通过签名验证
  • 时间戳检查:防止重放攻击
  • 敏感数据加密:认证凭证和交易数据加密存储
  • 访问控制:基于角色的权限管理
  • 审计日志:记录所有敏感操作

2. 性能优化

  • 连接池:复用HTTP连接减少开销
  • 缓存机制:缓存用户信息和关系数据
  • 异步处理:资金操作使用队列异步处理
  • 批量操作:支持批量查询和更新
  • 数据库优化:合理的索引和查询优化

3. 可靠性保障

  • 重试机制:网络异常时自动重试
  • 熔断器:服务异常时快速失败
  • 降级策略:关键功能的降级方案
  • 监控告警:实时监控服务状态
  • 数据一致性:确保资金操作的一致性

4. 扩展性设计

  • 插件化架构:支持新的第三方服务接入
  • 配置化管理:通过配置文件管理服务参数
  • 版本兼容:支持API版本升级
  • 水平扩展:支持多实例部署
  • 模块解耦:与其他模块松耦合

配置示例

1. 环境配置

// config/thirdparty.php
'services' => [
    'urs' => [
        'enabled' => true,
        'base_url' => env('URS_BASE_URL', 'https://urs.example.com/api'),
        'app_key' => env('URS_APP_KEY', 'Hy0LmLKJSbDQY2oaaZOZKR1XKpFHSY8Y'),
        'timeout' => env('URS_TIMEOUT', 30),
        'diamond_ratio' => env('URS_DIAMOND_RATIO', 300),
        'fund_user_id' => env('URS_FUND_USER_ID', 15),
        'control_user_id' => env('URS_CONTROL_USER_ID', 16),
        'webhook_secret' => env('URS_WEBHOOK_SECRET', 'urs_webhook_secret'),
    ],
],

2. 数据库初始化

-- 插入URS服务配置
INSERT INTO kku_thirdparty_services (
    name, code, provider, service_type, version, base_url, auth_type, status,
    description, timeout, retry_times, retry_delay, health_check_url,
    health_check_interval, webhook_url, webhook_secret, priority, config,
    default_params, default_headers, created_at, updated_at
) VALUES (
    'URS用户推广系统',
    'URS_PROMOTION',
    'URS',
    'SOCIAL',
    'v1',
    'https://urs.example.com/api',
    'SIGNATURE',
    'ACTIVE',
    'URS用户推广关系管理和资金操作系统',
    30,
    3,
    1000,
    '/health',
    300,
    '/webhook/urs',
    'urs_webhook_secret_key',
    10,
    '{"diamond_ratio":300,"fund_user_id":15,"control_user_id":16,"currency_type":"DIAMOND","precision":10}',
    '{"format":"json","version":"1.0"}',
    '{"Content-Type":"application/json","Accept":"application/json","User-Agent":"KKU-Farm/1.0"}',
    NOW(),
    NOW()
);

-- 插入认证凭证
INSERT INTO kku_thirdparty_credentials (
    service_id, environment, auth_type, credentials, is_active, created_at, updated_at
) VALUES (
    1,
    'production',
    'SIGNATURE',
    '{"app_key":"Hy0LmLKJSbDQY2oaaZOZKR1XKpFHSY8Y","timeout":300,"algorithm":"AES-256-CBC","hash_algorithm":"sha256"}',
    1,
    NOW(),
    NOW()
);

-- 插入配额配置
INSERT INTO kku_thirdparty_quotas (
    service_id, quota_type, quota_limit, current_usage, is_active, created_at, updated_at
) VALUES
(1, 'PER_MINUTE', 100, 0, 1, NOW(), NOW()),
(1, 'PER_HOUR', 6000, 0, 1, NOW(), NOW()),
(1, 'PER_DAY', 100000, 0, 1, NOW(), NOW());

测试方案

1. 单元测试

// tests/Unit/ThirdParty/UrsServiceTest.php
class UrsServiceTest extends TestCase
{
    public function testGetUserInfo()
    {
        $userKey = '$2y$10$i.h97m13olfIaU.ZTYiyeeXFl8xqn48w2bFiAhcoQsJdU6K3w.Lgu';
        $result = UrsService::getUserInfo($userKey);

        $this->assertArrayHasKey('userId', $result['data']);
        $this->assertTrue($result['success']);
    }

    public function testGetUserTeam()
    {
        $userId = 10002;
        $result = UrsService::getUserTeam($userId);

        $this->assertArrayHasKey('team', $result['data']);
        $this->assertTrue($result['success']);
    }

    public function testHandleDeposit()
    {
        $result = UrsService::handleDeposit(10002, 10.0, 'test_tx_001');

        $this->assertTrue($result['success']);
        $this->assertArrayHasKey('data', $result);
    }
}

2. 集成测试

// tests/Integration/ThirdParty/UrsIntegrationTest.php
class UrsIntegrationTest extends TestCase
{
    public function testWebhookFlow()
    {
        // 测试完整的Webhook流程
        $response = $this->postJson('/api/thirdparty/webhook/urs/deposit', [
            'userId' => 10002,
            'usdtAmount' => 10.0,
            'transactionId' => 'integration_test_001'
        ]);

        $response->assertStatus(200);
        $response->assertJson(['success' => true]);
    }
}

部署清单

1. 代码部署

  • 创建UrsService服务类
  • 创建UrsWebhookController控制器
  • 创建UrsCryptoService加密服务
  • 创建UrsAuthService认证服务
  • 添加Webhook路由配置
  • 更新ThirdParty服务提供者

2. 数据库部署

  • 执行服务配置插入SQL
  • 执行认证凭证插入SQL
  • 执行配额配置插入SQL
  • 创建必要的数据库索引

3. 配置部署

  • 更新环境变量配置
  • 更新ThirdParty模块配置
  • 配置队列和缓存
  • 配置监控和告警

4. 测试验证

  • 执行单元测试
  • 执行集成测试
  • 进行性能测试
  • 验证监控告警

总结

通过将URS系统对接到ThirdParty模块,可以实现:

  1. 统一管理:所有第三方服务在一个模块中统一管理
  2. 安全增强:标准化的认证和加密机制
  3. 监控完善:全面的服务监控和告警
  4. 性能优化:连接池、缓存、异步处理等优化
  5. 运维便利:完善的后台管理和运维工具

这种对接方案既保持了URS系统的原有功能,又获得了ThirdParty模块提供的企业级服务管理能力,为系统的稳定运行和后续扩展奠定了坚实基础。