PagnovoPagnovodocs

Webhooks

Payload de webhook v1 (legado)

v1 é nosso formato original de webhook. A estrutura é camelCase plana — sem envelope, todos os campos no nível raiz — e você identifica o tipo do evento inspecionando type e status em vez de um nome de evento dedicado.

Existem dois valores possíveis para type no nível superior: TRANSACTION (eventos de cash-in) e WITHDRAW (eventos de cash-out). Dentro de cada um, o campo status te diz o que aconteceu. Infrações em transações chegam embutidas dentro do payload da transação como um objeto aninhado infraction — não como webhooks próprios.

v1 continua totalmente suportada. Funcionalidades novas só vão pra v2, mas correções de bug e trabalho de confiabilidade se aplicam às duas.

ℹ️ V2 trouxe rastreio de origem. A partir do refator V2, todo webhook de cash-in em v2 carrega source_type + IDs polimórficos (invoice_id, offer_id, product_id, quick_link_id) indicando se a transação veio de API direta, Invoice, Checkout de Offer ou QuickLink. V1 não recebeu esses campos — se precisar rastrear origem, migre para Payload v2.

Webhook de transação

Dispara quando o status de uma transação muda. Duas formas possíveis: com ou sem um objeto infraction embutido.

Atualização padrão de transação:

JSON
{
  "transactionId": "23456789",
  "externalId": "id-do-seu-negocio",
  "payerDocument": "12345678900",
  "payerFullName": "João da Silva",
  "status": "APPROVED",
  "endToEnd": "E12345678202604081432123456789012",
  "amount": 5000,
  "type": "TRANSACTION",
  "sourceType": "CHECKOUT_OFFER",
  "invoiceId": null,
  "offerId": "off_d4c3b2a1",
  "productId": "prd_7e8f9a0b",
  "quickLinkId": null
}

Origem da transação (V1 também traz): os campos sourceType (API / INVOICE / CHECKOUT_OFFER / QUICK_LINK) e invoiceId / offerId / productId / quickLinkId indicam de onde a transação veio. Só aparecem quando há contexto — transação via API direta tem sourceType: "API" e os IDs vêm null (ou ausentes). Use pra reconciliar sem precisar de um GET /transactions/:id.

Com infração embutida:

JSON
{
  "transactionId": "23456789",
  "externalId": "id-do-seu-negocio",
  "payerDocument": "12345678900",
  "payerFullName": "João da Silva",
  "status": "APPROVED",
  "infraction": {
    "id": "dd0b2c77-8dd6-4eb5-b254-a46417eac46d",
    "status": "AWAITING_CUSTOMER_RESPONSE",
    "createdAt": "2026-04-08T00:18:00.580Z",
    "closedAt": null,
    "defendedAt": null,
    "responseAt": null,
    "cancelledAt": null,
    "reasonDetails": "Pagador reportou a transação como não autorizada.",
    "analysisResult": null,
    "analysisDetails": "Em análise pelo time de compliance."
  },
  "endToEnd": "E12345678202604081432123456789012",
  "amount": 5000,
  "type": "TRANSACTION"
}

Referência de campos:

  • transactionId — ID numérico interno. Use ao chamar GET /transactions/:id.
  • externalId — o valor que você setou como externalId ao criar a transação. É o link de volta para o seu banco de dados.
  • payerDocument / payerFullName — dados KYC do pagador vindos da instituição dele.
  • endToEnd — identificador end-to-end do PIX do Bacen. Útil para conciliação contra seu extrato bancário.
  • amount — sempre em centavos.
  • status — veja a tabela abaixo.
  • infraction — presente apenas quando há uma infração aberta ou recentemente fechada vinculada a esta transação.

Valores de status da transação

StatusQuando apareceO que fazer
PENDINGA transação foi criada mas ainda não foi paga.Aguarde. O QR Code do PIX ainda é válido até expiresAt.
APPROVEDO pagador pagou. Os fundos foram creditados no seu saldo.Entregue o produto/serviço. Esse é o estado de sucesso.
REJECTEDA instituição do pagador rejeitou o pagamento.Trate como não pago. O usuário precisa tentar de novo.
BLOCKEDPagamento recebido mas retido em bloqueio cautelar por compliance.Não entregue ainda. Aguarde resolução; o status vai mudar.
REFUNDEDUm estorno foi concluído com sucesso.Reverta o lançamento correspondente no seu sistema.
REFUNDED_PROCESSINGUm estorno está em curso mas ainda não foi finalizado.Marque a transação como em estorno; outro webhook virá.
CHARGEBACKUm chargeback foi executado. Fundos debitados do seu saldo.Atualize o pedido imediatamente. Guarde evidências caso vire disputa.
INCOSISTENTInconsistência interna detectada do nosso lado. A transação está em um estado que não conseguimos resolver automaticamente.Não trate como paga nem como não paga. Abra um ticket de suporte com o transactionId e o x-trace-id do webhook. Resolvemos esses casos manualmente e reenviamos o webhook com o status final correto.

Webhook de saque

Dispara quando o status de um saque muda:

JSON
{
  "withdrawId": "123456789",
  "externalId": "id-do-seu-negocio",
  "receiverName": "Maria Souza",
  "receiverDocument": "98765432100",
  "errorMessage": null,
  "status": "WITHDRAW_APPROVED",
  "endToEnd": "E98765432202604081500123456789012",
  "voucher": "https://voucher.pagnovo.com/receipt?token=...",
  "amount": 5000,
  "type": "WITHDRAW"
}

Referência de campos:

  • withdrawId — ID interno. Use em GET /withdraws/collect/:id.
  • externalId — sua referência de negócio, setada na criação.
  • receiverName / receiverDocument — o que o DICT retornou para a chave PIX de destino. Útil para conferir antes de baixar nos seus livros.
  • errorMessage — preenchido apenas em estados de erro. Caso contrário é null.
  • endToEnd — identificador end-to-end do PIX do Bacen. Sempre presente quando o SPI confirma.
  • voucher — URL para o comprovante oficial em PDF, válida por 6 meses.
  • amount — sempre em centavos.

Valores de status:

StatusQuando apareceO que fazer
WITHDRAW_REQUESTO saque foi aceito pela nossa API e está enfileirado.Marque como em curso. Não trate como final.
WITHDRAW_PROCESSINGEstamos conversando com o SPI.Aguarde. O estado final vem em segundos até alguns minutos.
WITHDRAW_APPROVEDO SPI confirmou a transferência. Os fundos saíram do seu saldo.Marque como final. Use endToEnd para conciliação.
WITHDRAW_REJECTEDO SPI ou a instituição de destino rejeitou. Verifique errorMessage.Os fundos retornaram ao seu saldo disponível. Notifique seu usuário.
WITHDRAW_RETURNEDA transferência foi inicialmente concluída, mas a instituição de destino devolveu o valor (conta encerrada, atividade suspeita).O valor está de volta no seu saldo. Investigue o motivo.
WITHDRAW_ERRORErro genérico do nosso lado ou no trânsito. errorMessage tem os detalhes.Trate como não enviado. Considere retry só depois de entender a causa.

Valores de status de infração

Quando um objeto infraction embutido está presente, o status dele te diz onde a infração está no ciclo da disputa e quem precisa agir:

StatusQuem ageO que significa
AWAITING_CUSTOMER_RESPONSEVocêA instituição do pagador abriu uma disputa. Precisamos das suas evidências. Responda pelo dashboard antes do prazo response_at expirar.
AWAITING_ADDITIONAL_INFOVocêSua resposta inicial foi recebida mas o compliance precisa de mais informação. Veja analysis_details pra entender o que falta.
UNDER_REVIEWTime de complianceSua resposta foi recebida. Estamos analisando. Nenhuma ação do seu lado.
CLOSEDFinal. Verifique analysis_result para ver quem ganhou: AGREED (concordamos com a disputa, transação está sendo ou foi revertida) ou DISAGREED (disputa negada, transação se mantém).
CANCELLEDA parte que abriu retirou a disputa. Transação se mantém.

Os campos de timestamp (createdAt, responseAt, defendedAt, closedAt, cancelledAt) são preenchidos conforme a infração avança nos estados. Úteis para acompanhamento de SLA — se responseAt está null e createdAt é de mais de 24h atrás, você está atrasado.