ZAP-API
PreçosCasos de UsoBlogDocsLogin
Começar grátis
  1. Blog
  2. WhatsApp API para agências de viagem: cotação, reserva e check-in
Vertical

WhatsApp API para agências de viagem: cotação, reserva e check-in

Como agências de viagem automatizam cotações, confirmações de reserva, lembretes de check-in e suporte durante a viagem via WhatsApp API.

27 de maio de 2026·11 min de leitura·Equipe Editorial ZAP API

Cliente entra no Instagram da agência de viagens, vê foto de Maragogi, comenta "quanto custa?". Resposta padrão da indústria: "manda mensagem no WhatsApp com mais detalhes". 87% dos turistas preferem WhatsApp para cotação inicial — em pesquisa de 2025 com 4.200 viajantes brasileiros, foi o canal mais escolhido em todas as faixas etárias acima de 18 anos. Email ficou em quinto lugar.

Mas cotar pelo WhatsApp manualmente é lento (15-30 minutos por cotação) e perde escala. Esse artigo mostra como uma agência automatiza o ciclo completo de turismo via WhatsApp: cotação inicial em 90 segundos, envio de proposta em PDF, confirmação de reserva, vouchers, lembrete de check-in e suporte durante a viagem.

O fluxo da viagem em 6 etapas

  1. Cotação: cliente pergunta destino, bot coleta dados estruturados, gera proposta em segundos
  2. Apresentação: proposta enviada como PDF (type:document) com fotos
  3. Reserva: cliente confirma, bot gera link de pagamento (PIX/cartão)
  4. Vouchers: após pagamento, vouchers e itinerário enviados em PDF
  5. Pré-viagem: 48h antes, lembrete de check-in com botões
  6. Suporte na viagem: canal aberto 24/7 com escalada pra humano em emergência

Cotação automática

Cliente manda "Quero viagem pra Maragogi em junho, casal, 5 dias". Bot extrai entidades estruturadas (destino, mês, número de viajantes, duração) e consulta sua API de inventário (CVC, Decolar internamente, ou seu próprio sistema).

import axios from "axios";

const ZAP = axios.create({
  baseURL: "https://api.zap-api.tech/v1",
  headers: { Authorization: `Bearer ${process.env.ZAP_TOKEN}` },
});

async function processarCotacao(phone, texto, instanceId) {
  // 1. Extrai entidades via NLP (use OpenAI, Claude ou seu próprio modelo)
  const entidades = await extrairEntidades(texto);
  // ex: { destino: "Maragogi", mes: "2026-06", viajantes: 2, duracao: 5 }

  if (!entidades.destino) {
    await replyText(phone, instanceId, "Pra onde você quer ir? (ex: Maragogi, Bariloche, Salvador)");
    return;
  }

  // 2. Busca pacotes no inventário
  const pacotes = await buscarPacotes({
    destino: entidades.destino,
    mes: entidades.mes,
    viajantes: entidades.viajantes || 2,
    duracao: entidades.duracao || 5,
  });

  if (pacotes.length === 0) {
    await replyText(
      phone,
      instanceId,
      `Não encontrei pacotes pra ${entidades.destino} em ${entidades.mes}. Quer testar outras datas?`
    );
    return;
  }

  // 3. Envia top 3 pacotes como cards (lista interativa)
  await ZAP.post(`/instances/${instanceId}/messages`, {
    to: phone,
    type: "list",
    list: {
      header: "Pacotes encontrados",
      body: `${pacotes.length} opções pra ${entidades.destino}`,
      footer: "Escolha uma para ver detalhes",
      button: "Ver pacotes",
      sections: [
        {
          title: "Opções",
          rows: pacotes.slice(0, 3).map((p) => ({
            id: `pacote_${p.id}`,
            title: `${p.nomeHotel} - R$ ${p.preco}`,
            description: `${p.duracao} dias, ${p.regime}`,
          })),
        },
      ],
    },
  });
}

Envio da proposta em PDF

Cliente clicou em um pacote? Gere PDF com proposta detalhada (logo, fotos, condições) e envie via type:document.

import PDFDocument from "pdfkit";
import fs from "fs";

async function gerarPropostaPDF(pacote, cliente) {
  const filename = `/tmp/proposta_${pacote.id}_${Date.now()}.pdf`;
  const doc = new PDFDocument();
  doc.pipe(fs.createWriteStream(filename));

  doc.image("logo.png", 50, 30, { width: 100 });
  doc.fontSize(20).text(`Proposta: ${pacote.nomeHotel}`, 50, 150);
  doc.fontSize(12).text(`Cliente: ${cliente.nome}`);
  doc.text(`Destino: ${pacote.destino}`);
  doc.text(`Período: ${pacote.checkin} a ${pacote.checkout}`);
  doc.text(`Regime: ${pacote.regime}`);
  doc.text(`Total: R$ ${pacote.preco}`);
  doc.moveDown();
  doc.text("Inclui:");
  pacote.inclusoes.forEach((i) => doc.text(`• ${i}`));

  doc.moveDown();
  doc.text("Condições de pagamento:");
  doc.text("• PIX à vista: 5% de desconto");
  doc.text("• Cartão em 6x sem juros");

  doc.end();

  await new Promise((r) => doc.on("end", r));
  return filename;
}

async function enviarProposta(phone, instanceId, pacote, cliente) {
  const pdf = await gerarPropostaPDF(pacote, cliente);
  // Upload pra storage e pega URL pública (S3, Cloudinary, etc)
  const url = await uploadPdfPublico(pdf);

  await ZAP.post(`/instances/${instanceId}/messages`, {
    to: phone,
    type: "document",
    document: {
      url,
      filename: `Proposta_${pacote.nomeHotel.replace(/\s/g, "_")}.pdf`,
      caption: `Sua proposta personalizada! Total: R$ ${pacote.preco}. Quer fechar agora?`,
    },
  });

  // Em seguida, oferece botões de ação
  await ZAP.post(`/instances/${instanceId}/messages`, {
    to: phone,
    type: "buttons",
    buttons: {
      text: "O que você decide?",
      buttons: [
        { id: `fechar_${pacote.id}`, text: "Fechar agora" },
        { id: `negociar_${pacote.id}`, text: "Negociar" },
        { id: `outro_${pacote.id}`, text: "Ver outros" },
      ],
    },
  });
}

Reserva e pagamento

// Webhook recebe button "fechar_X"
case "fechar":
  const pacoteId = buttonId.split("_")[1];
  const pacote = await db.pacote.findUnique({ where: { id: pacoteId } });

  // Cria reserva no inventário
  const reserva = await criarReserva(pacote, cliente);

  // Gera cobrança PIX (Woovi/Asaas/etc)
  const cobranca = await criarCobranca({
    valor: pacote.preco * 100,
    correlationId: `reserva_${reserva.id}`,
    descricao: `Pacote ${pacote.nomeHotel}`,
  });

  await ZAP.post(`/instances/${instanceId}/messages`, {
    to: phone,
    type: "text",
    text: {
      body:
        `Reserva criada (${reserva.codigo})!\n\n` +
        `Pague o PIX abaixo nas próximas 2h pra confirmar:\n\n` +
        `${cobranca.brCode}\n\n` +
        `Após pago, vouchers e itinerário chegam em até 5 minutos.`,
    },
  });
  break;

Vouchers e itinerário

Webhook do gateway de pagamento confirma. Sistema gera vouchers (hotel, transfer, passeios) e envia em sequência:

app.post("/webhooks/pagamento", async (req, res) => {
  res.status(200).send("ok");
  if (req.body.event !== "PAYMENT_COMPLETED") return;

  const reservaId = req.body.correlationID.replace("reserva_", "");
  const reserva = await db.reserva.findUnique({
    where: { id: reservaId },
    include: { cliente: true, pacote: true },
  });

  // Gera vouchers (hotel, transfer, passeios)
  const vouchers = await gerarVouchers(reserva);

  // Envia itinerário consolidado
  await ZAP.post(`/instances/${process.env.INSTANCE_ID}/messages`, {
    to: reserva.cliente.telefone,
    type: "document",
    document: {
      url: vouchers.itinerarioUrl,
      filename: `Itinerario_${reserva.codigo}.pdf`,
      caption:
        `Pagamento confirmado!\n\n` +
        `Aqui está seu itinerário completo. Boas viagens!`,
    },
  });

  // Envia vouchers individuais como anexos separados
  for (const v of vouchers.individuais) {
    await ZAP.post(`/instances/${process.env.INSTANCE_ID}/messages`, {
      to: reserva.cliente.telefone,
      type: "document",
      document: {
        url: v.url,
        filename: `Voucher_${v.tipo}.pdf`,
      },
    });
    await sleep(1500); // throttle leve
  }
});

Lembrete de check-in 24h antes

// Cron diário às 12h
cron.schedule("0 12 * * *", async () => {
  const amanha = new Date();
  amanha.setDate(amanha.getDate() + 1);
  amanha.setHours(0, 0, 0, 0);
  const limite = new Date(amanha);
  limite.setHours(23, 59, 59);

  const reservas = await db.reserva.findMany({
    where: {
      checkin: { gte: amanha, lte: limite },
      status: "confirmada",
      lembrete24h: false,
    },
    include: { cliente: true, pacote: true },
  });

  for (const r of reservas) {
    await ZAP.post(`/instances/${process.env.INSTANCE_ID}/messages`, {
      to: r.cliente.telefone,
      type: "buttons",
      buttons: {
        text:
          `Olá ${r.cliente.primeiroNome}! Amanhã é seu check-in em ${r.pacote.destino}.\n\n` +
          `Hotel: ${r.pacote.nomeHotel}\n` +
          `Endereço: ${r.pacote.endereco}\n` +
          `Check-in a partir de ${r.pacote.checkinHora}\n\n` +
          `Tudo certo?`,
        buttons: [
          { id: `checkin_ok_${r.id}`, text: "Tudo certo" },
          { id: `checkin_duvida_${r.id}`, text: "Tenho dúvida" },
          { id: `checkin_problema_${r.id}`, text: "Tenho problema" },
        ],
      },
    });
    await db.reserva.update({ where: { id: r.id }, data: { lembrete24h: true } });
  }
});

Suporte durante a viagem

Durante a viagem, cliente pode ter problema (voo atrasou, hotel overbooking, transfer não chegou). Roteamento humano com escalonamento:

// Detecção de palavras-chave de emergência
const PALAVRAS_EMERGENCIA = ["emergencia", "urgente", "perdi", "roubaram", "hospital", "policia"];

app.post("/webhook/zap", async (req, res) => {
  res.status(200).send("ok");
  if (req.body.type !== "message.received") return;

  const texto = (req.body.message.body?.text || "").toLowerCase();
  const phone = req.body.message.from;
  const reservaAtiva = await buscarReservaAtiva(phone);

  // Se cliente tem reserva em curso e mandou palavra de emergência
  if (reservaAtiva && PALAVRAS_EMERGENCIA.some((p) => texto.includes(p))) {
    // Escala IMEDIATAMENTE pra atendente humano de plantão
    await alertarPlantao({
      cliente: reservaAtiva.cliente,
      mensagem: texto,
      destino: reservaAtiva.pacote.destino,
      telefoneCliente: phone,
    });
    await replyText(
      phone,
      req.body.instanceId,
      "Recebemos sua mensagem. Um atendente entra em contato em até 5 minutos."
    );
    return;
  }

  // Senão, fluxo normal
  // ...
});

Casos práticos

Agência boutique (15 reservas/mês)

1 instância, fluxo manual + bot. Cotação automática poupa 30 min/cotação. ROI: +6 vendas adicionais/mês porque atende mais leads simultaneamente.

Operadora média (300 reservas/mês)

3 instâncias (cotação, reserva, suporte). Bot fecha 60% das vendas sem intervenção humana. Atendentes humanos focam em casos premium e resolução de problemas em viagem.

OTA (Online Travel Agency) com 5k reservas/mês

15 instâncias com pool por região (uma específica pra Nordeste, outra pra internacional). Integração direta com GDS Amadeus + bot multi-idioma (PT, EN, ES). Suporte 24/7 cobre fuso horário internacional.

FAQ

Como atender múltiplos idiomas?

Detecte idioma pela primeira mensagem (use franc-min ou OpenAI). Salve em cliente.idiomaPreferido. Templates de mensagem têm variantes em PT/EN/ES. Bot responde sempre no idioma detectado.

E se o cliente está em fuso horário diferente (Europa, Ásia)?

Não envie lembretes em horário Brasil. Use cliente.timezone (preencha pelo destino + horário do voo). Cron de 12h Brasil vira 12h destino. Suporte humano em plantão noturno (terceirizado ou rodízio interno).

Emergência fora do horário comercial?

Plantão 24/7 obrigatório pra agência que vende viagem. Fluxo: bot detecta emergência → tenta resolver com FAQ pré-cadastrado (cancelamento de voo: link da cia, rebooking automático) → escala pra humano de plantão (notificação push no celular dele) → SLA de resposta 5min.

Integração com GDS (Amadeus, Sabre)?

Use middleware Node que conecta com SOAP/XML do GDS de um lado e expõe REST pro seu bot do outro. Bibliotecas: @amadeus/amadeus-node, node-sabre. Latência 800ms-2s por consulta — exiba "buscando..." no WhatsApp pra cliente saber que está rodando.

Como pagar comissão de fornecedor?

Webhook do gateway de pagamento dispara: split automático Woovi/PIX, ou rotina mensal de transferência via gateway com NF-e. Comissão típica: 8-15% do valor da reserva. Reconciliação mensal por contador.

Pronto para automatizar cotação e reserva via WhatsApp? A ZAP API atende agências de turismo de pequeno e médio porte com sandbox pra testar fluxos antes de migrar volume real. Criar conta grátis e teste com 7 dias.

Experimente a ZAP API gratuitamente

7 dias de trial sem precisar de cartão. A partir de R$29/mês*.

Criar instância grátis
EE
Equipe Editorial ZAP APIRevisão técnica

Desenvolvedores e especialistas em integrações WhatsApp. Todo conteúdo passa por revisão técnica para garantir precisão e aplicabilidade.

Ver perfil completoDocumentaçãoTrial grátis

Leia também

Vertical · 16 de jun. de 2026 · 10 min

WhatsApp API para petshops e clínicas veterinárias: lembretes, vacina e recompra

Como petshops e veterinárias usam a API de WhatsApp para reduzir faltas e aumentar recorrência: lembrete de banho e tosa, vacina em dia, recompra de ração e pós-consulta.

Vertical · 17 de jun. de 2026 · 10 min

WhatsApp API para concessionárias e oficinas: revisão, orçamento e pós-venda

Fluxos de WhatsApp via API para concessionárias e oficinas mecânicas: lembrete de revisão programada, aprovação de orçamento, status do veículo, recall e funil de vendas.

Vertical · 18 de jun. de 2026 · 10 min

WhatsApp API para salões de beleza e barbearias: acabe com o no-show

Como salões e barbearias usam a API de WhatsApp para derrubar o no-show e fidelizar: confirmação automática, lembrete na véspera, recorrência no intervalo certo e horário vago.

Vertical · 29 de mai. de 2026 · 11 min

WhatsApp API para academias: renovação, presença e motivação

Como academias e estúdios fitness usam WhatsApp API para lembrar renovações, confirmar aulas, enviar treinos e manter alunos engajados para reduzir churn.

Tópicos:Chatbots com IAE-commerceAPI WhatsApp

Explore também

Casos de usoWhatsApp API por segmentoComparativoZAP API vs alternativasPreçosPlanos e o que está inclusoGlossárioTermos técnicos de WhatsApp API
ZAP-API

API REST para WhatsApp com webhooks assinados, Meta Pixel/CAPI e compliance LGPD. Sem aprovação da Meta.

Status operacional🇧🇷 Feito no Brasil

Produto

  • Preços
  • Casos de uso
  • Comparativo
  • Trial grátis
  • Dashboard

Recursos

  • Documentação
  • Blog
  • Glossário
  • RSS Feed

Empresa

  • Sobre
  • Imprensa
  • Termos de uso
  • Privacidade
  • Criar conta
  • Login

Contato

  • [email protected]
  • [email protected]
  • Resposta em até 24h úteis
© 2026 ZAP-API — Todos os direitos reservados·CNPJ 42.130.949/0001-56·Termos·Privacidade

Desenvolvido por PreviusIA