Skip to content

Webhooks ​

Eventos são entregues por HTTP POST aos seus endpoints ativos.

Catálogo de eventos ​

typequando
payment.succeededpagamento confirmado
payment.settledpagamento liquidado — planejado, ainda não é disparado (não há confirmação automática de liquidação hoje; ver Liquidação)
payment.cancelledpagamento cancelado
payment.failedpagamento recusado

Internamente, payment.captured é entregue publicamente como payment.succeeded. payment.authorized não gera webhook.

Envelope ​

json
{
  "id": "evt_9f8c...", "type": "payment.succeeded", "created": 1789990000,
  "data": {
    "payment": {
      "id": "pay_9f8c...",
      "amount": 510000,
      "currency": "BRL",
      "gross_amount": 510000,
      "gross_currency": "BRL",
      "fee_amount": 25000,
      "fee_currency": "BRL",
      "net_amount": 95000,
      "net_currency": "USD",
      "payment_method": "pix",
      "status": "succeeded",
      "reference": "pedido-123",
      "failure_code": null,
      "fx": {
        "rate": 5.1,
        "base": "USD",
        "quote": "BRL",
        "locked_at": 1800000000,
        "valid_until": null,
        "rate_history_id": 123
      },
      "settlement": {
        "estimated_date": "2026-09-08",
        "reason": [
          { "type": "cutoff", "note": "..." },
          { "type": "weekend", "date": "2026-09-05" },
          { "type": "holiday", "date": "2026-09-07", "country": "BR", "name": "..." }
        ]
      }
    }
  }
}

O payload público nunca inclui spot_rate, cobertura_centibps, source, median_3_stablecoin, percent_centibps nem percentuais de regra.

Liquidação (settlement) ​

Presente apenas em payment.succeeded. Diz quando o valor deve cair e por quê aquela data — para você fechar o caixa sem recalcular o calendário bancário (BR/Febraban + US/Fedwire), o corte de 15h (America/Sao_Paulo) e o rolamento de fim de semana por conta.

  • estimated_date (AAAA-MM-DD, America/Sao_Paulo) é uma ESTIMATIVA, não uma garantia. Reflete as regras vigentes de calendário no momento da confirmação.
  • reason[] é o rastro cronológico do que moveu a data: cutoff (pago após as 15h), weekend, e holiday (com country e name). Array vazio significa que a data caiu direto, sem ajustes.
  • Não há campo de "D+N". Use estimated_date; o reason explica o caminho. Não some dias por conta.
  • Fora da cobertura do calendário, o objeto settlement é omitido — nunca enviamos uma data sem cobertura. Trate a ausência como "sem previsão", não como erro.
  • Não existe evento de confirmação de liquidação. payment.succeeded traz a previsão; a plataforma não emite hoje um evento que confirme que o crédito efetivamente ocorreu na estimated_date. Não assuma confirmação automática — se você precisa conciliar o crédito real, faça-o pelo seu extrato bancário.

Assinatura ​

Cada entrega carrega o header:

Pagooz-Signature: t=1789990000,v1=<hex>

v1 é o HMAC-SHA256, em hex, de "{t}.{body}" (o timestamp, um ponto, e o corpo bruto do request), usando o secret do endpoint. Verifique e rejeite entregas com t a mais de 5 minutos do agora (tolerância de replay).

Exemplo funcional (Node):

js
const crypto = require("crypto");

function verifyPagoozSignature(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(",").map((kv) => kv.split("=")));
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false; // 5 min
  const expected = crypto.createHmac("sha256", secret)
    .update(`${t}.${rawBody}`).digest("hex");
  const a = Buffer.from(expected), b = Buffer.from(parts.v1 || "");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Entrega, retry e idempotência do consumidor ​

  • Uma entrega é bem-sucedida somente com resposta 2xx.
  • Falha aciona 5 tentativas com backoff: imediato, 1 minuto, 5 minutos, 30 minutos e 2 horas.
  • Depois da 5ª falha, a entrega fica dead_lettered e visível no cockpit.
  • Entrega ao menos uma vez. O mesmo evento pode chegar mais de uma vez (retry, renotificação, reentrega). Seu consumidor deve ser idempotente por event.id — processe cada id uma só vez.

Configuração no cockpit ​

Uma URL por tenant por ambiente (sandbox e live). O cockpit lê o modo global da sessão e salva a URL daquele ambiente. O secret de assinatura é exibido uma única vez na criação/rotação. A tabela webhook_endpoints não é usada nesta versão; fica reservada para múltiplos destinos futuros.


Conciliação e renotificação ​

Reenvio manual no cockpit ​

O merchant pode reenviar uma entrega falhada pelo cockpit. O payload reenviado mantém o mesmo event_id; a nova tentativa é registrada em webhook_deliveries com origin = "manual".

Histórico de entregas ​

O cockpit mostra as últimas entregas por ambiente. Cada objeto:

json
{
  "id": "whd_9f8c...", "event_id": "evt_9f8c...",
  "attempt": 3, "status": "failed", "http_status": 503,
  "response_body": "...",
  "origin": "auto", "created": 1789990000, "next_attempt_at": 1789990300
}

Permite diagnosticar sozinho por que uma notificação não chegou.


Transferência bancária (TED) — confirmação por conferência ​

Uma cobrança paga por transferência bancária não é confirmada por sistema: o pagador envia o comprovante no checkout e a Poolvo confere o recebimento antes de dar a cobrança por paga. Isso muda o que você deve esperar como integrador:

  • O payment.succeeded de uma transferência chega depois da conferência, não no momento em que o pagador diz que pagou. Entre uma coisa e outra podem passar horas, e a conferência acontece em horário comercial. Não trate a demora como falha nem reenvie a cobrança.
  • Enquanto aguarda conferência, o pagamento existe e não conta como pago: não some no seu fechamento de período e não gera webhook.
  • Recusa na conferência (comprovante que não confere) chega como payment.failed.
  • Quando o pagamento é confirmado, o webhook é o mesmo payment.succeeded do PIX e do cartão, com os mesmos campos. Você não precisa de tratamento próprio por método.

payment_methods em POST /v1/payment_links aceita pix e card. Cobrança por transferência bancária é criada pelo fluxo de cotação (POST /v1/quotes com payment_method: "ted", depois aceitando a cotação), e o objeto Payment devolve payment_method: "ted" normalmente.

Liquidação é confirmada fora da API ​

A previsão de liquidação vem no payment.succeeded (ver Webhooks → Liquidação). A confirmação de que o crédito ocorreu é registrada pela Poolvo por conferência manual, e não é exposta na API hoje: não existe evento, nem campo de status de liquidação no objeto Payment. payment.settled segue planejado. Se você precisa conciliar o crédito real, use o seu extrato bancário — não espere uma notificação nossa.