Skip to main content
Um Checkout representa a compra do cliente. Ele pode gerar um ou mais Orders, sempre separados por cooperativa. Cada Order pode possuir um Payment quando há valor externo ou dinheiro a cobrar, e sempre possui tickets que ocupam assentos em segmentos específicos da viagem. O Order pode nascer no canal digital (ONLINE), presencial (POS) ou pelo app do motorista (DRIVER_APP). Em venda POS, o sistema resolve ou cria User + Customer antes de criar o pedido, sem gerar convite de ativação. Em Checkout QR, o Customer é vinculado pelo app do cliente ao escanear o QR Code.

Status

O status inicial depende do resultado retornado pelo provider de billing. Transições posteriores chegam por webhook.

Criação do pedido

Validações

Cada ticket recebe cooperativeId, transportOperatorId, seatPrice, tripItineraryPrice, campos de sumarização de valor, qrCode, code, snapshot e os segmentos cobertos. Quando o canal é POS, o operador informa ou resolve o Customer antes da criação do Order. Se o sistema criar uma conta nova para o passageiro nesse fluxo, ela nasce sem convite de ativação. Quando o canal é DRIVER_APP, o usuário autenticado inicia um Checkout QR com Trip e forma de pagamento. O Customer autenticado escaneia o QR Code, completa o contexto do ticket no app do cliente e a confirmação cria Checkout, Order, Ticket e assentos ocupados.

Reserva de assentos

A reserva é segmentada. Um ticket SP → Ribeirão ocupa todos os segmentos entre a parada de embarque e a parada de desembarque. Outro passageiro só pode usar o mesmo assento em segmentos que não se sobrepõem. Se algum segmento já estiver ocupado, o pedido é rejeitado e nenhuma reserva parcial permanece.

Crédito corporativo

O Customer pode indicar quanto de crédito corporativo quer usar no checkout. A reserva pode acontecer no checkout para garantir saldo durante a compra. A captura definitiva do crédito sempre acontece por Ticket, gerando CreditLedgerEntry com ticketId.

Pagamento e confirmação

O pagamento é criado no provider de billing durante o checkout quando há paidAmount a cobrar. Cada Order tem no máximo um Payment, pois cada Order pertence a uma única cooperativa. O pedido pode nascer PENDING ou já PAID, conforme a resposta do provider ou a confirmação de dinheiro. Confirmações, recusas e estornos posteriores chegam por webhook de billing e atualizam o pedido e o pagamento. No Checkout QR com dinheiro, o Payment nasce PAID com method = CASH e channel = DRIVER_APP quando o recebimento é confirmado. A prestação de contas desse dinheiro acontece depois no domínio Billing. No Checkout QR com crédito corporativo, o Customer autoriza o uso no app do cliente. Se o crédito cobrir todo o valor, o Order pode confirmar sem Payment; o uso financeiro fica em CreditLedgerEntry por Ticket.

Cancelamento total

Um pedido pode ser cancelado quando suas regras de status permitem. Em pedidos pagos, o cancelamento solicita estorno ao provider antes de atualizar tickets e pagamento. Efeitos do cancelamento total:
  • Tickets válidos ficam CANCELLED.
  • Reservas de assento dos tickets são liberadas.
  • Payment é marcado como REFUNDED quando há estorno.
  • Benefícios e créditos aplicados são revertidos conforme a regra de cada domínio.
  • Crédito capturado é estornado por Ticket.
  • Order fica CANCELED.

Cancelamento de ticket

Um ticket individual pode ser cancelado quando ainda restam outros tickets válidos no pedido.
  1. O valor do ticket cancelado define o estorno parcial.
  2. As reservas daquele ticket são liberadas.
  3. Crédito capturado naquele ticket é estornado para o mesmo CreditGrant.
  4. O Order.amount passa a refletir a soma dos tickets restantes.
  5. Se o ticket cancelado era o último válido, o fluxo vira cancelamento total.
Cancelar um ticket sempre libera os TripSeatSegments daquele ticket. Depois da liberação, o mesmo assento pode ser vendido novamente para os segmentos correspondentes.
O preço do ticket é congelado no momento da compra. Mudanças posteriores na rota ou no assento não alteram tickets já emitidos.

Atividades do ticket

Validações de QR Code, embarques, rejeições, falhas e reimpressões são registradas em Ticket Activity. O Ticket guarda o estado consolidado; o histórico operacional fica append-only.