Pular para o conteúdo principal

O que são Webhooks?

Um webhook é uma maneira eficiente de receber notificações e dados em tempo real de sistemas externos.

Ao configurar uma URL em seu sistema, você pode permitir que outros serviços publiquem informações para essa URL sempre que um evento relevante acontecer. Isso significa que, em vez de precisar consultar constantemente esses sistemas para obter atualizações, os dados chegam automaticamente, assim que ocorrem.

Essa abordagem é especialmente útil para automatizar processos e reagir instantaneamente a eventos importantes, como novas transações, atualizações de pedidos ou mudanças em dados, economizando tempo e recursos.

Esta documentação visa esclarecer o comportamento dos nossos webhooks, facilitando sua integração e garantindo um processo de implementação mais ágil e eficiente.

Formato Padrão das Mensagens de Webhook

As mensagens enviadas pelo webhook têm o propósito exclusivo de notificar sobre a ocorrência de alterações em registros, sem fornecer detalhes completos sobre a mudança em si. Esse modelo simplificado contribui para manter a comunicação via webhook segura e eficiente.

Após o recebimento de uma notificação de webhook, é comum que seu sistema realize uma consulta adicional à API para obter detalhes completos sobre o registro alterado.

Cada mensagem de webhook contém os seguintes elementos:

  • status: Indica o tipo de alteração realizada no objeto, como CREATION, UPDATE, etc.
  • params: Um dicionário que contém os parâmetros necessários para identificar o recurso afetado.
  • resource: A URI do recurso que foi alterado, que pode ser usada para consultar o dado atualizado ou criado.
  • tenant_id: Identificador do cliente ao qual o evento se refere.
  • topic: Define a categoria ou tipo de evento, ajudando a classificar a natureza da notificação.

Exemplo de Mensagem

{
"data": {
"status": "CREATION",
"params": {
"id": "debde69a-2dbb-427b-b478-6cffd7930ecf"
},
"resource": "/seller/v0/tickets/debde69a-2dbb-427b-b478-6cffd7930ecf"
},
"tenant_id": "3b5cf468-c858-404b-9e53-630e3df9d74a",
"topic": "sac_ticket"
}

Interpretação do Status nas Mensagens de Webhook

O campo status indica a operação realizada sobre um registro no sistema e informa ao consumidor do webhook qual ação foi tomada. Os possíveis valores são:

  • CREATION: Indica uma operação de criação de um registro no tópico especificado.
  • UPDATE: Indica a atualização de um registro existente.
  • DELETION: Indica a exclusão de um registro.
aviso

Se o seu sistema armazena dados das nossas APIs, é fundamental aplicar as atualizações e deleções conforme indicadas, já que podem envolver moderação e remoção de informações sensíveis de clientes.

Receba Atualizações por Webhook

Para configurar um webhook usando a API v0, siga a documentação do portal de desenvolvedores.

Para configurar um webhook usando a API v1 (com HTTPS obrigatório e assinatura HMAC), siga a documentação v1.

Segurança dos Webhooks (API v1)

A API v1 de webhooks introduz melhorias de segurança que permitem verificar a autenticidade das notificações recebidas. Ao criar uma inscrição via PUT /v1/onboarding/signup, você recebe um secret e todas as notificações passam a ser assinadas com HMAC-SHA256.

HTTPS Obrigatório

Na API v1, todas as URLs de webhook devem usar HTTPS. URLs HTTP são rejeitadas com erro 422 Unprocessable Entity.

// Erro retornado ao enviar URL HTTP na v1
{
"message": "Unprocessable entity",
"slug": "UNPROCESSABLE_ENTITY",
"details": [
{
"field": "webhook",
"location": "body",
"message": "URL must use HTTPS scheme",
"slug": "INVALID_PARAMETER_VALUE"
}
]
}

Client Secret

Ao criar ou atualizar uma inscrição via PUT /v1/onboarding/signup, o response inclui um secret no campo parameters de cada subscription. O formato do secret é whsec_* (exemplo: whsec_abc123).

{
"subscriptions": [
{
"id": "subscription_id",
"parameters": {
"url": "https://seu-servidor.com/webhooks",
"secret": "whsec_abc123"
},
"topic": "sac_ticket",
...
}
]
}
Atenção

O secret é exibido somente no response do PUT /v1/onboarding/signup. Ele não pode ser recuperado depois. Armazene-o de forma segura imediatamente após a criação da inscrição.

Se você perder o secret, será necessário chamar PUT /v1/onboarding/signup novamente. Isso gera um novo secret e inicia um período de graça de 1 hora durante o qual o secret anterior ainda é aceito.

Verificação de Assinatura (HMAC-SHA256)

Todas as notificações enviadas para subscriptions v1 incluem dois headers de segurança:

HeaderDescrição
X-Signature-256Assinatura HMAC-SHA256 do payload no formato sha256=<hex_digest>
X-TimestampTimestamp Unix (segundos) do momento do envio

Formato do Payload Assinado

A assinatura é calculada sobre a string {timestamp}.{body}, onde:

  • {timestamp} é o valor do header X-Timestamp
  • {body} é o corpo da requisição (JSON) exatamente como recebido

A inclusão do timestamp no payload assinado protege contra ataques de replay — uma mensagem interceptada não pode ser reenviada em outro momento, pois o timestamp não corresponderá.

Exemplo de Verificação em Python

import hmac
import hashlib

def verify_webhook_signature(
payload: bytes,
signature_header: str,
timestamp: str,
secret: str,
) -> bool:
"""Verifica a assinatura HMAC-SHA256 de uma notificação webhook."""
# Monta o payload assinado: {timestamp}.{body}
signed_payload = f"{timestamp}.".encode() + payload

# Calcula o HMAC esperado
expected = hmac.new(
secret.encode(),
signed_payload,
hashlib.sha256,
).hexdigest()

# Pode haver múltiplas assinaturas durante rotação de secret
signatures = signature_header.split(",")
for sig in signatures:
sig_value = sig.strip().removeprefix("sha256=")
if hmac.compare_digest(sig_value, expected):
return True

return False


# Uso:
# signature = request.headers["X-Signature-256"]
# timestamp = request.headers["X-Timestamp"]
# is_valid = verify_webhook_signature(
# payload=request.body,
# signature_header=signature,
# timestamp=timestamp,
# secret="whsec_seu_secret_aqui",
# )

Exemplo de Verificação em Node.js

const crypto = require('crypto')

function verifyWebhookSignature(payload, signatureHeader, timestamp, secret) {
// Monta o payload assinado: {timestamp}.{body}
const signedPayload = `${timestamp}.${payload}`

// Calcula o HMAC esperado
const expected = crypto.createHmac('sha256', secret).update(signedPayload).digest('hex')

// Pode haver múltiplas assinaturas durante rotação de secret
const signatures = signatureHeader.split(',')
for (const sig of signatures) {
const sigValue = sig.trim().replace('sha256=', '')
if (crypto.timingSafeEqual(Buffer.from(sigValue), Buffer.from(expected))) {
return true
}
}

return false
}

// Uso:
// const isValid = verifyWebhookSignature(
// req.body, // corpo raw da requisição
// req.headers["x-signature-256"],
// req.headers["x-timestamp"],
// "whsec_seu_secret_aqui"
// );

Rotação de Secret

Ao chamar PUT /v1/onboarding/signup novamente, um novo secret é gerado. Durante o período de graça de 1 hora, as notificações são enviadas com duas assinaturas no header X-Signature-256:

X-Signature-256: sha256=<assinatura_secret_novo>,sha256=<assinatura_secret_antigo>

Isso permite que você atualize o secret no seu sistema sem perder notificações. Após 1 hora, apenas a assinatura do novo secret será enviada.

Retrocompatibilidade

Subscriptions criadas via API v0 (PUT /v0/onboarding/signup) continuam funcionando normalmente sem assinatura. A verificação de assinatura é exclusiva da API v1. A migração de v0 para v1 é opcional.

Comparativo v0 vs v1

CaracterísticaAPI v0API v1
ProtocoloHTTP ou HTTPSHTTPS obrigatório
Client SecretNão disponívelwhsec_* por subscription
Assinatura HMACNão disponívelX-Signature-256 + X-Timestamp
Rotação de secretN/APeríodo de graça de 1h com duas assinaturas
EndpointsPUT /v0/onboarding/signupPUT /v1/onboarding/signup