# Billing

Turista's billing model separates owner-facing invoices from customer-facing receipts and tracks all money movement through transactions.

## Invoice

`App\Models\Invoice` is generated for the owner when a reservation is confirmed.

Key fields:

- `reservation_id`
- `received` enum (invoice type/role)
- `document_number`
- `price`, `total_price`, `discount`, `net_price`
- `paid_amount`, `remaining_amount`
- `paid_at`, `due_at`

Invoices cannot be deleted if transactions exist against them.

## Receipt

`App\Models\Receipt` mirrors the invoice for the customer.

Key fields:

- `reservation_id`
- `invoice_id` (nullable)
- same financial fields as invoice

Receipts give customers a record of what they owe or have paid.

## Transaction

`App\Models\Transaction` records each payment or refund.

Key fields:

- `invoice_id`
- `type` — `payment` or `refund`
- `payment_method` — `cash`, `card`, or `wallet`
- `amount`
- `reason`

The `PaymentService` processes payments and refunds atomically to avoid double-credits or race conditions.

## Wallet

Customers have a `wallet` balance on their profile. Refunds can be credited to the wallet, and wallet balance can be used as a payment method.

## Sequence numbering

`SequenceService` maintains atomic counters in the `sequences` table. Each invoice, receipt, and reservation gets a zero-padded number such as:

- `RES-00001`
- `INV-00001`
- `REC-00001`

## Recalculation

When a reservation is updated (e.g., date change), `ReservationService::recalculateReservation` updates the invoice and receipt totals and triggers any required refund.

## Security note

Financial operations use row-level locking and atomic updates to prevent race conditions. See the security audit for additional hardening notes.
