Passageiros Intermediário 10 min de leitura

Passageiros - Convites e Links de Confirmação

Cobre os dois fluxos principais de envio de link a um passageiro: o link de convite (gerado no checkout ou via prorrogação, válido por 48h, abre um formulário para o convidado preencher dados ou vincular dependente) e o link mágico de acesso ao portal Minha Conta (gerado sob demanda no dropdown da reserva, válido por 30 minutos, autologa o comprador). Inclui envio por WhatsApp/e-mail, prorrogação de convite expirado e o caminho alternativo em que o próprio comprador preenche os dados pendentes pela área do cliente.

Atualizado em 12/08/2026

Passageiros - Convites e Links de Confirmação

O que é

Existem dois tipos de link que o admin pode enviar para um passageiro a partir da listagem Passageiros da excursão, e eles servem para coisas diferentes.

O link de convite é gerado quando o comprador finaliza uma reserva sem preencher os dados de todos os passageiros do grupo (escolheu a opção "Convidar depois" para uma das vagas). O sistema cria um ExcursaoPassageiroPendente, um PassageiroConviteToken válido por 48h e um passageiro placeholder marcado como cadastrado_via = convite_pendente. O link /convite/{token} abre um formulário público onde o convidado se identifica (ou se loga, se já for cliente) e seus dados substituem o placeholder.

O link mágico (auto-login) é um atalho operacional: você gera sob demanda um link de 30 minutos que entra no portal Minha Conta já autenticado como o comprador da reserva, redirecionando para o pedido específico. Serve para resolver dúvida de cliente sem pedir e-mail/senha - porém qualquer pessoa com o link entra na conta, então o sistema exige um aviso de risco antes de gerar.

Você normalmente chega aqui quando: o convidado não preencheu os dados a tempo, o cliente perdeu acesso à própria conta, ou o atendimento precisa olhar a reserva pelo ponto de vista do cliente.

Como usar

Enviar link de convite no momento da reserva

O fluxo padrão é automático: quando o comprador escolhe a opção convite para uma vaga do carrinho, o PassageiroConviteService::criarPassageirosPendentes faz tudo em transação:

  1. Cria um ExcursaoPassageiroPendente com expira_em = agora + 48h.
  2. Gera um PassageiroConviteToken (string aleatória) e calcula a URL /convite/{token} via PassageiroConviteToken::getLink().
  3. Se o checkout marcou enviar_email ou enviar_whatsapp, dispara o envio:
    • E-mail via template cliente.convite-passageiro (assunto "Convite para viagem - {nome da excursão}").
    • WhatsApp via Evolution API, se o módulo whatsapp-mensagens estiver ativo e a instância conectada. Sem o módulo, o sistema só registra um wa.me/... no log (fallback).

Cada convite é único - o sistema não bloqueia "duplicatas" do comprador no WhatsApp (uso de clienteId: null no EnviarWhatsAppJob) para que cada convidado receba seu próprio link.

Reenviar / prorrogar convite expirado

Quando o token vence ou é usado, o passageiro placeholder continua na listagem com a tag visual de Convite pendente:

  1. Vá em Viagens (Excursões) no menu lateral e abra a excursão.
  2. Acesse a aba Passageiros.
  3. Localize a linha do passageiro convidado (avatar laranja, label "Convite pendente").
  4. Abra o dropdown de ações (ícone de três pontos) e clique em Prorrogar convite (+48h).
  5. O sistema decide automaticamente:
    • Se o token atual ainda existe e não foi usado nem expirou → estende expira_em em mais 48h.
    • Se foi usado/expirou → cria um novo token (apaga o antigo) e renova o prazo.
  6. O modal de compartilhamento abre com o novo link. Use Copiar, ou os botões de compartilhamento para WhatsApp/Telegram/e-mail.

A ação só aparece quando cadastrado_via = convite_pendente. Para reservas comuns o item não é renderizado.

Comprador preencher os dados pela área do cliente

O próprio comprador pode resolver pendências sem precisar reenviar o link: na Minha Conta, em cada reserva, aparecem os passageiros pendentes do grupo. O comprador preenche o formulário e o PassageiroConviteService::preencherPeloComprador atualiza o placeholder (ou cria um passageiro novo, se não houver placeholder), grava cadastrado_via = preenchido_comprador e marca o token como usado.

Esse fluxo dispensa o convidado de fazer qualquer coisa - útil quando o comprador conhece os dados (família/dependentes) e quer fechar a reserva sozinho.

Vincular dependente já cadastrado

Quando o cliente logado abre o link /convite/{token} e escolhe um dependente do próprio cadastro, o sistema chama vincularDependente. O placeholder é atualizado com:

  • cliente_id do titular (mantido para CRM/financeiro consolidados);
  • dependente_id do dependente vinculado;
  • nome, CPF, RG, telefone, e-mail e data de nascimento copiados do dependente;
  • cadastrado_via = link_convite_dependente.

O dependente não se torna um cliente separado - continua referenciado pelo titular.

Gerar link mágico de acesso ao portal

  1. Na listagem Passageiros da excursão, abra o dropdown de ações da linha do passageiro.
  2. Clique em Enviar acesso ao portal (ícone de chave).
  3. O modal Acesso ao portal do cliente abre na etapa Aviso:
    • Texto destacado em laranja explicando que o link autologa sem senha.
    • Checkbox de confirmação: "Confirmo que entendi o risco e quero gerar o link de acesso para {nome}".
  4. Marque o checkbox e clique em Gerar link.
  5. O sistema chama ExcursaoPassageiroController::gerarLinkMagico que:
    • Identifica o cliente alvo (comprador_id se for convidado/dependente; senão cliente_id).
    • Gera 64 caracteres aleatórios via bin2hex(random_bytes(32)), salva o hash SHA-256 em auto_login_token do cliente e define auto_login_expires_at = agora + 30min.
    • Monta /auth/magic/{plain}?redirect=/minha-conta/reservas/{codigo} (ou /minha-conta se a reserva não tem Order).
  6. Etapa Compartilhar: o modal mostra o link em campo somente-leitura com botão Copiar + grade Enviar por com WhatsApp e E-mail.
  7. O botão E-mail envia automaticamente um e-mail formatado com layout da sua empresa (logo, cor primária, botão CTA). Requer ?via=email no request - o componente já manda esse parâmetro quando você clica.

O cliente alvo do magic link é sempre o comprador da reserva, não o passageiro convidado - porque é quem realmente loga e gerencia.

Casos especiais

Cliente sem e-mail cadastrado

No modal do link mágico, se cliente.email for vazio, o botão E-mail fica desabilitado e aparece o aviso "Cliente sem e-mail cadastrado - só dá pra enviar via WhatsApp ou copiar o link.". O envio por e-mail simplesmente é pulado e o JSON de resposta volta email_enviado: false.

Token usado ou expirado no link de convite

A view pública /convite/{token} chama PassageiroConviteService::validarToken antes de renderizar o formulário e, dependendo do estado, retorna uma view de erro específica:

  • code = invalid → "Link inválido."
  • code = used → "Este link já foi utilizado."
  • code = expired → "Este link expirou."

Para o caso expired, use Prorrogar convite (+48h) no admin para gerar um novo token e reenviar.

Convite com placeholder pré-existente vs. sem placeholder

A partir do release de placeholders, todo pendente novo cria também um ExcursaoPassageiro com cadastrado_via = convite_pendente para que a vaga apareça na listagem desde o primeiro momento. O processarCadastro (e vincularDependente/preencherPeloComprador) detecta o placeholder via pendente.vinculado_passageiro_id e atualiza os campos em vez de criar um novo passageiro. Pendentes antigos sem placeholder ainda funcionam - o serviço cria o passageiro novo e o financeiro do zero para retrocompatibilidade.

Confirmação automática quando o financeiro já está pago

Se o convidado preenche os dados depois que o pagamento da reserva já foi confirmado (ExcursaoPassageiroFinanceiro.status = pago para o placeholder), o processarCadastro muda o status do passageiro para confirmado em vez de manter pendente. Útil em reservas pré-pagas onde só faltavam os dados do convidado.

Invalidação automática do contrato

Sempre que um passageiro é vinculado/preenchido via convite, o ContratoService::invalidarAceiteGrupo é chamado em background com motivo "Passageiro vinculado via convite: {nome}". Se o comprador já tinha aceitado o contrato, o aceite é invalidado porque a composição do grupo mudou - o sistema vai pedir nova assinatura. Mesmo comportamento para vínculo de dependente e preenchimento pelo comprador.

Sem módulo de WhatsApp ativo

Quando tenant_has_addon('whatsapp-mensagens') é falso ou a instância Evolution não está conectada, o envio por WhatsApp não dispara o EnviarWhatsAppJob. O serviço só monta https://wa.me/{telefone}?text={mensagem urlencode} e registra no log para auditoria. Nesse cenário, a melhor opção operacional é Copiar o link e colar manualmente.

Quem o magic link autentica

A regra é: comprador_id se existir, senão cliente_id. Para um pax convidado/dependente o sistema autentica o titular da compra (quem paga e administra), não o convidado, porque é o titular que tem acesso real à Minha Conta. O redirect aponta direto para a reserva (/minha-conta/reservas/{codigo}) se houver order_id, ou cai na home da Minha Conta.

Token de magic link é single-use

auto_login_used_at é gravado quando o link é consumido em /auth/magic/{plain}. Tentar abrir o mesmo link de novo dá erro - gere um novo pelo modal Enviar acesso ao portal. O hash do token também rotaciona a cada gerarLinkMagico, invalidando qualquer link anterior do mesmo cliente.

Erros comuns e como resolver

  • "Cliente não encontrado." - Causa: o passageiro não tem comprador_id nem cliente_id válidos (registro órfão). Solução: editar o passageiro e vincular a um cliente real antes de tentar gerar o magic link.
  • "Esta reserva não é um convite pendente." - Causa: tentativa de prorrogar via /admin/reservas/{passageiro}/prorrogar-convite em um passageiro cujo cadastrado_via não é convite_pendente. Solução: a ação só faz sentido em placeholders de convite; para reenviar dados a um passageiro normal, use o Enviar acesso ao portal.
  • "Convite pendente não encontrado para esta reserva." - Causa: o ExcursaoPassageiroPendente foi deletado mas o placeholder ficou. Solução: cancelar o placeholder e recadastrar o pax manualmente.
  • "Link inválido." / "Este link já foi utilizado." / "Este link expirou." - Causa: token do convite vencido, consumido ou string incorreta. Solução: prorrogar pelo admin (gera novo token) e reenviar.
  • "Informe o nome completo (nome e sobrenome)." - Causa: o convidado preencheu só o primeiro nome no formulário público. Solução: pedir nome + sobrenome (mínimo 5 caracteres, pelo menos 2 partes de 2+ caracteres).
  • "CPF inválido." - Causa: dígitos verificadores não batem ou CPF formado só por números repetidos. Solução: conferir documento.
  • "Cliente sem e-mail cadastrado" (aviso no modal do link mágico) - Causa: cliente.email é nulo. Solução: cadastrar e-mail no cliente, ou enviar o link via WhatsApp/cópia manual.
  • Convite por WhatsApp não chegou - Causa: módulo whatsapp-mensagens inativo, instância Evolution desconectada, ou número formatado errado. Solução: verificar Módulos > WhatsApp Mensagens > Conexão. Sem o módulo, o link só é copiável manualmente.

Onde encontrar

  • URL canônica: /admin/excursoes/{excursao}/passageiros
  • Endpoint do magic link: POST /admin/passageiros/{passageiro}/link-magico (com ?via=email para também enviar por e-mail)
  • Endpoint de prorrogação: POST /admin/reservas/{passageiro}/prorrogar-convite
  • Formulário público do convidado: GET /convite/{token} (rota site.convite.cadastro)
  • Caminho no menu: Viagens (Excursões) > {excursão} > Passageiros
  • Permissões necessárias: ver as reservas para gerar magic link, editar as reservas para prorrogar convite, editar as viagens para editar dados do placeholder
  • Módulo necessário: nenhum para o convite básico; WhatsApp Mensagens se quiser entrega automática por WhatsApp via Evolution API

Veja também

  • Cadastrar Passageiro - alternativa quando você já tem os dados completos do passageiro e não precisa de convite.
  • Status do Passageiro - entender as mudanças de status quando o convidado conclui o cadastro.
  • Documentos e Requisitos - próximo passo depois que os dados básicos do passageiro estão preenchidos.
  • Gerenciar Passageiros na Excursão - visão geral da listagem agrupada por transporte onde os botões de convite e magic link aparecem.

Este artigo foi útil?

Obrigado pelo seu feedback!

Neste artigo

Comece a usar agora

Crie sua conta e teste grátis por 7 dias, com acesso a todas as funcionalidades.

Testar Grátis