GGateway Docs

Webhooks

Notificações assíncronas de eventos — a única forma confiável de saber que um PIX/boleto foi pago (não faça polling em produção).

Configurar

Backoffice → WebhooksNovo endpoint (informe URL + um secret, usado pra assinar cada entrega) → inscreva-se nos tipos de evento que te interessam. Não há um endpoint público em /v1 pra isso nesta entrega — é uma operação de configuração, feita uma vez, via Backoffice/API admin.

Tipos de evento

EventoQuando dispara
payment.createdPagamento iniciado.
payment.processingEm processamento.
payment.authorizedCartão autorizado (não capturado).
payment.paidAprovado — qualquer método.
payment.failedRecusado ou erro.
payment.refundedEstornado.
payment.cancelledAutorização cancelada antes de capturar.
pix.createdCobrança PIX emitida.
pix.paidPIX pago.
pix.expiredPIX expirou sem pagamento.
boleto.createdBoleto emitido.
boleto.paidBoleto compensado.
settlement.createdRepasse agendado.
settlement.paidRepasse processado.

Payload

{
  "id": "evt_...",
  "type": "payment.paid",
  "tenantId": "...",
  "merchantId": "...",
  "payload": { "paymentId": "...", "amountInCents": 5000, "method": "pix" },
  "occurredAt": "2026-08-25T19:44:15.916Z",
  "correlationId": "..."
}

Headers de assinatura

Toda entrega chega com 4 headers:

HeaderConteúdo
X-Gateway-SignatureHMAC-SHA256 hex de ${timestamp}.${rawBody}
X-Gateway-TimestampUnix timestamp da assinatura
X-Gateway-Event-IdId do evento (mesmo de payload.id)
X-Gateway-Delivery-IdId desta tentativa específica de entrega

Verificar a assinatura

Sempre use o corpo cru da request (nunca req.body já parseado, que pode re-serializar o JSON e invalidar a assinatura):

TypeScript
import { verifySignature } from '@gateway/sdk';

app.post('/webhooks/gateway', (req, res) => {
  const ok = verifySignature({
    payload: req.rawBody,
    timestamp: req.headers['x-gateway-timestamp'],
    signature: req.headers['x-gateway-signature'],
    secret: process.env.GATEWAY_WEBHOOK_SECRET!,
  });
  if (!ok) return res.status(401).end();

  const event = JSON.parse(req.rawBody);
  // ...
  res.status(200).end();
});
PHP
$ok = $webhooks->verifySignature(
    file_get_contents('php://input'),
    $_SERVER['HTTP_X_GATEWAY_TIMESTAMP'],
    $_SERVER['HTTP_X_GATEWAY_SIGNATURE'],
    getenv('GATEWAY_WEBHOOK_SECRET'),
);

Duplicidade e ordem

O mesmo evento pode chegar mais de uma vez (retry de rede do nosso lado, ou reenvio) — sempre trate pelo id do evento (idempotente do seu lado: já processou esse id? ignore). Eventos também não chegam necessariamente na ordem em que aconteceram — nunca assuma que payment.processing chega antes de payment.paid; trate cada evento como um snapshot de status, não como um passo sequencial.

Retry e dead letter

Uma entrega que falhar (timeout, 4xx/5xx da sua URL) é tentada de novo com backoff crescente: 1min, 5min, 15min, 1h, 6h, 24h. Depois da última tentativa sem sucesso, a entrega vai pra dead letter — visível no Backoffice, com replay manual disponível (reprocessa sob demanda, sem esperar o schedule).

Responda rápido

Devolva 2xx assim que tiver validado a assinatura e enfileirado o processamento internamente — não faça o processamento pesado (chamadas a outros serviços, etc.) antes de responder; isso conta como timeout do lado do Gateway e aciona um retry desnecessário.