feat: 增强奖池与钱包服务的多币种支持能力
更新 JackpotManualBurstService:在解析头奖中奖者时支持币种代码处理。 重构 SettlementBatchWorkflowService:按币种聚合玩家派奖金额,确保各币种结算准确入账。 修改 SettlementOrchestrator:按币种分别处理奖池爆奖流程,提升派奖准确性。 优化 TicketWalletService:在派奖幂等键中加入币种信息,避免多币种场景下的重复处理问题。 新增测试用例,验证多币种派奖场景及待处理交易的正确处理逻辑。
This commit is contained in:
@@ -460,3 +460,89 @@ test('replay while order still processing returns 1002', function (): void {
|
||||
->assertStatus(409)
|
||||
->assertJsonPath('code', ErrorCode::WalletTransferPending->value);
|
||||
});
|
||||
|
||||
test('transfer in replay while pending_reconcile stays pending without wallet credit', function (): void {
|
||||
Http::fake([
|
||||
'timeout-debit-replay.test/*' => Http::response([], 504),
|
||||
]);
|
||||
config(['lottery.main_site.wallet_api_url' => 'https://timeout-debit-replay.test']);
|
||||
config(['lottery.main_site.wallet_debit_path' => 'debit']);
|
||||
|
||||
$player = Player::query()->create([
|
||||
'site_code' => 'main',
|
||||
'site_player_id' => 'in-pending-replay',
|
||||
'username' => null,
|
||||
'nickname' => null,
|
||||
'default_currency' => 'NPR',
|
||||
'status' => 0,
|
||||
]);
|
||||
|
||||
$key = 'in-pending-replay-key';
|
||||
$payload = [
|
||||
'amount' => 500,
|
||||
'currency' => 'NPR',
|
||||
'idempotent_key' => $key,
|
||||
];
|
||||
|
||||
$this->withHeader('Authorization', 'Bearer dev:'.$player->id)
|
||||
->postJson('/api/v1/wallet/transfer-in', $payload)
|
||||
->assertStatus(409)
|
||||
->assertJsonPath('code', ErrorCode::WalletTransferPending->value);
|
||||
|
||||
$this->withHeader('Authorization', 'Bearer dev:'.$player->id)
|
||||
->postJson('/api/v1/wallet/transfer-in', $payload)
|
||||
->assertStatus(409)
|
||||
->assertJsonPath('code', ErrorCode::WalletTransferPending->value);
|
||||
|
||||
expect(TransferOrder::query()->where('idempotent_key', $key)->count())->toBe(1)
|
||||
->and(TransferOrder::query()->where('idempotent_key', $key)->value('status'))->toBe('pending_reconcile')
|
||||
->and(WalletTxn::query()->where('biz_type', 'transfer_in')->count())->toBe(0);
|
||||
});
|
||||
|
||||
test('transfer out replay while pending_reconcile keeps single pending txn', function (): void {
|
||||
Http::fake([
|
||||
'timeout-credit-replay.test/*' => Http::response([], 504),
|
||||
]);
|
||||
config(['lottery.main_site.wallet_api_url' => 'https://timeout-credit-replay.test']);
|
||||
config(['lottery.main_site.wallet_credit_path' => 'credit']);
|
||||
|
||||
$player = Player::query()->create([
|
||||
'site_code' => 'main',
|
||||
'site_player_id' => 'out-pending-replay',
|
||||
'username' => null,
|
||||
'nickname' => null,
|
||||
'default_currency' => 'NPR',
|
||||
'status' => 0,
|
||||
]);
|
||||
PlayerWallet::query()->create([
|
||||
'player_id' => $player->id,
|
||||
'wallet_type' => 'lottery',
|
||||
'currency_code' => 'NPR',
|
||||
'balance' => 1_000,
|
||||
'frozen_balance' => 0,
|
||||
'status' => 0,
|
||||
'version' => 0,
|
||||
]);
|
||||
|
||||
$key = 'out-pending-replay-key';
|
||||
$payload = [
|
||||
'amount' => 200,
|
||||
'idempotent_key' => $key,
|
||||
];
|
||||
|
||||
$this->withHeader('Authorization', 'Bearer dev:'.$player->id)
|
||||
->postJson('/api/v1/wallet/transfer-out', $payload)
|
||||
->assertStatus(409)
|
||||
->assertJsonPath('code', ErrorCode::WalletTransferPending->value);
|
||||
|
||||
$this->withHeader('Authorization', 'Bearer dev:'.$player->id)
|
||||
->postJson('/api/v1/wallet/transfer-out', $payload)
|
||||
->assertStatus(409)
|
||||
->assertJsonPath('code', ErrorCode::WalletTransferPending->value);
|
||||
|
||||
expect(TransferOrder::query()->where('idempotent_key', $key)->count())->toBe(1)
|
||||
->and(TransferOrder::query()->where('idempotent_key', $key)->value('status'))->toBe('pending_reconcile')
|
||||
->and(WalletTxn::query()->where('biz_type', 'transfer_out')->count())->toBe(1)
|
||||
->and(WalletTxn::query()->where('biz_type', 'transfer_out')->value('status'))->toBe('pending_reconcile')
|
||||
->and((int) PlayerWallet::query()->where('player_id', $player->id)->value('balance'))->toBe(800);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user