tenant = Tenant::factory()->create(['balance_rub' => '0.00']); $this->user = User::factory()->create(['tenant_id' => $this->tenant->id]); $legalEntity = LegalEntity::create([ 'code' => 'test_le_'.uniqid(), 'name' => 'ООО Тест', 'legal_form' => 'OOO', 'inn' => '7700000000', ]); $this->gw = PaymentGateway::create([ 'code' => 'yookassa', 'name' => 'ЮKassa', 'driver' => 'yookassa', 'legal_entity_id' => $legalEntity->id, 'config' => '', 'is_active' => true, 'accepts_methods' => ['card'], 'min_amount_rub' => '100.00', ]); }); function seedPayment(Tenant $tenant, PaymentGateway $gw, string $status, string $amount, int $minutesAgo, ?string $reason = null): SaasTransaction { return SaasTransaction::create([ 'tenant_id' => $tenant->id, 'type' => 'topup', 'amount_rub' => $amount, 'gateway_id' => $gw->id, 'gateway_code' => 'yookassa', 'gateway_payment_id' => 'pay_'.uniqid(), 'status' => $status, 'failure_reason' => $reason, 'created_at' => now()->subMinutes($minutesAgo), ]); } it('показывает незавершённую оплату: статус failed и сумму — чтобы кабинет предложил оплатить снова', function () { seedPayment($this->tenant, $this->gw, 'failed', '10000.00', 30, 'expired_on_confirmation'); $this->actingAs($this->user)->getJson('/api/billing/last-payment') ->assertOk() ->assertJsonPath('data.status', 'failed') ->assertJsonPath('data.amount_rub', '10000.00') ->assertJsonPath('data.failure_reason', 'expired_on_confirmation'); }); it('показывает платёж, который ещё ждёт оплаты', function () { seedPayment($this->tenant, $this->gw, 'pending', '5000.00', 3); $this->actingAs($this->user)->getJson('/api/billing/last-payment') ->assertOk() ->assertJsonPath('data.status', 'pending') ->assertJsonPath('data.amount_rub', '5000.00'); }); it('старую оплату (сутки+) не показывает — баннер не должен всплывать при каждом заходе', function () { seedPayment($this->tenant, $this->gw, 'failed', '10000.00', 60 * 30, 'expired_on_confirmation'); $this->actingAs($this->user)->getJson('/api/billing/last-payment') ->assertOk() ->assertJsonPath('data', null); }); it('успешную оплату не показывает как проблему', function () { seedPayment($this->tenant, $this->gw, 'success', '1000.00', 10); $this->actingAs($this->user)->getJson('/api/billing/last-payment') ->assertOk() ->assertJsonPath('data', null); }); it('чужой платёж не виден (изоляция клиентов)', function () { $other = Tenant::factory()->create(); seedPayment($other, $this->gw, 'failed', '10000.00', 20, 'expired_on_confirmation'); $this->actingAs($this->user)->getJson('/api/billing/last-payment') ->assertOk() ->assertJsonPath('data', null); });