Faturas, Pix e boleto
Eduzz no WhatsApp: fatura paga, boleto e carrinho com o x-signature validado
A Eduzz envia webhooks do MyEduzz e do checkout, cada um com id, nome do evento, bloco data e sentDate, e assina cada envio com o cabeçalho x-signature, um HMAC-SHA256 do corpo. A ZapZap tem a Eduzz no assistente Recuperar vendas: gera a URL do webhook e o fluxo de mensagem, e valida o x-signature quando você informa a chave secreta.
Atualizado em
Por que conectar
A Eduzz tem dois eventos que facilitam a vida de quem recupera venda: a fatura aberta (invoice_opened) já traz a URL de recuperação (saleRecoveryUrl) e o link do boleto (bankslipUrl), e o carrinho abandonado (cart_abandonment) traz a URL do checkout para a pessoa voltar. Com isso a mensagem não precisa de busca extra: o link já está no payload. Mande só para quem iniciou uma compra, com 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 uma chave de acesso na Eduzz
No Console de desenvolvedor da Eduzz, abra a tela de Segurança do webhook e gere uma chave. Você pode cadastrar quantas quiser, uma por destino, o que ajuda quando o mesmo evento vai para sistemas diferentes. A Eduzz assina cada mensagem com essa chave e envia o resultado no cabeçalho x-signature.
- 2
Crie a configuração do webhook
No menu Configurações, clique em Nova configuração: nome, chave de acesso, URL para envio dos dados e os eventos desejados. A Eduzz recomenda testar a URL, que precisa responder 200 a 299. Há um campo para limitar o máximo de eventos em paralelo para a sua URL, útil em lançamento. O webhook envia só eventos dos produtos da conta com a qual você está logado.
- 3
Gere a URL na ZapZap e salve a chave
Em Fluxos, Recuperar vendas, escolha Eduzz, o objetivo e o número, e cole a URL gerada (https://api.zapzapapi.com/api/webhooks/flow/{segredo}) na Eduzz. Salve a chave secreta no assistente: a ZapZap calcula o HMAC-SHA256 do corpo bruto, aceita o resultado em hexadecimal ou base64 e recusa com 401 o que não bater.
- 4
Responda ao ping e confira o telefone
Ao ativar ou verificar a URL, a Eduzz manda um evento ping, com data.message igual a ping, e espera um 2xx. Na ZapZap, o ping não traz telefone e responde triggered: 0, o que é esperado. Depois dispare um evento real de teste e veja, na amostra do webhook, qual campo foi detectado como telefone (data.buyer.cellphone, data.buyer.phone ou data.customer.phone no carrinho).
- 5
Use os links do payload na mensagem
No editor do fluxo, o texto de partida usa {nome} e {produto}. Para incluir o link de recuperação ou do boleto, o caminho é um endpoint seu, que lê data.saleRecoveryUrl ou data.bankslipUrl e envia pela API da ZapZap, como no exemplo abaixo.
Exemplo
// Valida o x-signature da Eduzz e manda o link de recuperação pela ZapZap
import crypto from 'node:crypto';
import express from 'express';
const app = express();
app.post('/eduzz', express.raw({ type: 'application/json' }), async (req, res) => {
const esperado = crypto.createHmac('sha256', process.env.EDUZZ_CHAVE).update(req.body).digest('hex');
const recebido = String(req.get('x-signature') || '');
const ok = recebido.length === esperado.length && crypto.timingSafeEqual(Buffer.from(recebido), Buffer.from(esperado));
if (!ok) return res.sendStatus(401);
const ev = JSON.parse(req.body.toString('utf8'));
res.sendStatus(200);
if (ev.event === 'ping' || (await jaProcessado(ev.id))) return; // sua função: UNIQUE no id
const d = ev.data;
const fone = String(d.buyer?.cellphone || d.buyer?.phone || d.customer?.phone || '').replace(/\D/g, '');
const link = d.saleRecoveryUrl;
if (!fone || !link) 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! Seu pedido ficou pela metade. Retome por aqui: ' + link }),
});
});Ilustrativo. Os campos e endpoints exatos estão na documentação.
Eventos da Eduzz que viram mensagem
A referência pública da Eduzz lista dezenas de eventos. Os da tabela são os que mais se encaixam em cobrança e recuperação, com o campo de telefone que a referência documenta.
| Objetivo | Evento | Telefone e links no payload |
|---|---|---|
| Pagamento confirmado | myeduzz.invoice_paid | data.buyer.cellphone, phone e phone2; data.paidAt; data.paymentMethod (bankslip, pix, creditCard...) |
| Fatura em aberto | myeduzz.invoice_opened | data.buyer.cellphone; data.saleRecoveryUrl; data.bankslipUrl |
| Fatura expirada | myeduzz.invoice_expired | mesmo envelope de fatura; use para o último lembrete |
| Carrinho abandonado | sun.cart_abandonment | data.customer.phone; data.saleRecoveryUrl; data.productId |
| Estorno e disputa | myeduzz.invoice_refunded, myeduzz.invoice_chargeback | Para retirar acesso, não para vender |
x-signature na prática
Segundo a Eduzz, o x-signature é hmac('sha256', chave_secreta, corpo_da_requisição); se o resultado for idêntico ao do cabeçalho, a mensagem é legítima. A documentação não diz se o resultado vem em hexadecimal ou base64, por isso a ZapZap aceita os dois. No seu endpoint, calcule sobre o corpo cru (os bytes recebidos), antes de qualquer parse do JSON, e compare em tempo constante. Recalcular sobre um JSON reserializado muda espaços e ordem de chaves e a assinatura deixa de bater.
- Chave: uma por destino. Se um dia a chave vazar, gere outra e aponte a configuração para ela.
- Replay: o envelope tem sentDate, mas a documentação não diz que ele entra na assinatura. Use o id do evento para descartar repetidos.
- Paralelismo: o limite de eventos em paralelo da configuração protege o seu servidor em lançamento. A ZapZap aceita 120 requisições por minuto por webhook; acima disso responde 429.
Quando NÃO usar o assistente
O assistente monta mensagens com nome e produto. Se você quer colocar o saleRecoveryUrl ou o bankslipUrl no texto, ou diferenciar a mensagem por data.paymentMethod, use um endpoint seu ou o n8n. Também não use eventos de estorno e chargeback para mensagem de marketing: o contato por esses eventos é para tratar o problema do cliente. E não mande para quem nunca iniciou uma compra; isso é prospecção e precisa de outra base.
Fontes e data da conferência
Eventos, campos de telefone, saleRecoveryUrl, bankslipUrl, assinatura x-signature, criação da configuração e evento ping foram conferidos em 29/10/2026 no Eduzz Developer Hub (developers.eduzz.com), nas páginas de Webhook (Criando um webhook, Segurança, Evento de Verificação) e na especificação OpenAPI pública dos webhooks. O comportamento da ZapZap vem do código do produto em produção.
Perguntas frequentes
Como a Eduzz prova que o webhook é dela?
Enviando o cabeçalho x-signature, um HMAC-SHA256 do corpo da requisição calculado com a chave secreta que você cadastrou. Você recalcula sobre o corpo cru e compara; se for igual, a mensagem é legítima. A ZapZap faz essa conferência quando você salva a chave no assistente.
Por que recebo um evento ping sem telefone?
O ping serve para verificar a URL: ele tem data.message igual a ping e espera um 2xx. Não é uma venda. Na ZapZap ele responde triggered: 0, o que é normal, e no seu endpoint você deve ignorá-lo.
Qual campo tem o celular do comprador?
Nos eventos de fatura, a referência documenta data.buyer.cellphone, data.buyer.phone e data.buyer.phone2. No carrinho abandonado o campo é data.customer.phone. A ZapZap prefere o celular quando ambos existem, mas confira na amostra qual foi detectado.
Dá para mandar o link de recuperação da venda?
O payload da fatura aberta e do carrinho abandonado traz data.saleRecoveryUrl. Para colocar esse link no texto, use um endpoint seu ou o n8n, que leem o campo e chamam a API da ZapZap. O texto do assistente é fixo com nome e produto.
Meu servidor não aguenta o volume de um lançamento. E agora?
A configuração do webhook na Eduzz tem um limite de eventos enviados em paralelo para a sua URL. Defina um valor que o seu servidor aguente e deixe a fila interna cuidar do resto. Responda 2xx rápido e envie o WhatsApp em segundo plano.
A Eduzz manda eventos de outras contas?
Não. O webhook envia apenas eventos dos produtos pertencentes à conta usada na configuração. Se faltar evento, confira se você está logado na conta que tem os produtos.
Posso usar isso para lembrar quem não pagou há semanas?
Com cuidado. O lembrete de fatura expirada deve ser curto, respeitoso e com um jeito de parar de receber. Cobrança que expõe ou constrange o devedor é problema jurídico além de risco de bloqueio, e a ZapZap, canal não oficial, não garante que o número não será limitado.
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.
