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
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
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
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
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
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.
| Objetivo | Evento | Telefone e dados úteis |
|---|---|---|
| Boas-vindas | PURCHASE_APPROVED | data.buyer.checkout_phone e checkout_phone_code, data.buyer.first_name, data.product.name, purchase.price.value |
| Boleto não pago | PURCHASE_BILLET_PRINTED | data.purchase.payment.billet_url e billet_barcode quando o pagamento é boleto |
| Carrinho abandonado | PURCHASE_OUT_OF_SHOPPING_CART | data.buyer.phone (com código do país), data.buyer.name, data.product.name, data.offer.code |
| Atraso e cancelamento | PURCHASE_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.
