POST assinado para essa URL e insiste
até receber um 2xx. É a volta do webhook de entrada: lá a
plataforma de venda avisa o club; aqui o club avisa você.
O formato segue o Standard Webhooks, então as bibliotecas
oficiais do padrão conferem a assinatura sem código nosso.
A requisição
O envelope
Todo evento tem a mesma casca:Catálogo
A escolha de eventos é uma lista explícita, sem coringa: um endpoint recebe só os tipos que
escolheu, e um tipo novo que entrar no catálogo nunca começa a sair para quem não o pediu.
O documento do aluno (CPF) não sai em evento nenhum.
Verificar a assinatura
A assinatura é um HMAC-SHA256 sobre{webhook-id}.{webhook-timestamp}.{corpo}. A chave é o
segredo sem o prefixo whsec_, decodificado de base64; o resultado vai em base64 depois de
v1,.
Três cuidados que valem para qualquer linguagem:
- Assine o corpo cru, os bytes exatos que chegaram, antes de qualquer parse. Um JSON lido e serializado de novo muda espaço, ordem ou escape de acento, e a assinatura deixa de conferir.
- Aceite qualquer uma das assinaturas do cabeçalho: na troca de segredo vêm duas.
- Recuse o que chega velho: timestamp com mais de 5 minutos de diferença do seu relógio. Como o timestamp entra na assinatura, uma requisição capturada não pode ser repetida depois.
O segredo
O segredo (whsec_…) aparece uma única vez: ao cadastrar o endpoint e ao trocá-lo, em
Segredo de assinatura, na página do endpoint. Perdeu, troque.
Na troca, o segredo anterior continua assinando por 24 horas: nesse intervalo cada entrega
leva as duas assinaturas, e o seu lado aceita a que conferir. Atualize o segredo do seu lado
dentro desse prazo e nenhuma entrega fica sem conferir no meio do caminho.
Responder
Responda2xx rápido e processe depois. Cada tentativa tem 15 segundos de prazo;
grave o evento numa fila sua e responda, em vez de fazer o trabalho dentro da requisição.
- Qualquer resposta fora de
2xxconta como falha, inclusive4xx: um401depois de trocar o segredo ou um404de um deploy pela metade se consertam do seu lado, e a entrega volta a tentar. - Redirecionamento (
3xx) não é seguido. Cadastre a URL final. Retry-Afterem429e503é respeitado, até 10 horas: ele alonga a espera até a próxima tentativa, nunca a encurta.
Novas tentativas
Uma entrega tem 8 tentativas no total. Depois de cada falha, a próxima espera:
Cada espera varia ±10%, para mil entregas que falharam juntas não voltarem juntas. São cerca de
27 horas entre a primeira e a última tentativa; esgotadas as oito, a entrega fica
failed.
Entrega pelo menos uma vez, e sem ordem
A mesma mensagem pode chegar mais de uma vez — a sua resposta se perdeu na rede, alguém reenviou pelo painel. Deduplique pelowebhook-id: guarde os ids já processados e ignore o
repetido.
Não há garantia de ordem. Uma falha numa tentativa faz o evento seguinte chegar antes. Não
decida pelo tipo da última mensagem que chegou: use o occurred_at e o estado do recurso que
vem no data. O corpo é montado segundos depois do fato e traz o recurso como está naquele
momento — num access.revoked, data.enrollment.status já é revoked.
O disjuntor
Um endpoint que só falha não deve receber rajadas:- A partir de 5 falhas seguidas, o endpoint passa a receber uma tentativa por vez, com intervalos que começam em 1 minuto e dobram até 1 hora.
- Qualquer
2xxzera o disjuntor. - Cinco dias sem nenhuma entrega aceita desligam o endpoint. A fila dele é cancelada e quem administra o club recebe um e-mail.
Estados do endpoint
Pausar é para uma manutenção do seu lado, em que nada pode se perder. Desligar é para parar de
receber.
O endereço
- Precisa ser
httpse resolver para a internet pública. Rede privada,localhoste IPs reservados são recusados no cadastro — e de novo a cada conexão, contra o IP que o DNS devolveu naquela hora. - Não há IP fixo de saída: não dá para liberar a entrega por lista de IPs. A assinatura é o que prova que a mensagem veio do club.
- Até 20 endpoints por club.
- Cadastrar e gerir endpoints exige permissão de administração do club: o histórico de entregas leva nome e e-mail de alunos.
Testar
Enviar teste, na página do endpoint, cria uma entregawebhook.test que passa pelo mesmo
caminho dos eventos reais: assinatura, conferência do endereço, novas tentativas. O teste que
passa prova o que vai acontecer com os eventos de verdade. Só funciona com o endpoint ligado, e não espera o disjuntor: é o jeito de conferir, na hora, que o seu lado voltou.
Retenção
Depois que o corpo é apagado, a entrega continua no histórico, mas não há mais o que reenviar.
O prazo do corpo não tem exceção. Uma entrega que fica pendente mais de 30 dias — o caso é o
endpoint pausado e esquecido — é cancelada, para o corpo sair no prazo como todos os outros.
Remoção de aluno
Quando um aluno é removido do club (LGPD):- sai
student.removed, só com o id — o sinal para apagar a pessoa do seu sistema também; - os corpos das mensagens anteriores que falavam dela são apagados;
- o que ainda não tinha saído é cancelado;
- eventos daquele aluno gravados depois da remoção não saem.