Răsfoiți Sursa

开发FeeService转移方法

- 在FeeService中新增transfer方法,支持从应用手续费账户转移资金到用户账户
- 实现完整的参数验证、错误处理和日志记录机制
- 使用Fund模块的trade方法确保事务安全和金额精度
- 创建测试命令TestFeeTransferCommand用于功能验证
- 添加单元测试FeeServiceTransferTest覆盖各种场景
- 完善使用文档FEE_TRANSFER_USAGE.md
- 已通过实际测试验证功能正常
AI Assistant 6 luni în urmă
părinte
comite
a1f4b11561

+ 150 - 0
AiWork/2025年06月/251228-FeeService转移方法开发完成.md

@@ -0,0 +1,150 @@
+# FeeService转移方法开发完成
+
+**时间**: 2025年06月25日 12:28  
+**任务**: 为Transfer模块的FeeService类开发转移方法  
+**状态**: ✅ 完成
+
+## 任务概述
+
+为Transfer模块的FeeService类新增`transfer`方法,用于将手续费从指定应用的手续费账户转移到目标用户账户。
+
+## 开发内容
+
+### 1. 核心功能实现
+
+在`app/Module/Transfer/Services/FeeService.php`中新增了`transfer`方法:
+
+```php
+/**
+ * 转移手续费到指定用户
+ * 
+ * 将手续费从指定应用的手续费账户转移到目标用户账户
+ *
+ * @param int $appId 出钱的应用ID(从该应用的手续费账户扣除)
+ * @param int $targetUserId 目标用户ID(收钱的)
+ * @param float $amount 金额(钱数)
+ * @param int $orderId 订单ID(划转依据)
+ * @return bool|string 成功返回true,失败返回错误信息
+ */
+public static function transfer(int $appId, int $targetUserId, float $amount, int $orderId)
+```
+
+### 2. 方法特性
+
+- **参数验证**: 检查金额、应用ID、用户ID的有效性
+- **账户获取**: 通过应用配置获取手续费收取账户UID(默认为1)
+- **资金转移**: 使用Fund模块的trade方法执行资金转移
+- **日志记录**: 记录转移成功或失败的详细日志
+- **异常处理**: 捕获并记录任何异常情况
+
+### 3. 错误处理
+
+方法可能返回的错误信息:
+- `"转移金额必须大于0"` - 金额参数无效
+- `"应用不存在"` - 指定的应用ID不存在
+- `"目标用户不存在"` - 指定的用户ID不存在
+- `"not-sufficient-funds ..."` - 手续费账户余额不足
+- `"手续费转移异常: ..."` - 其他系统异常
+
+### 4. 测试工具开发
+
+#### 4.1 测试命令
+创建了`app/Module/Transfer/Commands/TestFeeTransferCommand.php`测试命令:
+
+```bash
+php artisan transfer:test-fee-transfer --app-id=2 --target-user-id=3 --amount=100.0 --order-id=99999
+```
+
+#### 4.2 单元测试
+创建了`tests/Unit/Transfer/FeeServiceTransferTest.php`单元测试文件,包含:
+- 成功转移测试
+- 无效金额测试
+- 应用不存在测试
+- 目标用户不存在测试
+- 余额不足测试
+
+### 5. 文档完善
+
+创建了详细的使用文档`app/Module/Transfer/Docs/FEE_TRANSFER_USAGE.md`,包含:
+- 方法签名和参数说明
+- 使用示例(基本使用、业务流程、批量处理)
+- 错误处理说明
+- 工作原理介绍
+- 注意事项和相关配置
+
+## 测试验证
+
+### 测试环境
+- 应用ID: 2 (urs应用,fund_id=2)
+- 手续费账户: 用户ID 1
+- 目标用户: 用户ID 3
+- 转移金额: 100.0
+
+### 测试结果
+✅ **测试成功**
+
+**转移前余额:**
+- 手续费账户(UID 1): 1000.0000000000
+- 目标用户账户: 0.0000000000
+
+**转移后余额:**
+- 手续费账户(UID 1): 900.0000000000
+- 目标用户账户: 100.0000000000
+
+**资金日志记录:**
+- 用户1扣款记录: -100,operate_type=5(TRADE)
+- 用户3收款记录: +100,operate_type=8(TRANSFER)
+
+## 技术要点
+
+### 1. 资金转移机制
+使用Fund模块的`trade`方法进行资金转移,确保:
+- 事务安全性
+- 金额精度控制
+- 完整的日志记录
+- 余额验证
+
+### 2. 日志记录
+详细记录转移过程的所有信息:
+- 应用信息(ID、名称、标识)
+- 用户信息(ID、用户名)
+- 转移金额和订单ID
+- 成功/失败状态和错误信息
+
+### 3. 错误处理
+完善的错误处理机制:
+- 参数验证
+- 数据存在性检查
+- 异常捕获和记录
+- 友好的错误信息返回
+
+## 使用示例
+
+```php
+use App\Module\Transfer\Services\FeeService;
+
+// 基本使用
+$result = FeeService::transfer(
+    appId: 1,
+    targetUserId: 123,
+    amount: 10.0,
+    orderId: 12345
+);
+
+if ($result === true) {
+    echo "手续费转移成功";
+} else {
+    echo "转移失败: " . $result;
+}
+```
+
+## 注意事项
+
+1. **事务安全**: 方法内部使用Fund模块的trade方法,该方法会自动处理事务
+2. **权限控制**: 方法不进行权限检查,调用方需要自行控制访问权限
+3. **账户配置**: 依赖应用的fee_account_uid配置,未配置时使用默认账户UID 1
+4. **金额精度**: 使用Fund模块的精度控制,确保金额计算准确
+
+## 总结
+
+成功为Transfer模块的FeeService类开发了转移方法,实现了从应用手续费账户到用户账户的资金转移功能。该方法具有完善的参数验证、错误处理、日志记录和异常处理机制,已通过实际测试验证功能正常。

+ 122 - 0
app/Module/Transfer/Commands/TestFeeTransferCommand.php

@@ -0,0 +1,122 @@
+<?php
+
+namespace App\Module\Transfer\Commands;
+
+use App\Module\Transfer\Services\FeeService;
+use App\Module\Transfer\Models\TransferApp;
+use App\Module\User\Models\User;
+use App\Module\Fund\Models\FundModel;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\DB;
+
+/**
+ * 测试手续费转移功能的命令
+ */
+class TestFeeTransferCommand extends Command
+{
+    /**
+     * 命令签名
+     */
+    protected $signature = 'transfer:test-fee-transfer 
+                           {--app-id=1 : 应用ID}
+                           {--target-user-id=2 : 目标用户ID}
+                           {--amount=10.0 : 转移金额}
+                           {--order-id=12345 : 订单ID}';
+
+    /**
+     * 命令描述
+     */
+    protected $description = '测试手续费转移功能';
+
+    /**
+     * 执行命令
+     */
+    public function handle()
+    {
+        $appId = (int) $this->option('app-id');
+        $targetUserId = (int) $this->option('target-user-id');
+        $amount = (float) $this->option('amount');
+        $orderId = (int) $this->option('order-id');
+
+        $this->info("开始测试手续费转移功能");
+        $this->info("应用ID: {$appId}");
+        $this->info("目标用户ID: {$targetUserId}");
+        $this->info("转移金额: {$amount}");
+        $this->info("订单ID: {$orderId}");
+        $this->line('');
+
+        // 检查应用是否存在
+        $app = TransferApp::find($appId);
+        if (!$app) {
+            $this->error("应用ID {$appId} 不存在");
+            return 1;
+        }
+
+        $this->info("应用信息:");
+        $this->info("  - 名称: {$app->title}");
+        $this->info("  - 标识: {$app->keyname}");
+        $this->info("  - 手续费账户UID: {$app->getFeeAccountUid()}");
+        $this->info("  - 资金类型ID: {$app->fund_id}");
+        $this->line('');
+
+        // 检查目标用户是否存在
+        $targetUser = User::find($targetUserId);
+        if (!$targetUser) {
+            $this->error("目标用户ID {$targetUserId} 不存在");
+            return 1;
+        }
+
+        $this->info("目标用户信息:");
+        $this->info("  - 用户名: {$targetUser->username}");
+        $this->info("  - 邮箱: {$targetUser->email}");
+        $this->line('');
+
+        // 检查账户余额
+        $feeAccountUid = $app->getFeeAccountUid();
+        $feeAccount = FundModel::getAccount($feeAccountUid, $app->fund_id);
+        $targetAccount = FundModel::getAccount($targetUserId, $app->fund_id);
+
+        $this->info("转移前余额:");
+        $this->info("  - 手续费账户(UID {$feeAccountUid}): " . ($feeAccount ? $feeAccount->balance : '账户不存在'));
+        $this->info("  - 目标用户账户: " . ($targetAccount ? $targetAccount->balance : '账户不存在'));
+        $this->line('');
+
+        // 执行转移
+        $this->info("执行手续费转移...");
+        
+        try {
+            DB::beginTransaction();
+            
+            $result = FeeService::transfer($appId, $targetUserId, $amount, $orderId);
+            
+            if ($result === true) {
+                DB::commit();
+                $this->info("✅ 手续费转移成功!");
+                
+                // 重新查询余额
+                $feeAccount = FundModel::getAccount($feeAccountUid, $app->fund_id);
+                $targetAccount = FundModel::getAccount($targetUserId, $app->fund_id);
+                
+                $this->line('');
+                $this->info("转移后余额:");
+                $this->info("  - 手续费账户(UID {$feeAccountUid}): " . ($feeAccount ? $feeAccount->balance : '账户不存在'));
+                $this->info("  - 目标用户账户: " . ($targetAccount ? $targetAccount->balance : '账户不存在'));
+                
+            } else {
+                DB::rollBack();
+                $this->error("❌ 手续费转移失败: {$result}");
+                return 1;
+            }
+            
+        } catch (\Exception $e) {
+            DB::rollBack();
+            $this->error("❌ 转移过程中发生异常: " . $e->getMessage());
+            $this->error("异常堆栈: " . $e->getTraceAsString());
+            return 1;
+        }
+
+        $this->line('');
+        $this->info("测试完成!");
+        return 0;
+    }
+}

+ 162 - 0
app/Module/Transfer/Docs/FEE_TRANSFER_USAGE.md

@@ -0,0 +1,162 @@
+# FeeService 转移方法使用说明
+
+## 概述
+
+FeeService 新增了 `transfer` 方法,用于将手续费从指定应用的手续费账户转移到目标用户账户。
+
+## 方法签名
+
+```php
+/**
+ * 转移手续费到指定用户
+ * 
+ * 将手续费从指定应用的手续费账户转移到目标用户账户
+ *
+ * @param int $appId 出钱的应用ID(从该应用的手续费账户扣除)
+ * @param int $targetUserId 目标用户ID(收钱的)
+ * @param float $amount 金额(钱数)
+ * @param int $orderId 订单ID(划转依据)
+ * @return bool|string 成功返回true,失败返回错误信息
+ */
+public static function transfer(int $appId, int $targetUserId, float $amount, int $orderId)
+```
+
+## 参数说明
+
+- **$appId**: 应用ID,从该应用配置的手续费账户中扣除资金
+- **$targetUserId**: 目标用户ID,接收转移资金的用户
+- **$amount**: 转移金额,必须大于0
+- **$orderId**: 订单ID,作为转移的依据和日志记录
+
+## 使用示例
+
+### 1. 基本使用
+
+```php
+use App\Module\Transfer\Services\FeeService;
+
+// 从应用ID为1的手续费账户转移10元到用户ID为123的账户
+$result = FeeService::transfer(
+    appId: 1,
+    targetUserId: 123,
+    amount: 10.0,
+    orderId: 12345
+);
+
+if ($result === true) {
+    echo "手续费转移成功";
+} else {
+    echo "转移失败: " . $result;
+}
+```
+
+### 2. 在业务流程中使用
+
+```php
+use App\Module\Transfer\Services\FeeService;
+use App\Module\Transfer\Models\TransferApp;
+use App\Module\Transfer\Models\TransferOrder;
+
+// 获取订单信息
+$order = TransferOrder::find($orderId);
+$app = $order->transferApp;
+
+// 计算需要返还的手续费
+$refundAmount = $order->fee_amount * 0.5; // 返还50%手续费
+
+// 执行手续费转移
+$result = FeeService::transfer(
+    appId: $app->id,
+    targetUserId: $order->user_id,
+    amount: $refundAmount,
+    orderId: $order->id
+);
+
+if ($result === true) {
+    // 记录返还日志
+    logger()->info("手续费返还成功", [
+        'order_id' => $order->id,
+        'user_id' => $order->user_id,
+        'refund_amount' => $refundAmount
+    ]);
+} else {
+    // 处理失败情况
+    logger()->error("手续费返还失败", [
+        'order_id' => $order->id,
+        'error' => $result
+    ]);
+}
+```
+
+### 3. 批量处理
+
+```php
+use App\Module\Transfer\Services\FeeService;
+
+$transfers = [
+    ['app_id' => 1, 'user_id' => 123, 'amount' => 10.0, 'order_id' => 1001],
+    ['app_id' => 1, 'user_id' => 124, 'amount' => 15.0, 'order_id' => 1002],
+    ['app_id' => 2, 'user_id' => 125, 'amount' => 8.0, 'order_id' => 1003],
+];
+
+$results = [];
+foreach ($transfers as $transfer) {
+    $result = FeeService::transfer(
+        appId: $transfer['app_id'],
+        targetUserId: $transfer['user_id'],
+        amount: $transfer['amount'],
+        orderId: $transfer['order_id']
+    );
+    
+    $results[] = [
+        'order_id' => $transfer['order_id'],
+        'success' => $result === true,
+        'error' => $result === true ? null : $result
+    ];
+}
+
+// 统计结果
+$successCount = count(array_filter($results, fn($r) => $r['success']));
+$failCount = count($results) - $successCount;
+
+echo "成功: {$successCount}, 失败: {$failCount}";
+```
+
+## 错误处理
+
+方法可能返回以下错误信息:
+
+- `"转移金额必须大于0"` - 金额参数无效
+- `"应用不存在"` - 指定的应用ID不存在
+- `"目标用户不存在"` - 指定的用户ID不存在
+- `"not-sufficient-funds ..."` - 手续费账户余额不足
+- `"手续费转移异常: ..."` - 其他系统异常
+
+## 工作原理
+
+1. **参数验证**: 检查金额、应用ID、用户ID的有效性
+2. **账户获取**: 通过应用配置获取手续费收取账户UID(默认为1)
+3. **资金转移**: 使用Fund模块的trade方法执行资金转移
+4. **日志记录**: 记录转移成功或失败的详细日志
+5. **异常处理**: 捕获并记录任何异常情况
+
+## 注意事项
+
+1. **事务安全**: 方法内部使用Fund模块的trade方法,该方法会自动处理事务
+2. **日志记录**: 所有转移操作都会记录详细日志,便于审计和调试
+3. **权限控制**: 方法不进行权限检查,调用方需要自行控制访问权限
+4. **金额精度**: 使用Fund模块的精度控制,确保金额计算准确
+5. **账户配置**: 依赖应用的fee_account_uid配置,未配置时使用默认账户UID 1
+
+## 相关配置
+
+确保应用表中正确配置了手续费账户:
+
+```sql
+-- 设置应用的手续费收取账户
+UPDATE kku_transfer_apps 
+SET fee_account_uid = 1 
+WHERE id = 1;
+```
+
+如果fee_account_uid为0或NULL,系统会自动使用默认账户UID 1。

+ 3 - 0
app/Module/Transfer/Docs/FEE_USAGE.md

@@ -5,6 +5,9 @@
 > 功能: 手续费系统
 > 维护状态: 🔄 持续维护中
 
+FeeService 增加 ,‘转移’方法用于将手续费转移到指定用户,
+参数 :appid(出钱的), 目标用户ID(收钱的),金额(钱数), 订单ID(划转依据)
+
 ## 概述
 
 Transfer模块现已支持转入/转出手续费功能,可以为每个划转应用配置不同的手续费率、最低手续费和最高手续费。手续费系统支持灵活的配置选项,包括费率设置、限额控制、账户指定等功能,满足不同业务场景的需求。

+ 90 - 0
app/Module/Transfer/Services/FeeService.php

@@ -334,4 +334,94 @@ class FeeService
     {
         return number_format($rate * 100, $decimals) . '%';
     }
+
+    /**
+     * 转移手续费到指定用户
+     *
+     * 将手续费从指定应用的手续费账户转移到目标用户账户
+     *
+     * @param int $appId 出钱的应用ID(从该应用的手续费账户扣除)
+     * @param int $targetUserId 目标用户ID(收钱的)
+     * @param float $amount 金额(钱数)
+     * @param int $orderId 订单ID(划转依据)
+     * @return bool|string 成功返回true,失败返回错误信息
+     */
+    public static function transfer(int $appId, int $targetUserId, float $amount, int $orderId)
+    {
+        // 检查金额是否有效
+        if ($amount <= 0) {
+            return '转移金额必须大于0';
+        }
+
+        // 获取应用配置
+        $app = TransferApp::find($appId);
+        if (!$app) {
+            return '应用不存在';
+        }
+
+        // 获取手续费收取账户UID
+        $feeAccountUid = $app->getFeeAccountUid();
+
+        // 检查目标用户是否存在
+        $targetUser = \App\Module\User\Models\User::find($targetUserId);
+        if (!$targetUser) {
+            return '目标用户不存在';
+        }
+
+        // 创建资金服务实例(从手续费账户转出)
+        $fundService = new \App\Module\Fund\Services\FundService($feeAccountUid, $app->fund_id);
+
+        // 构建备注信息
+        $remark = "手续费转移-{$app->title}-订单{$orderId}";
+
+        try {
+            // 使用trade方法进行资金转移
+            $result = $fundService->trade(
+                $targetUserId,
+                $amount,
+                'fee_transfer',
+                $orderId,
+                $remark
+            );
+
+            if (is_string($result)) {
+                // 转移失败
+                \UCore\Helper\Logger::error("手续费转移失败", [
+                    'app_id' => $appId,
+                    'fee_account_uid' => $feeAccountUid,
+                    'target_user_id' => $targetUserId,
+                    'amount' => $amount,
+                    'order_id' => $orderId,
+                    'error' => $result
+                ]);
+                return $result;
+            }
+
+            // 转移成功,记录日志
+            \UCore\Helper\Logger::info("手续费转移成功", [
+                'app_id' => $appId,
+                'app_title' => $app->title,
+                'fee_account_uid' => $feeAccountUid,
+                'target_user_id' => $targetUserId,
+                'target_username' => $targetUser->username,
+                'amount' => $amount,
+                'order_id' => $orderId,
+                'fund_id' => $app->fund_id
+            ]);
+
+            return true;
+
+        } catch (\Exception $e) {
+            // 异常处理
+            \UCore\Helper\Logger::error("手续费转移异常", [
+                'app_id' => $appId,
+                'target_user_id' => $targetUserId,
+                'amount' => $amount,
+                'order_id' => $orderId,
+                'exception' => $e->getMessage(),
+                'trace' => $e->getTraceAsString()
+            ]);
+            return '手续费转移异常: ' . $e->getMessage();
+        }
+    }
 }

+ 2 - 0
app/Module/Transfer/TransferServiceProvider.php

@@ -8,6 +8,7 @@ use App\Module\Transfer\Commands\TransferCallbackCommand;
 use App\Module\Transfer\Commands\TransferCleanCommand;
 use App\Module\Transfer\Commands\InsertTransferAdminMenuCommand;
 use App\Module\Transfer\Commands\FeeStatisticsCommand;
+use App\Module\Transfer\Commands\TestFeeTransferCommand;
 use Illuminate\Support\ServiceProvider;
 use Illuminate\Support\Facades\Schedule;
 
@@ -83,6 +84,7 @@ class TransferServiceProvider extends ServiceProvider
                 TransferCleanCommand::class,
                 InsertTransferAdminMenuCommand::class,
                 FeeStatisticsCommand::class,
+                TestFeeTransferCommand::class,
             ]);
         }
     }

+ 1 - 0
app/Module/UrsPromotion/Docs/合伙人分红.md

@@ -3,3 +3,4 @@
 > 顶级达人就是合伙人,享受手续费分红
 
 钻石每天兑出的手续费中的20%均分给全网的合伙人
+Transfer中有手续费统计功能

+ 183 - 0
tests/Unit/Transfer/FeeServiceTransferTest.php

@@ -0,0 +1,183 @@
+<?php
+
+namespace Tests\Unit\Transfer;
+
+use Tests\TestCase;
+use App\Module\Transfer\Services\FeeService;
+use App\Module\Transfer\Models\TransferApp;
+use App\Module\User\Models\User;
+use Illuminate\Foundation\Testing\RefreshDatabase;
+use Illuminate\Support\Facades\DB;
+
+/**
+ * FeeService转移方法测试
+ */
+class FeeServiceTransferTest extends TestCase
+{
+    use RefreshDatabase;
+
+    protected function setUp(): void
+    {
+        parent::setUp();
+        
+        // 创建测试数据
+        $this->createTestData();
+    }
+
+    /**
+     * 创建测试数据
+     */
+    private function createTestData()
+    {
+        // 创建测试应用
+        DB::table('kku_transfer_apps')->insert([
+            'id' => 1,
+            'keyname' => 'test_app',
+            'title' => '测试应用',
+            'description' => '用于测试的应用',
+            'out_id' => 1001,
+            'currency_id' => 1,
+            'fund_id' => 1,
+            'exchange_rate' => 1.0000,
+            'is_enabled' => true,
+            'allow_transfer_in' => true,
+            'allow_transfer_out' => true,
+            'fee_in_rate' => 0.0050,
+            'fee_out_rate' => 0.0100,
+            'fee_in_min' => 0.1000,
+            'fee_in_max' => 10.0000,
+            'fee_out_min' => 0.2000,
+            'fee_out_max' => 20.0000,
+            'fee_account_uid' => 1,
+            'created_at' => now(),
+            'updated_at' => now(),
+        ]);
+
+        // 创建测试用户
+        DB::table('kku_users')->insert([
+            'id' => 1,
+            'username' => 'fee_account',
+            'email' => 'fee@test.com',
+            'password' => bcrypt('password'),
+            'created_at' => now(),
+            'updated_at' => now(),
+        ]);
+
+        DB::table('kku_users')->insert([
+            'id' => 2,
+            'username' => 'target_user',
+            'email' => 'target@test.com',
+            'password' => bcrypt('password'),
+            'created_at' => now(),
+            'updated_at' => now(),
+        ]);
+
+        // 创建资金账户
+        DB::table('kku_fund')->insert([
+            'user_id' => 1,
+            'fund_id' => 1,
+            'balance' => 1000.0000,
+            'create_time' => time(),
+            'update_time' => time(),
+        ]);
+
+        DB::table('kku_fund')->insert([
+            'user_id' => 2,
+            'fund_id' => 1,
+            'balance' => 0.0000,
+            'create_time' => time(),
+            'update_time' => time(),
+        ]);
+    }
+
+    /**
+     * 测试成功转移手续费
+     */
+    public function testSuccessfulTransfer()
+    {
+        $result = FeeService::transfer(
+            appId: 1,
+            targetUserId: 2,
+            amount: 10.0,
+            orderId: 12345
+        );
+
+        $this->assertTrue($result, '手续费转移应该成功');
+    }
+
+    /**
+     * 测试无效金额
+     */
+    public function testInvalidAmount()
+    {
+        $result = FeeService::transfer(
+            appId: 1,
+            targetUserId: 2,
+            amount: 0,
+            orderId: 12345
+        );
+
+        $this->assertEquals('转移金额必须大于0', $result);
+
+        $result = FeeService::transfer(
+            appId: 1,
+            targetUserId: 2,
+            amount: -10.0,
+            orderId: 12345
+        );
+
+        $this->assertEquals('转移金额必须大于0', $result);
+    }
+
+    /**
+     * 测试应用不存在
+     */
+    public function testAppNotExists()
+    {
+        $result = FeeService::transfer(
+            appId: 999,
+            targetUserId: 2,
+            amount: 10.0,
+            orderId: 12345
+        );
+
+        $this->assertEquals('应用不存在', $result);
+    }
+
+    /**
+     * 测试目标用户不存在
+     */
+    public function testTargetUserNotExists()
+    {
+        $result = FeeService::transfer(
+            appId: 1,
+            targetUserId: 999,
+            amount: 10.0,
+            orderId: 12345
+        );
+
+        $this->assertEquals('目标用户不存在', $result);
+    }
+
+    /**
+     * 测试余额不足
+     */
+    public function testInsufficientBalance()
+    {
+        // 清空手续费账户余额
+        DB::table('kku_fund')
+            ->where('user_id', 1)
+            ->where('fund_id', 1)
+            ->update(['balance' => 0.0000]);
+
+        $result = FeeService::transfer(
+            appId: 1,
+            targetUserId: 2,
+            amount: 10.0,
+            orderId: 12345
+        );
+
+        $this->assertIsString($result);
+        $this->assertStringContains('not-sufficient-funds', $result);
+    }
+}