> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devmob.app.br/llms.txt
> Use this file to discover all available pages before exploring further.

# CheckoutSession

> Sessão temporária de checkout por QR Code antes da criação do Checkout

`CheckoutSession` registra o handshake de checkout por QR Code antes da criação do checkout. A sessão nasce sem Customer, expõe um QR Code temporário, é vinculada quando o cliente autenticado escaneia o código e só então pode confirmar uma venda por dinheiro ou crédito corporativo.

## Campos

| Campo                   | Tipo                           | Descrição                                                                   |
| ----------------------- | ------------------------------ | --------------------------------------------------------------------------- |
| `checkoutSessionId`     | `UUID`                         | Identificador único                                                         |
| `tripId`                | `UUID`                         | Trip selecionada para a venda                                               |
| `tripItineraryId`       | `UUID?`                        | Itinerário escolhido pelo Customer antes da confirmação                     |
| `seatId`                | `UUID?`                        | Assento escolhido pelo Customer antes da confirmação                        |
| `paymentMethod`         | `CheckoutSessionPaymentMethod` | Forma escolhida para o checkout                                             |
| `qrTokenHash`           | `String`                       | Hash do token usado no QR Code; o token bruto não é persistido              |
| `passengerDraft`        | `Json?`                        | Passageiro informado pelo Customer antes da criação do Passenger definitivo |
| `requestedCreditAmount` | `Int?`                         | Valor de crédito solicitado pelo Customer para esta sessão                  |
| `promotionalCode`       | `String?`                      | Código promocional informado pelo Customer, quando aplicável                |
| `expiresAt`             | `DateTime`                     | Data limite de validade do QR Code                                          |
| `linkedAt`              | `DateTime?`                    | Data em que o Customer foi vinculado                                        |
| `preparedAt`            | `DateTime?`                    | Data em que o Customer preparou o contexto do ticket                        |
| `confirmedAt`           | `DateTime?`                    | Data em que a venda foi confirmada                                          |
| `canceledBy`            | `UUID?`                        | Usuário que cancelou a sessão, quando aplicável                             |
| `canceledAt`            | `DateTime?`                    | Data de cancelamento                                                        |
| `createdBy`             | `UUID?`                        | Usuário que criou o registro, quando aplicável                              |
| `createdAt`             | `DateTime`                     | Data de criação                                                             |
| `updatedBy`             | `UUID?`                        | Usuário que fez a última atualização, quando aplicável                      |
| `updatedAt`             | `DateTime`                     | Data da última atualização                                                  |

## Relacionamentos

* Relaciona-se com [Trip](/data-modelling/operations/trip) por `tripId`.
* Relaciona-se com [TripItinerary](/data-modelling/operations/trip-itinerary) por `tripItineraryId`, depois da preparação pelo app do cliente.
* Relaciona-se com [Seat](/data-modelling/fleet/seat) por `seatId`, depois da preparação pelo app do cliente.
* A sessão não persiste `driverId`, `customerId` ou `checkoutId`.
* O usuário que cria ou cancela a sessão é auditado por `createdBy` e `canceledBy`, sem transformar a sessão em entidade de Driver.
* O Customer é resolvido pelo User autenticado no Customer API.
* O Checkout criado pela confirmação é retorno do fluxo de confirmação.

## Regras de Negócio

* A sessão é criada por um canal autenticado de venda usando o User autenticado.
* O app do cliente deve autenticar o Customer e vincular a sessão antes de qualquer confirmação de compra.
* O canal que inicia a venda seleciona a Trip e `paymentMethod`; o app do cliente prepara o contexto necessário para emitir Ticket, como passageiro, itinerário, assento, crédito e promoção.
* `tripItineraryId`, `seatId`, `passengerDraft`, `requestedCreditAmount`, `promotionalCode` e `preparedAt` só são preenchidos depois que o Customer envia o contexto do ticket pelo app.
* A Trip deve estar elegível para venda pelo fluxo de QR Code e o usuário autenticado deve estar autorizado para operá-la.
* A sessão deve expirar em `expiresAt`; sessões expiradas ou canceladas não podem criar Checkout.
* Apenas sessões vinculadas, preparadas, não expiradas, não canceladas e ainda não confirmadas podem ser confirmadas.
* Quando `paymentMethod = CREDIT_GRANT`, a autorização e a validação de saldo acontecem no app do cliente. O canal de venda não seleciona crédito do Customer manualmente.
* `requestedCreditAmount` é solicitação do Customer; o valor definitivo usado no checkout fica em Checkout, Order, Ticket e CreditLedgerEntry.
* Quando `paymentMethod = CASH`, a confirmação significa que o dinheiro foi aceito. A prestação de contas posterior segue o fluxo financeiro do canal em [CashSettlement](/data-modelling/billing/cash-settlement).
* A confirmação cria [Checkout](/data-modelling/sales/checkout), [Order](/data-modelling/sales/order), [Ticket](/data-modelling/sales/ticket) e as reservas de assento necessárias.
* Depois da confirmação, `confirmedAt` é preenchido e o Checkout criado é retornado pelo fluxo de confirmação.
* O QR Code não é estado do Checkout; o estado temporário do QR vive somente na CheckoutSession.
* O status da sessão é calculado a partir dos timestamps e não deve ser persistido.

<Info>
  `paymentMethod = CREDIT_GRANT` aqui não adiciona `CREDIT_GRANT` em PaymentMethod. Crédito corporativo continua sendo modelado por CreditGrant e CreditLedgerEntry.
</Info>

## Enums

### CheckoutSessionPaymentMethod

| Valor          | Descrição                                                   |
| -------------- | ----------------------------------------------------------- |
| `CASH`         | Venda em dinheiro                                           |
| `CREDIT_GRANT` | Venda paga com crédito corporativo autorizado pelo Customer |

### CheckoutSessionComputedStatus

Status virtual calculado em repository/query, sem campo persistido.

| Valor       | Descrição                                                                               |
| ----------- | --------------------------------------------------------------------------------------- |
| `CREATED`   | `linkedAt`, `preparedAt`, `confirmedAt` e `canceledAt` vazios, com `expiresAt` futuro   |
| `LINKED`    | `linkedAt` preenchido, sem preparação/confirmação/cancelamento e com `expiresAt` futuro |
| `PREPARED`  | `preparedAt` preenchido, sem confirmação/cancelamento e com `expiresAt` futuro          |
| `CONFIRMED` | `confirmedAt` preenchido                                                                |
| `EXPIRED`   | `expiresAt` no passado antes da confirmação                                             |
| `CANCELED`  | `canceledAt` preenchido antes da confirmação                                            |

## Example

```json theme={null}
{
  "checkoutSessionId": "01981255-3c7a-7bd4-bb5f-8b47bc4dce91",
  "tripId": "0197a80f-2d8f-7710-b243-b67fb477a1c0",
  "tripItineraryId": "0197a810-87ce-7b60-9d80-660d0ee1c413",
  "seatId": "0197a80a-bc30-70c3-954f-657c74277162",
  "paymentMethod": "CASH",
  "qrTokenHash": "sha256:8f34d4b7c7b3a331a7e3f7c6f8fdb9e2637a7d94e95d2f7c22b8c411d4815c4f",
  "passengerDraft": {
    "name": "Mariana Costa",
    "document": "12345678909",
    "documentType": "CPF",
    "birthDate": "1992-04-18"
  },
  "requestedCreditAmount": 0,
  "promotionalCode": null,
  "expiresAt": "2026-07-08T12:15:00.000Z",
  "linkedAt": "2026-07-08T12:10:21.000Z",
  "preparedAt": "2026-07-08T12:10:45.000Z",
  "confirmedAt": "2026-07-08T12:11:08.000Z",
  "canceledBy": null,
  "canceledAt": null,
  "createdBy": "0197a805-0910-7eb2-bae7-90a13df2a9b2",
  "createdAt": "2026-07-08T12:10:00.000Z",
  "updatedBy": "0197a805-0910-7eb2-bae7-90a13df2a9b2",
  "updatedAt": "2026-07-08T12:11:08.000Z"
}
```
