README.md 9.8 KB

Transfer模块 - 划转系统

Transfer模块是农场游戏系统的资金划转核心模块,负责处理用户与外部系统之间的资金转入转出操作。

📋 目录

🎯 核心概念

基本术语

术语 说明 示例
转入订单 用户充值/存入资金到农场系统 URS用户充值100元到农场
转出订单 用户提现/转出资金到外部系统 农场用户提现30000钻石到URS
外部金额 第三方系统的金额单位 URS系统的100元
内部金额 农场系统的钻石数量 农场系统的30000钻石
汇率 外部金额与内部金额的转换比例 1元 = 300钻石

订单状态

enum TransferStatus: int
{
    case CREATED = 100;     // 已创建
    case PROCESSING = 200;  // 处理中
    case COMPLETED = 300;   // 已完成
    case FAILED = 400;      // 失败
    case CANCELLED = 500;   // 已取消
}

订单类型

enum TransferType: int
{
    case IN = 1;   // 转入
    case OUT = 2;  // 转出
}

🏗️ 架构设计

模块结构

app/Module/Transfer/
├── Controllers/           # 后台管理控制器
├── Dtos/                 # 数据传输对象
├── Enums/                # 枚举类
├── Events/               # 事件类
├── Handlers/             # API处理器
├── Logics/               # 业务逻辑层
├── Models/               # 数据模型
├── Repositories/         # 数据仓库层
├── Services/             # 服务层
├── Validations/          # 验证类
└── Validators/           # 验证器

核心类说明

类名 职责 说明
TransferLogic 核心业务逻辑 处理转入转出订单创建和执行
TransferThirdPartyService 第三方服务 专门处理第三方应用集成
TransferApp 应用配置模型 管理划转应用配置和手续费计算
TransferOrder 订单模型 划转订单数据模型
OrderLogic 订单处理逻辑 处理订单状态变更和外部API调用
CallbackLogic 回调处理逻辑 处理外部系统回调通知

💱 金额转换逻辑

转换规则

第三方应用转出

外部金额 × 汇率 = 内部金额
示例:100元 × 300 = 30000钻石

普通应用转出

内部金额 ÷ 汇率 = 外部金额
示例:30000钻石 ÷ 300 = 100元

转入操作

外部金额 × 汇率 = 内部金额
示例:50元 × 300 = 15000钻石

重要原则

  1. 避免双重转换:只在TransferLogic层进行一次转换
  2. 精度处理:使用bcmath函数确保计算精度
  3. 汇率验证:确保汇率大于0,避免计算异常

💰 手续费机制

手续费模式

转出:手续费额外收取

用户想转出:3000钻石
手续费:10钻石
用户总扣除:3010钻石
外部实际收到:3000钻石(完整金额)

转入:手续费从金额中扣除

外部转入:3000钻石
手续费:10钻石
用户实际收到:2990钻石

手续费计算

// 按比例计算
$feeAmount = $amount * $feeRate;

// 应用最低限制
if ($feeAmount < $minFee) {
    $feeAmount = $minFee;
}

// 应用最高限制
if ($maxFee > 0 && $feeAmount > $maxFee) {
    $feeAmount = $maxFee;
}

手续费配置

字段 说明 示例
fee_out_rate 转出手续费率 0.01 (1%)
fee_out_min 转出最低手续费 0.5钻石
fee_out_max 转出最高手续费 10钻石
fee_in_rate 转入手续费率 0.005 (0.5%)
fee_in_min 转入最低手续费 1钻石
fee_in_max 转入最高手续费 50钻石

🔌 第三方应用集成

核心服务

TransferThirdPartyService专门处理第三方应用需求:

// 创建提现订单
$result = TransferThirdPartyService::createWithdrawOrder(
    thirdPartyAppId: 11,
    farmUserId: 39027,
    thirdPartyUserId: '10002',
    thirdPartyAmount: '100',  // 外部金额
    remark: 'URS提取',
    callbackData: ['operation_type' => 'withdraw']
);

// 创建充值订单
$result = TransferThirdPartyService::createDepositOrder(
    thirdPartyAppId: 11,
    farmUserId: 39027,
    thirdPartyUserId: '10002',
    thirdPartyAmount: '50',   // 外部金额
    remark: 'URS充值',
    callbackData: ['operation_type' => 'deposit']
);

特殊功能

  1. 跳过密码验证:第三方应用无需用户输入密码
  2. 自动金额转换:自动处理外部金额与内部金额转换
  3. 回调支持:支持状态变更回调通知
  4. 权限控制:独立控制转入/转出操作权限

📡 API接口

转出接口

POST /api/transfer/out
Content-Type: application/json

{
    "transfer_app_id": 1,
    "amount": "30000",
    "password": "123456",
    "out_user_id": "user123",
    "remark": "提现到银行卡"
}

转入接口

POST /api/transfer/in
Content-Type: application/json

{
    "transfer_app_id": 1,
    "business_id": "ORDER_20250619001",
    "amount": "15000",
    "out_user_id": "user123",
    "remark": "银行卡充值"
}

回调接口

POST /api/transfer/callback
Content-Type: application/json

{
    "business_id": "ORDER_20250619001",
    "out_id": 1,
    "success": true,
    "message": "处理成功"
}

🗄️ 数据库设计

主要数据表

transfer_apps - 划转应用配置表

CREATE TABLE `kku_transfer_apps` (
  `id` int NOT NULL AUTO_INCREMENT,
  `title` varchar(100) NOT NULL COMMENT '应用名称',
  `exchange_rate` decimal(10,4) NOT NULL DEFAULT '1.0000' COMMENT '汇率',
  `allow_transfer_in` tinyint(1) NOT NULL DEFAULT '1' COMMENT '允许转入',
  `allow_transfer_out` tinyint(1) NOT NULL DEFAULT '1' COMMENT '允许转出',
  `fee_out_rate` decimal(8,6) NOT NULL DEFAULT '0.000000' COMMENT '转出手续费率',
  `fee_out_min` decimal(20,10) NOT NULL DEFAULT '0.0000000000' COMMENT '转出最低手续费',
  `fee_out_max` decimal(20,10) NOT NULL DEFAULT '0.0000000000' COMMENT '转出最高手续费',
  -- 更多字段...
  PRIMARY KEY (`id`)
);

transfer_orders - 划转订单表

CREATE TABLE `kku_transfer_orders` (
  `id` int NOT NULL AUTO_INCREMENT,
  `transfer_app_id` int NOT NULL COMMENT '划转应用ID',
  `out_order_id` varchar(100) NOT NULL COMMENT '外部订单ID',
  `user_id` int NOT NULL COMMENT '用户ID',
  `type` tinyint NOT NULL COMMENT '类型:1转入,2转出',
  `status` int NOT NULL COMMENT '状态',
  `out_amount` decimal(30,10) NOT NULL COMMENT '外部金额',
  `amount` decimal(30,10) NOT NULL COMMENT '内部金额',
  `exchange_rate` decimal(10,4) NOT NULL COMMENT '汇率',
  `fee_amount` decimal(30,10) NOT NULL DEFAULT '0.0000000000' COMMENT '手续费',
  `actual_amount` decimal(30,10) NOT NULL COMMENT '实际金额',
  -- 更多字段...
  PRIMARY KEY (`id`)
);

⚙️ 配置说明

应用配置

在后台管理界面配置划转应用:

  1. 基本信息:应用名称、描述
  2. 汇率设置:外部金额与内部金额转换比例
  3. 权限控制:允许转入/转出操作
  4. 手续费配置:费率、最低/最高限制
  5. 账户配置:转入来源账户、转出目标账户
  6. API配置:外部API地址、回调URL

环境配置

# Transfer模块配置
TRANSFER_DEFAULT_FEE_ACCOUNT_UID=1
TRANSFER_CALLBACK_TIMEOUT=30
TRANSFER_API_TIMEOUT=60

📝 使用示例

基本转出操作

use App\Module\Transfer\Services\TransferService;

// 创建转出订单
$order = TransferService::createTransferOut(
    transferAppId: 1,
    userId: 12345,
    amount: '30000',
    password: '123456',
    outUserId: 'user123',
    remark: '提现到银行卡'
);

echo "订单ID: {$order->id}";
echo "外部订单ID: {$order->out_order_id}";
echo "状态: {$order->status->name}";

URS第三方集成示例

use App\Module\Transfer\Services\TransferThirdPartyService;

// URS提现
$result = TransferThirdPartyService::createWithdrawOrder(
    thirdPartyAppId: 11,
    farmUserId: 39027,
    thirdPartyUserId: '10002',
    thirdPartyAmount: '100',
    remark: 'URS提取',
    callbackData: [
        'operation_type' => 'withdraw',
        'urs_order_id' => 'URS_20250619001'
    ]
);

if (is_string($result)) {
    echo "创建失败: {$result}";
} else {
    echo "创建成功,订单ID: {$result->id}";
}

🔧 故障排除

常见问题

1. 金额转换错误

问题:外部金额2500变成内部金额2500
原因:双重转换问题
解决:确保只在TransferLogic层进行一次转换

2. 手续费计算异常

问题:手续费从转出金额中扣除,用户困惑
原因:手续费模式理解错误
解决:转出使用额外收取模式,转入使用扣除模式

3. 余额验证失败

问题:用户余额充足但验证失败
原因:验证逻辑与执行逻辑不一致
解决:确保验证器检查转出金额+手续费总和

4. 事务级别错误

问题:transaction level is 0错误
原因:Fund模块trade方法需要在事务中执行
解决:在调用前开启事务

调试工具

# 重现错误请求
php artisan debug:reproduce-error {request_log_id}

# 检查订单状态
php artisan transfer:order:status {order_id}

# 重试失败订单
php artisan transfer:order:retry {order_id}

版本: v1.0
最后更新: 2025-06-19
维护者: AI Assistant