Documentação Painel do produtor →

Webhooks

Conecte qualquer área de membros ao Destpay. Avisamos o seu sistema quando o aluno deve ganhar ou perder acesso — sem você precisar consultar nada.

Esta página descreve os webhooks de saída (Destpay → seu sistema).

Configurar

  1. No painel, vá em Integrações → Área de membros → Configurar webhook.
  2. Informe a URL que vai receber os avisos e escolha os eventos e produtos que interessam. Deixar em branco significa todos.
  3. Guarde o secret gerado. Ele aparece uma única vez e serve para você conferir que a chamada veio mesmo de nós.
  4. Use o botão Testar para receber um ping e validar a integração antes de ir para produção.

Enviamos um POST com corpo JSON. Se o seu sistema responder 2xx, a entrega é concluída. Qualquer outra resposta — ou timeout de 10 segundos — entra em reentrega automática.

Validar a assinatura

Todo request traz estes cabeçalhos:

CabeçalhoConteúdo
x-destpay-eventNome do evento (ex.: aluno.liberado)
x-destpay-timestampUnix timestamp, em segundos, de quando assinamos
x-destpay-signatureHMAC-SHA256 em hexadecimal
x-destpay-deliveryID da entrega — use para idempotência e suporte

A assinatura é o HMAC-SHA256 de timestamp + "." + corpo, usando o secret do seu endpoint como chave.

Assine o corpo cru, exatamente como recebido — não o JSON reserializado. Reserializar muda espaços e ordem de chaves, e a assinatura não bate. É o erro mais comum nesse tipo de integração.

import crypto from 'node:crypto'

function validar(req, secret) {
  const ts = req.headers['x-destpay-timestamp']
  const assinatura = req.headers['x-destpay-signature']
  const corpoCru = req.rawBody // string, não req.body já parseado

  const esperado = crypto
    .createHmac('sha256', secret)
    .update(`${ts}.${corpoCru}`)
    .digest('hex')

  // comparação em tempo constante evita vazar informação por timing
  const ok = crypto.timingSafeEqual(
    Buffer.from(esperado),
    Buffer.from(assinatura),
  )

  // rejeita requisições antigas (proteção contra replay)
  const recente = Math.abs(Date.now() / 1000 - Number(ts)) < 300
  return ok && recente
}

Formato do envelope

Todo evento chega no mesmo formato:

{
  "event": "aluno.bloqueado",
  "enviado_em": "2026-07-31T03:05:05.178Z",
  "dados": { }
}

Ciclo do aluno

Estes são os eventos que a área de membros precisa. Todos carregam o mesmo bloco dados.

EventoQuando disparaO que fazer
aluno.liberadoPagou a 1ª parcela e virou cliente ativoLiberar acesso
aluno.bloqueadoUma parcela venceu e não foi pagaBloquear acesso
aluno.reativadoO inadimplente regularizouDevolver acesso
aluno.concluidoPagou todas as parcelasManter acesso; marcar como concluído
aluno.canceladoO parcelamento foi canceladoRevogar acesso

Exemplo de payload

{
  "event": "aluno.bloqueado",
  "enviado_em": "2026-07-31T03:05:05.178Z",
  "dados": {
    "cliente": {
      "id": "e65436b7-5fc0-44cf-a9ff-a5841e3482ae",
      "nome": "Ana Paula Ferreira",
      "email": "ana@example.com",
      "cpf": "39053344705",
      "telefone": "11988887777",
      "status": "inadimplente",
      "status_anterior": "ativo"
    },
    "produto": {
      "campanha_id": "38965ec9-2981-4bef-bdc9-6a513a77fab4",
      "campanha": "Turma Webhook",
      "nome": "Mentoria Premium"
    },
    "empresa_id": "c7c4ca4b-e184-4a2f-a557-e5ccdf9f69c2"
  }
}

Como identificar o aluno: use cliente.email ou cliente.cpf. O cliente.id é estável e único no Destpay — se puder guardá-lo do seu lado, é a chave mais segura.

Como saber qual produto liberar: use produto.campanha_id (estável) ou produto.nome.

Status do cliente

StatusSignificado
iniciadoComeçou o checkout, não concluiu
pendente_assinaturaFalta assinar o contrato
pendente_pagamentoAssinou, aguardando a 1ª parcela
ativoPagou a 1ª parcela — tem acesso
inadimplenteTem parcela vencida — sem acesso
quitadoPagou tudo
canceladoParcelamento cancelado

Regra de negócio do Destpay: o aluno só vira cliente ativo quando a 1ª parcela é paga. Antes disso ele existe no sistema, mas não deve ter acesso.

Ping de teste

Disparado pelo botão Testar do painel. Serve para validar URL e assinatura antes de ir para produção.

{
  "event": "ping",
  "enviado_em": "2026-07-31T03:00:00.000Z",
  "dados": { "mensagem": "Teste de configuracao do webhook Destpay." }
}

Reentrega

Se a sua URL não responder 2xx — ou passar de 10 segundos — a entrega volta para a fila.

TentativaEspera até a próxima
1 minuto
5 minutos
15 minutos
1 hora
3 horas
6 horas

Depois da 6ª tentativa a entrega é marcada como falhou e fica no painel para reenvio manual.

Boas práticas

Responda rápido

Devolva 200 assim que receber e processe depois. O timeout é de 10 segundos; se estourar, tratamos como falha e reenviamos.

Seja idempotente

Uma reentrega pode chegar depois de você já ter processado — por exemplo, se a sua resposta se perdeu no caminho. Use x-destpay-delivery para ignorar duplicatas.

Não confie na ordem

Com rede instável, um aluno.bloqueado reentregue pode chegar depois de um aluno.reativado. Compare enviado_em ou confie no campo cliente.status, que sempre reflete o estado no momento do envio.

Trate evento desconhecido

Podemos acrescentar eventos novos. Ignore o que não conhecer e responda 200 — devolver erro só gera reentrega desnecessária.

Acompanhar envios

No painel, em Integrações → Área de membros, cada envio aparece com evento, horário, código HTTP e número de tentativas. Falhas mostram o erro e podem ser reenviadas manualmente.