Pular para o conteúdo principal

Notificação

Os webhooks permitem que você receba notificações em tempo real sobre eventos em sua conta.

Visão Geral​

Quando um evento ocorre, a plataforma envia uma requisição HTTP POST para o seu endpoint de webhook. Todos os tipos de evento são entregues na mesma URL configurada.

Configurando Webhooks​

  1. Informe os endpoints de webhook: sandbox e produção
  2. Implemente um handler para receber eventos de webhook

Segurança​

Toda requisição de webhook é assinada. Valide a assinatura antes de processar o evento para garantir que a notificação veio da plataforma e não foi adulterada.

Headers​

Cada requisição inclui os seguintes headers:

HeaderDescrição
X-Webhook-SignatureAssinatura HMAC-SHA256 do corpo, no formato sha256=<hex>
X-Event-IDIdentificador único do evento
X-Event-TypeTipo do evento (ex: payment.completed)
X-Delivery-AttemptNúmero de reenvios já realizados (0 na primeira entrega)

Como a assinatura é calculada​

A assinatura é o HMAC-SHA256 do corpo bruto da requisição — os bytes exatos recebidos — codificado em hexadecimal, usando a chave secreta do seu webhook. O valor é enviado no header prefixado por sha256=.

aviso

Calcule a assinatura sobre o corpo bruto. Não deserialize e re-serialize o JSON antes de validar: a re-serialização altera os bytes (ordem de campos, espaçamento) e invalida a assinatura.

Validando em Go​

package webhooks

import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"io"
"net/http"
"strings"
)

// ValidateSignature verifica o header X-Webhook-Signature contra o corpo bruto da requisição.
// secret é a chave secreta do seu webhook; body são os bytes exatos recebidos.
func ValidateSignature(secret string, body []byte, signatureHeader string) bool {
// O header vem no formato "sha256=<hex>".
want, ok := strings.CutPrefix(signatureHeader, "sha256=")
if !ok {
return false
}

mac := hmac.New(sha256.New, []byte(secret))
mac.Write(body)
got := hex.EncodeToString(mac.Sum(nil))

// Comparação em tempo constante para evitar ataques de temporização.
return hmac.Equal([]byte(want), []byte(got))
}

// Exemplo de handler HTTP.
func HandleWebhook(secret string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Leia o corpo bruto ANTES de qualquer decodificação de JSON.
body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "não foi possível ler o corpo", http.StatusBadRequest)
return
}

if !ValidateSignature(secret, body, r.Header.Get("X-Webhook-Signature")) {
http.Error(w, "assinatura inválida", http.StatusUnauthorized)
return
}

// Assinatura válida — processe o evento a partir do corpo (body).
// Responda 2xx para confirmar o recebimento.
w.WriteHeader(http.StatusOK)
}
}

Tipos de Evento​

EventoDescrição
payment.completedUm pagamento foi concluído com sucesso
terminal.activatedUm terminal foi ativado com sucesso