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. 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. 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. 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. 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. 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.

ObjetivoEventoTelefone e links no payload
Pagamento confirmadomyeduzz.invoice_paiddata.buyer.cellphone, phone e phone2; data.paidAt; data.paymentMethod (bankslip, pix, creditCard...)
Fatura em abertomyeduzz.invoice_openeddata.buyer.cellphone; data.saleRecoveryUrl; data.bankslipUrl
Fatura expiradamyeduzz.invoice_expiredmesmo envelope de fatura; use para o último lembrete
Carrinho abandonadosun.cart_abandonmentdata.customer.phone; data.saleRecoveryUrl; data.productId
Estorno e disputamyeduzz.invoice_refunded, myeduzz.invoice_chargebackPara 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.