Webhooks da Área de Membros

Este documento descreve como integrar e consumir os webhooks enviados pela plataforma TheMembers. Os webhooks permitem que sistemas de clientes recebam notificações em tempo real sobre eventos relevantes, como conclusão de aulas, emissão de certificados, publicação de conteúdo e inatividade de usuários.


Visão Geral

A plataforma TheMembers envia requisições HTTP POST para os endpoints de webhook registrados pelos clientes sempre que determinados eventos ocorrem. O payload enviado está no formato JSON e contém informações detalhadas sobre o evento.

Características principais:

  • Protocolo: HTTP POST

  • Formato: JSON

  • Autenticação: HMAC-SHA256

  • Timeout: 30 segundos

  • Tentativas: Até 3 tentativas em caso de falha

  • Intervalo entre tentativas: 30s, 60s, 120s


Autenticação e Segurança

Cada requisição enviada para o webhook do cliente contém um cabeçalho de autenticação HMAC para garantir a integridade e autenticidade dos dados:

  • Cabeçalho: X-Webhook-Signature

  • Valor: Assinatura HMAC-SHA256 do corpo da requisição, usando o client_token do cliente

  • Cabeçalho adicional: X-Webhook-Event — Nome do evento disparado

Como validar:

  1. Calcule o HMAC-SHA256 do corpo da requisição recebida (JSON bruto, sem formatação extra) usando seu client_token como chave.

Importante: O JSON é serializado usando as seguintes regras:

  • Barras / não são escapadas (sem \/)

  • Caracteres Unicode não são escapados (ex: á ao invés de \u00e1)

  1. Certifique-se de que sua serialização JSON corresponda a esse comportamento.

  2. Codifique o resultado em hexadecimal (hash_hmac com raw_output = false).

  3. Compare com o valor do cabeçalho X-Webhook-Signature.

circle-info

A assinatura só corresponderá se o JSON for serializado exatamente conforme as regras acima (sem barras ou unicode escapados).

Exemplo em PHP:

Exemplo em JavaScript (Node.js):


Exemplo de Assinatura

Abaixo está um exemplo de corpo de requisição de webhook e o valor esperado para o cabeçalho X-Webhook-Signature, assumindo que o client_token seja mySecretKey123.

Corpo da Requisição de Exemplo:

Assinatura Esperada

Para o corpo acima e client_token mySecretKey123, o valor do cabeçalho X-Webhook-Signature será (exemplo ilustrativo):

4a3d8c1e2f5b6a7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c

Nota: A assinatura acima é ilustrativa. O valor real dependerá da serialização exata do JSON e da chave secreta.

Importante: A assinatura só corresponderá se o JSON for serializado exatamente como acima, sem barras ou unicode escapados.


Eventos Enviados

1

Conclusão de Aula (class.completed)

Enviado quando um aluno conclui uma aula (progresso = 100% ou marcada como finalizada).

  • Tipo de Evento: class.completed

  • Tipo de Payload: class_history

Exemplo de Payload:

Campos principais:

  • type (string): Tipo do payload, sempre class_history para este evento

  • event (string): Nome do evento, sempre class.completed

  • created (string): Data/hora de criação do evento (ISO 8601)

  • data (object): Dados do evento, incluindo:

    • datetime (string): Data/hora em que a aula foi concluída (ISO 8601)

    • platform_id (integer)

    • platform_name (string)

    • student (object): id, reference_id, name, email, phone, document, gender

    • course (object): id, name, module (com id, name, class com id e name)

2

Publicação de Aula (class.published)

Enviado quando uma nova aula é publicada na plataforma (no momento da criação ou publicação manual).

  • Tipo de Evento: class.published

  • Tipo de Payload: class

Exemplo de Payload:

Campos principais:

  • type (string): Tipo do payload, sempre class para este evento

  • event (string): Nome do evento, sempre class.published

  • created (string): Data/hora de criação do evento (ISO 8601)

  • data (object): Inclui datetime, platform_id, platform_name, course (id, name, status, module com id, name, status, class com id e name)

3

Certificado Emitido (certificate.issued)

Enviado quando um certificado é emitido para um aluno.

  • Tipo de Evento: certificate.issued

  • Tipo de Payload: certificate

Exemplo de Payload:

Campos principais:

  • type (string): Tipo do payload, sempre certificate para este evento

  • event (string): Nome do evento, sempre certificate.issued

  • created (string): Data/hora de criação do evento (ISO 8601)

  • data (object): Inclui datetime, platform_id, platform_name, student (id, reference_id, name, email, phone, document, gender), course (id, name), certificate (id, name)

4

Usuário Inativo por 7 Dias (user.inactive_for_7_days)

Enviado quando um usuário está inativo por exatamente 7 dias (sem login nos últimos 7 dias ou sem login desde a criação da conta).

Observação: Usuários inativos que permanecem inativos continuarão recebendo este evento a cada 7 dias.

  • Tipo de Evento: user.inactive_for_7_days

  • Tipo de Payload: login_history

Exemplo de Payload:

Campos principais:

  • id (string): UUID único do evento

  • type (string): Tipo do payload, sempre login_history para este evento

  • event (string): Nome do evento, sempre user.inactive_for_7_days

  • created (string): Data/hora de criação do evento (ISO 8601)

  • data (object): Inclui datetime, inactive_days, platform_id, platform_name, student (id, reference_id, name, email, phone, document, gender)


Formato do Payload

  • Todas as requisições são enviadas com o cabeçalho Content-Type: application/json

  • Campos de data/hora seguem o padrão ISO 8601 (ex: 2025-01-13T14:30:00.000000Z)

  • Campos podem conter valores null quando não aplicável

  • O telefone é formatado no padrão E.164 quando disponível (ex: +5511999999999)

  • Documentos (CPF/CNPJ) são retornados apenas com números, sem formatação


Boas Práticas e Observações

Segurança

  • Sempre valide a assinatura HMAC antes de processar o payload

  • Mantenha seu client_token seguro e não o compartilhe

  • O client_token é único para cada URL de webhook registrado

  • Use HTTPS em seu endpoint de webhook

Resposta

  • Responda rapidamente com HTTP 200 para evitar reenvio do evento

  • Processe o evento de forma assíncrona se necessário

  • Não execute operações demoradas na thread principal

Confiabilidade

  • Implemente idempotência - o mesmo evento pode ser enviado mais de uma vez

  • Registre logs de eventos recebidos para facilitar troubleshooting

  • O endpoint deve estar disponível publicamente e aceitar requisições HTTPS

Tratamento de Erros

  • Em caso de falha no envio, o sistema tentará reenviar o evento até 3 vezes

  • Intervalos entre tentativas: 30s, 60s, 120s

  • Após 3 falhas, o evento será marcado como falho e não será reenviado

Timeout

  • O timeout da requisição é de 30 segundos

  • Certifique-se de que seu endpoint responda dentro desse tempo

Performance

  • O webhook pode receber múltiplos eventos em sequência

  • Processe cada evento de forma independente e idempotente

  • Considere usar filas para processar eventos de forma assíncrona

Last updated