本文档描述如何将现有的URS(用户推广系统)功能对接到 ThirdParty 模块中,实现统一的第三方服务管理。URS系统提供用户信息查询、推广关系管理和资金操作等功能,通过ThirdParty模块可以实现更好的服务管理、监控和安全控制。
API接口:
Webhook机制:
核心流程:
在ThirdParty模块中,URS属于第三方平台类服务,具体分类为:
[
'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',
],
]
[
'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, // 永不过期
]
原始接口:POST /api/ecology/{ecology_id}/userInfo
ThirdParty调用:
ThirdPartyService::callApi('URS_PROMOTION', 'userInfo', [
'userKey' => $userKey
], 'POST');
原始接口:POST /api/ecology/{ecology_id}/userTeam
ThirdParty调用:
ThirdPartyService::callApi('URS_PROMOTION', 'userTeam', [
'userId' => $userId
], 'POST');
原始接口:POST /api/ecology/{ecology_id}/userLevelCount
ThirdParty调用:
ThirdPartyService::callApi('URS_PROMOTION', 'userLevelCount', [
'userId' => $userId,
'level' => $level // 1或3
], 'POST');
在ThirdParty模块中添加URS专用的Webhook处理路由:
// app/Module/ThirdParty/Routes/webhook.php
Route::post('/webhook/urs/{action}', [UrsWebhookController::class, 'handle'])
->name('urs.webhook')
->middleware(['throttle:60,1']);
创建专门的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('不支持的操作类型');
}
}
}
将现有的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;
}
}
在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'],
];
}
}
创建专门的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;
}
}
// 在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,
],
// URS服务健康检查配置
'health_check' => [
'enabled' => true,
'interval' => 300, // 5分钟检查一次
'timeout' => 10, // 10秒超时
'retry_times' => 3, // 重试3次
'alert_threshold' => 3, // 连续3次失败后告警
'endpoints' => [
'health' => '/health', // 健康检查端点
'status' => '/status', // 状态检查端点
],
],
// URS服务性能监控配置
'performance_monitor' => [
'response_time_threshold' => 5000, // 响应时间阈值(毫秒)
'error_rate_threshold' => 0.05, // 错误率阈值(5%)
'availability_threshold' => 0.99, // 可用性阈值(99%)
'monitor_interval' => 60, // 监控间隔(秒)
],
服务注册
加密服务集成
API接口适配
Webhook控制器开发
资金操作集成
异步处理优化
监控系统配置
配额管理
日志和审计
管理界面开发
运维工具
// 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'),
],
],
-- 插入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());
// 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);
}
}
// 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]);
}
}
通过将URS系统对接到ThirdParty模块,可以实现:
这种对接方案既保持了URS系统的原有功能,又获得了ThirdParty模块提供的企业级服务管理能力,为系统的稳定运行和后续扩展奠定了坚实基础。