Infoprodutos e produtores

Hotmart no WhatsApp: boas-vindas, boleto e carrinho abandonado com webhook

A Hotmart notifica o seu sistema por webhook a cada evento de venda. Na versão 2.0.0, o envelope traz id, creation_date, event, version e data, e o token de segurança (hottok) chega no cabeçalho X-HOTMART-HOTTOK. A ZapZap tem a Hotmart no assistente Recuperar vendas, em Fluxos: ele gera a URL do webhook e o fluxo de mensagem, e valida o hottok quando você o informa.

Atualizado em

Por que conectar

Produtor que vende pela Hotmart vive de três mensagens: a de boas-vindas quando a compra é aprovada, o lembrete de quem imprimiu o boleto e não pagou, e o chamado de quem preencheu o checkout e saiu. A Hotmart tem evento para os três (PURCHASE_APPROVED, PURCHASE_BILLET_PRINTED e PURCHASE_OUT_OF_SHOPPING_CART), mas há uma pegadinha de telefone que decide se o fluxo dispara ou não, explicada abaixo. Mande só para comprador ou lead que deixou o contato com você, e dê um jeito de parar de receber. A ZapZap conecta números por um canal não oficial e gerenciado. São R$15 por número ativo/mês, pré-pago, com crédito de boas-vindas ao criar a conta, sujeito à campanha vigente.

Passo a passo

  1. 1

    Crie a configuração de webhook na Hotmart em 2.0.0

    Na Hotmart, abra Ferramentas e depois Webhook e crie uma configuração. Escolha a versão 2.0.0 (a 1.0.0 está descontinuada e só quem já tinha configuração nela consegue criar novas), selecione o produto e os eventos, e cole a URL. A Hotmart guarda o histórico dos eventos por até 60 dias, o que ajuda a reenviar um teste.

  2. 2

    Gere a URL na ZapZap e escolha o objetivo

    Em Fluxos, clique em Recuperar vendas, escolha Hotmart, o objetivo e o número. A URL, no formato https://api.zapzapapi.com/api/webhooks/flow/{segredo}, é a que vai na Hotmart. O fluxo sai ligado e vinculado ao número escolhido, com textos de partida que usam {nome} e {produto}.

  3. 3

    Informe o hottok para validar a origem

    O hottok é um token único por conta, em Ferramentas > Webhook > Autenticação. A Hotmart o envia no cabeçalho X-HOTMART-HOTTOK de todas as requisições e recomenda validá-lo antes de processar. Salve-o no assistente e a ZapZap passa a recusar com 401 o evento cujo hottok não bate. Para trocar o token é preciso falar com o suporte da Hotmart.

  4. 4

    Resolva o telefone antes do primeiro disparo

    No carrinho abandonado, data.buyer.phone traz o telefone com o código do país. Nos eventos de compra, data.buyer.checkout_phone traz o telefone do checkout e, para comprador brasileiro, o DDD vem separado em data.buyer.checkout_phone_code. A ZapZap só aceita como telefone um valor de 10 a 13 dígitos; um número de 9 dígitos sem DDD não é detectado e o fluxo responde triggered: 0. Faça um teste e confira o campo detectado no editor do webhook.

  5. 5

    Teste, leia o histórico e ajuste

    Dispare um teste pela Hotmart, veja na ZapZap a amostra recebida e na Hotmart o histórico do evento. Se o telefone não vier completo, o caminho é um endpoint seu: você concatena DDD e número, e chama a API da ZapZap direto, como no exemplo abaixo.

Exemplo

// Quando o telefone vem sem DDD: seu endpoint junta e envia pela ZapZap
import express from 'express';
const app = express();

app.post('/hotmart', express.json(), async (req, res) => {
  if (req.get('X-HOTMART-HOTTOK') !== process.env.HOTMART_HOTTOK) return res.sendStatus(401);
  const { id, event, data } = req.body;
  res.sendStatus(200);
  if (event !== 'PURCHASE_APPROVED') return;
  if (await jaProcessado(id)) return; // sua função: UNIQUE no id do evento

  const b = data.buyer;
  const fone = String((b.checkout_phone_code || '') + (b.checkout_phone || '')).replace(/\D/g, '');
  if (fone.length < 10) return;

  await fetch('https://api.zapzapapi.com/api/v1/' + process.env.ZAPZAP_INSTANCE + '/send/text', {
    method: 'POST',
    headers: {
      'x-api-key': process.env.ZAPZAP_API_KEY,
      'x-api-secret': process.env.ZAPZAP_API_SECRET,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      number: fone.startsWith('55') ? fone : '55' + fone,
      text: 'Oi, ' + b.first_name + '! Sua compra de ' + data.product.name + ' foi aprovada. Qualquer dúvida, é só responder aqui.',
    }),
  });
});

Ilustrativo. Os campos e endpoints exatos estão na documentação.

Eventos 2.0.0 que importam e onde está o telefone

Os nomes abaixo são os da documentação oficial da versão 2.0.0. O campo purchase.status acompanha o evento e ajuda a filtrar, por exemplo WAITING_PAYMENT ou PRINTED_BILLET.

ObjetivoEventoTelefone e dados úteis
Boas-vindasPURCHASE_APPROVEDdata.buyer.checkout_phone e checkout_phone_code, data.buyer.first_name, data.product.name, purchase.price.value
Boleto não pagoPURCHASE_BILLET_PRINTEDdata.purchase.payment.billet_url e billet_barcode quando o pagamento é boleto
Carrinho abandonadoPURCHASE_OUT_OF_SHOPPING_CARTdata.buyer.phone (com código do país), data.buyer.name, data.product.name, data.offer.code
Atraso e cancelamentoPURCHASE_DELAYED, PURCHASE_CANCELED, PURCHASE_REFUNDEDÚteis em assinatura; confira o purchase.status de cada um

O que a documentação diz e o que você precisa testar

O evento de carrinho abandonado é gerado quando a pessoa preenche nome ou e-mail na página de pagamento e sai; a Hotmart faz essa verificação a cada 30 minutos, então a mensagem não chega no segundo em que o cliente fecha a aba. Considere esse atraso ao escrever o texto e ao escolher quando mandar o segundo lembrete.

Para Pix, a documentação lista os campos pix_code, pix_qrcode e pix_expiration_date dentro de purchase.payment, mas a lista de eventos não tem um nome próprio para Pix gerado. Teste na sua conta qual evento chega quando alguém escolhe Pix e não paga, antes de prometer essa mensagem no seu fluxo.

O produto de afiliado exige que o produtor libere os dados do comprador; sem isso, o telefone não vem.

Segurança, duplicidade e o que a Hotmart faz com URL com erro

  • hottok: valide em toda requisição. Ele não assina o corpo, é um token fixo; trate-o como segredo e não o registre em log.
  • Duplicidade: cada evento tem um id único. Grave-o e ignore repetições. A ZapZap, por sua vez, não dispara o mesmo fluxo duas vezes para o mesmo telefone em 10 minutos.
  • Datas: creation_date e approved_date vêm em milissegundos desde 1970 (UTC). Converta antes de comparar com a hora local.
  • URL com erro: a central de ajuda da Hotmart informa que a configuração é desativada se a URL cadastrada retornar erro. Acompanhe o status da sua configuração depois de um deploy.
  • Limite da ZapZap: 120 requisições por minuto por webhook; acima disso a resposta é 429.

Quando NÃO usar o assistente da ZapZap

Não use o assistente se o telefone do checkout chega sem DDD no seu produto e você não quer ou não pode alterar o checkout para exigir o número completo: nesse caso o campo não é detectado. Também não use para disparar para a base inteira de compradores antigos, que nunca foi avisada de que receberia WhatsApp: isso é campanha, não notificação, e pede consentimento. Para regras próprias (consultar sua área de membros, gerar link de acesso), prefira um endpoint seu, com o exemplo acima.

Fontes e data da conferência

Nomes de evento, campos do payload, cabeçalho X-HOTMART-HOTTOK, versão 2.0.0, regra de 30 minutos do carrinho e histórico de 60 dias foram conferidos em 29/10/2026 na documentação oficial da Hotmart (developers.hotmart.com), nas páginas Request events e Cart abandonment event da versão 2.0.0 e Using Webhooks, e na central de ajuda da Hotmart. O comportamento da ZapZap vem do código do produto em produção.

Perguntas frequentes

Onde a Hotmart envia o hottok na versão 2.0.0?

No cabeçalho HTTP X-HOTMART-HOTTOK de todas as requisições. A documentação recomenda validar antes de processar. Na versão 1.0.0, descontinuada, o hottok vinha como campo do corpo.

Por que o fluxo não dispara em PURCHASE_APPROVED?

O motivo mais provável é o telefone. Em data.buyer.checkout_phone o número de comprador brasileiro pode vir sem DDD, que fica em checkout_phone_code. A ZapZap só aceita telefone de 10 a 13 dígitos, então o fluxo responde triggered: 0. Teste e, se for o caso, junte os dois campos num endpoint seu.

Com que atraso chega o evento de carrinho abandonado?

A Hotmart verifica os carrinhos a cada 30 minutos. O envio começa quando a pessoa preenche nome ou e-mail na página de pagamento. Planeje a mensagem para esse ritmo e evite escrever como se o cliente tivesse acabado de sair.

Existe evento de Pix gerado?

A lista de eventos da versão 2.0.0 que conferimos não tem um nome próprio para Pix gerado. O payload traz pix_code, pix_qrcode e pix_expiration_date em purchase.payment. Teste na sua conta qual evento chega quando alguém escolhe Pix e não paga.

Posso usar a versão 1.0.0 do webhook?

A própria Hotmart diz que a 1.0.0 foi descontinuada e que só quem já tinha configuração nela pode criar novas. Para uma integração nova, use a 2.0.0. O envelope muda: campos como email e phone_number saem do primeiro nível e passam a ficar dentro de data.buyer.

A Hotmart reenvia o evento se meu servidor falhar?

A documentação consultada não detalha a política de retentativas, mas os eventos têm id único e ficam no histórico por até 60 dias. Trate cada id como chave de idempotência e acompanhe o status da configuração, porque a central de ajuda diz que ela é desativada se a URL retornar erro.

Posso falar com todo mundo que já comprou?

Não por este caminho. Notificação de uma compra atual é uma coisa; campanha para a base antiga é outra, e pede consentimento e cuidado com o ritmo. A ZapZap é um canal não oficial e não elimina o risco de bloqueio.

Comece agora

Crie sua conta, conecte um número em minutos e teste a API com aquecimento e anti-bloqueio. R$15 por número ativo/mês, pré-pago, sem fidelidade.