Include refund/cancel info in booking API responses
PHP Tests / php-tests (push) Waiting to run

Adds Booking::refunds() (hasMany Refund, scoped to this leg per
Refund::booking()) and eager-loads it alongside the other booking
relations, so index/show/store/cancel all expose a refunds array
(status, amount, reason, requested_at, completed_at). A booking that
was cancelled before any payment completed still returns refunds: [].
This commit is contained in:
Nyan Lin Paing
2026-09-03 20:43:02 +07:00
parent 051b091ef8
commit 47be71c2cf
4 changed files with 58 additions and 1 deletions
@@ -91,6 +91,39 @@ test('staff with process_refunds can cancel a confirmed booking, which refunds i
expect($booking->refresh()->status)->toBe(BookingStatus::Cancelled);
});
test('cancelling a confirmed booking returns the refund it created', function () {
$staff = User::factory()->create()->givePermissionTo('process_refunds');
$staffToken = $staff->createToken('staff-token')->plainTextToken;
$booking = Booking::factory()->create(['user_id' => $this->owner->id, 'status' => BookingStatus::Confirmed, 'price' => 15000]);
Payment::factory()->completed()->create([
'booking_id' => $booking->id,
'gateway' => PaymentMethod::KbzMiniApp,
'amount' => 15000,
'gateway_transaction_id' => 'EVB-CANCEL-API-2',
]);
$response = $this->withHeader('Authorization', "Bearer {$staffToken}")
->postJson("/api/v1/bookings/{$booking->booking_ref}/cancel")
->assertSuccessful()
->assertJsonPath('data.status', BookingStatus::Cancelled->value)
->assertJsonCount(1, 'data.refunds')
->assertJsonPath('data.refunds.0.status', RefundStatus::Completed->value)
->assertJsonPath('data.refunds.0.amount', '15000.00')
->assertJsonPath('data.refunds.0.reason', 'Booking cancellation');
expect($response->json('data.refunds.0.completed_at'))->not->toBeNull();
});
test('cancelling a pending_payment booking returns an empty refunds list — no money moved yet', function () {
$booking = Booking::factory()->create(['user_id' => $this->owner->id, 'status' => BookingStatus::PendingPayment]);
$this->withHeader('Authorization', "Bearer {$this->token}")
->postJson("/api/v1/bookings/{$booking->booking_ref}/cancel")
->assertSuccessful()
->assertJsonPath('data.refunds', []);
});
test('cancelling a confirmed booking with no completed payment surfaces as 422 and leaves it untouched', function () {
$staff = User::factory()->create()->givePermissionTo('process_refunds');
$staffToken = $staff->createToken('staff-token')->plainTextToken;