Webhooks

Webhooks são requisições HTTP POST enviadas automaticamente quando eventos acontecem na plataforma. Configure uma URL no seu ambiente para receber notificações em tempo real.

Configurando webhooks

Para configurar um novo webhook, acesse o console e crie um novo destino informando a URL do seu endpoint, escolhendo os tópicos (tipos de evento) que deseja receber. Após configurado, toda vez que um evento ocorrer, uma requisição HTTP POST será enviada para a URL cadastrada.


Consumindo webhooks

Cada requisição de webhook é uma requisição HTTP POST que inclui cabeçalhos com metadados do evento e um corpo JSON com os dados do evento.

Cabeçalhos

Todas as requisições de webhook incluem os seguintes cabeçalhos com o prefixo x-hme-:

  • Name
    content-type
    Type
    string
    Description

    Tipo do conteúdo. Sempre application/json.

  • Name
    x-hme-event-id
    Type
    string
    Description

    ID único do evento. Use para deduplicação de mensagens.

  • Name
    x-hme-timestamp
    Type
    string
    Description

    Timestamp Unix (em segundos) do momento em que o evento foi gerado.

  • Name
    x-hme-topic
    Type
    string
    Description

    Tópico do evento (ex: traffic-violation.created).

  • Name
    x-hme-signature
    Type
    string
    Description

    Assinatura HMAC-SHA256 no formato v0={signature}. Utilizada para verificação de autenticidade.

Exemplo de requisição

Exemplo de requisição HTTP

POST /webhooks HTTP/1.1
Content-Type: application/json
x-hme-event-id: evt_a056V7R7NmNRjl70
x-hme-timestamp: 1704067200
x-hme-topic: traffic-violation.created
x-hme-signature: v0=5f2c5e3b8a...

{
  "type": "traffic-violation.created",
  "data": {
    "id": 1,
    "ait": "AIT123456789",
    "code": "1234567890",
    "license_plate": "ABC1234",
    "description": "Excesso de velocidade",
    "status": "pending",
    "amount": 100.9,
    "date": "2024-01-01 12:00:00",
    "due_date": "2024-02-01",
    "company": {
      "id": 1,
      "tax_id": "12345678000190",
      "external_uid": "EXT_COMPANY_123",
      "name": "Empresa Exemplo Ltda"
    }
  }
}

Corpo da requisição

O corpo da requisição contém os dados do evento em formato JSON. Verifique o atributo type para identificar o tipo de evento.

  • Name
    type
    Type
    string
    Description

    Tipo do evento (ex: traffic-violation.created).

  • Name
    data
    Type
    object
    Description

    Dados do recurso associado ao evento.

Exemplo de payload

{
  "type": "traffic-violation.created",
  "data": {
    "id": 1,
    "ait": "AIT123456789",
    "code": "1234567890",
    "license_plate": "ABC1234",
    "description": "Excesso de velocidade",
    "status": "pending",
    "amount": 100.9,
    "date": "2024-01-01 12:00:00",
    "due_date": "2024-02-01",
    "company": {
      "id": 1,
      "tax_id": "12345678000190",
      "external_uid": "EXT_COMPANY_123",
      "name": "Empresa Exemplo Ltda"
    }
  }
}

Verificando assinaturas

Para garantir que uma requisição foi enviada pela API da habilitar.me, verifique a assinatura presente no cabeçalho x-hme-signature.

A assinatura é calculada usando HMAC-SHA256 sobre o corpo da requisição, utilizando a chave secreta do seu webhook.

O valor do cabeçalho x-hme-signature segue o formato:

v0=${signature}

Passos para verificação

  1. Extraia a assinatura (v0) do cabeçalho x-hme-signature.
  2. Calcule o HMAC-SHA256 do corpo da requisição usando sua chave secreta.
  3. Compare a assinatura calculada com a recebida usando comparação em tempo constante.
  4. Opcionalmente, use o cabeçalho x-hme-timestamp para rejeitar requisições com timestamps muito antigos e prevenir ataques de replay.

Verificando uma requisição

const crypto = require('crypto')

function verifyWebhook(req, secret) {
  const signatureHeader = req.headers['x-hme-signature']
  const body = JSON.stringify(req.body)

  // 1. Extrair assinatura
  const receivedSignature = signatureHeader.replace('v0=', '')

  // 2. Calcular assinatura esperada
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex')

  // 3. Comparar em tempo constante
  const isValid = crypto.timingSafeEqual(
    Buffer.from(expectedSignature),
    Buffer.from(receivedSignature)
  )

  if (!isValid) {
    throw new Error('Assinatura inválida')
  }

  // 4. (Opcional) Rejeitar timestamps antigos (ex: 5 minutos)
  const timestamp = parseInt(req.headers['x-hme-timestamp'])
  const currentTime = Math.floor(Date.now() / 1000)
  if (currentTime - timestamp > 300) {
    throw new Error('Timestamp expirado')
  }

  return true
}

Entrega e retentativas

A API opera com garantia de entrega at-least-once (pelo menos uma vez). Isso significa que, em casos raros, um mesmo evento pode ser entregue mais de uma vez. Use o cabeçalho x-hme-event-id para deduplicar mensagens no seu sistema.

Retentativas automáticas

Se o seu endpoint retornar um código de resposta HTTP diferente de 2xx, ou estiver indisponível, a entrega será retentada automaticamente com backoff exponencial. O número máximo de tentativas e o intervalo entre elas são configurados pela plataforma.

Retentativas manuais

Retentativas manuais podem ser acionadas através do portal de gerenciamento de webhooks.


Tipos de eventos

Abaixo estão listados todos os tipos de eventos disponíveis, agrupados por recurso. Clique no nome do recurso para acessar a documentação completa.

Empresas

  • Name
    company.created
    Description

    Uma nova empresa foi criada.

  • Name
    company.updated
    Description

    Uma empresa foi atualizada.

  • Name
    company.certificate.updated
    Description

    O certificado digital da empresa foi atualizado.

  • Name
    company.login.updated
    Description

    O login da empresa foi atualizado.

  • Name
    company.sne.updated
    Description

    O SNE da empresa foi atualizado.

Infrações

  • Name
    traffic-violation.created
    Description

    Uma nova infração foi criada.

  • Name
    traffic-violation.updated
    Description

    Uma infração foi atualizada.

Indicações

  • Name
    traffic-violation.indication.created
    Description

    Uma nova indicação foi criada.

  • Name
    traffic-violation.indication.updated
    Description

    Uma indicação foi atualizada.

Guias de Pagamento de Infrações

  • Name
    traffic-violation.ticket.created
    Description

    Uma nova guia de pagamento de infração foi criada.

  • Name
    traffic-violation.ticket.updated
    Description

    Uma guia de pagamento de infração foi atualizada.

Logins

  • Name
    login.created
    Description

    Um novo login foi criado.

  • Name
    login.updated
    Description

    Um login foi atualizado.

Usuários do Console

  • Name
    console-user.created
    Description

    Um novo usuário do console foi criado.

  • Name
    console-user.updated
    Description

    Um usuário do console foi atualizado.

Veículos

  • Name
    vehicle.created
    Description

    Um novo veículo foi criado.

  • Name
    vehicle.updated
    Description

    Um veículo foi atualizado.

Cobranças

  • Name
    charge.created
    Description

    Uma nova cobrança foi criada.

  • Name
    charge.updated
    Description

    Uma cobrança foi atualizada.

Guias de Pagamento de Cobranças

  • Name
    charge.payment-slip.created
    Description

    Uma nova guia de pagamento de cobrança foi criada.

  • Name
    charge.payment-slip.updated
    Description

    Uma guia de pagamento de cobrança foi atualizada.

Essa página foi útil?