Pagamentos

Webhook — Pagamento

Notificação de Pagamento Pix efetivado ou com falha (cash-out)

Notificação HTTP que o integrador pagador recebe quando um pagamento Pix sai da sua conta — seja efetivado (pagamento) ou com erro/rejeição (pagamento-falha).

É o espelho do webhook de recebimento: lá o integrador recebedor é avisado do crédito; aqui o integrador pagador é avisado do débito (sucesso ou falha).

Pagador e recebedor

Não confunda quem recebe o POST (seu endpoint) com os papéis dentro do payload:

PapelQuem éOnde aparece
Integrador (listener)Conta pagadora que cadastrou o webhookRecebe o POST na webhookUrl
PagadorQuem enviou o Pix (débito)nomePagador, cpfPagador/cnpjPagador, bancoPagador
RecebedorQuem receberia o Pix (crédito / destino)nomeRecebedor, cpfRecebedor/cnpjRecebedor, bancoRecebedor, campo chave

No fluxo típico deste guia, o integrador inicia pagamentos pela API: os campos *Pagador* descrevem o titular que debitou (ou tentou debitar); os campos *Recebedor* descrevem a contraparte de destino.

Duas chaves diferentes:

  • {chave} na URL do cadastro (PUT /api/v2/cobranca/webhooks/{chave}): qualquer chave Pix da conta pagadora (só para registrar o webhook).
  • chave no payload: chave Pix do recebedor (destino do pagamento).

Cadastro

Mesma rota pública do webhook de recebimento. Eventos: pagamento e/ou pagamento-falha.

Registrar em uma chave Pix da conta pagadora (EVP, e-mail, CPF/CNPJ ou telefone). Basta o evento em qualquer chave da conta — não precisa ser a chave usada no pagamento. Isso difere do recebimento, que exige o webhook na mesma chave embebida no QR.

MétodoRotaDescrição
GET/api/v2/cobranca/webhooks/{chave}Lista webhooks da chave (filtro opcional eventos)
PUT/api/v2/cobranca/webhooks/{chave}Cria webhook(s) — não atualiza existentes
PATCH/api/v2/cobranca/webhooks/{id}Atualiza URL/autorização pelo id
DELETE/api/v2/cobranca/webhooks/{id}Remove um webhook pelo id
{
  "webhookUrl": "https://integrador.exemplo.com.br/pix/pagamento",
  "eventos": ["pagamento", "pagamento-falha"],
  "autorizacao": {
    "tipo": "Bearer",
    "valor": "seu-token-secreto"
  }
}
CampoObrigatórioDescrição
{chave}simUma chave Pix da conta pagadora
webhookUrlsimURL que receberá o POST
eventossimInclua "pagamento" e/ou "pagamento-falha"
autorizacao.tiponãoScheme HTTP (Bearer, Basic). Use none ou omita para sem auth
autorizacao.valornãoToken/senha enviado no header Authorization (armazenado criptografado)

O PUT somente cria. Para alterar URL/autorização: PATCH /{id}. Para remover: DELETE /{id} (use o id do GET/PUT).

curl --location --request PUT 'https://api-h.nuvende.com.br/api/v2/cobranca/webhooks/{{chave_pix}}' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{access_token}}' \
--data '{
  "webhookUrl": "https://integrador.exemplo.com.br/pix/pagamento",
  "eventos": ["pagamento", "pagamento-falha"],
  "autorizacao": {
    "tipo": "Bearer",
    "valor": "seu-token-secreto"
  }
}'

Scopes: webhooks.read / webhooks.write.

Response (200) — criação

{
  "webhooks": [
    {
      "id": 12,
      "chave": "efca2b48-0d8a-4f10-9f07-26e6b5a1b921",
      "webhookUrl": "https://integrador.exemplo.com.br/pix/pagamento",
      "evento": "pagamento",
      "criacao": "2026-09-16 10:30:00"
    },
    {
      "id": 13,
      "chave": "efca2b48-0d8a-4f10-9f07-26e6b5a1b921",
      "webhookUrl": "https://integrador.exemplo.com.br/pix/pagamento",
      "evento": "pagamento-falha",
      "criacao": "2026-09-16 10:30:00"
    }
  ],
  "currentPage": 1,
  "lastPage": 1,
  "perPage": 15,
  "total": 2
}

Atualizar (PATCH)

curl --location --request PATCH 'https://api-h.nuvende.com.br/api/v2/cobranca/webhooks/{{id}}' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{access_token}}' \
--data '{
  "webhookUrl": "https://integrador.exemplo.com.br/pix/pagamento-v2",
  "autorizacao": {
    "tipo": "Bearer",
    "valor": "novo-token"
  }
}'

Quando dispara

Evento pagamento

Pagamento Pix confirmado (cash-out) → POST em todas as webhookUrl com evento pagamento
#Condição
1Pagamento atinge status efetivado (CONFIRMADO)
2A conta pagadora tem ao menos uma chave com webhook evento = pagamento

Evento pagamento-falha

Pagamento Pix com ERRO → POST em todas as webhookUrl com evento pagamento-falha
#Condição
1Pagamento em status ERRO
2A conta pagadora tem ao menos uma chave com webhook evento = pagamento-falha

Vale para pagamento para outro banco e transferência interna, independentemente da forma de iniciação (chave, QR ou manual).

  • Uma notificação de negócio por webhook (por URL). Reprocessamentos internos não geram novo POST se aquela URL já recebeu HTTP 2xx para o mesmo pagamento.
  • Vários webhooks do mesmo evento → múltiplos POST (mesmo payload, um por URL).
  • Sem webhook do evento na conta pagadora → nenhum POST (silencioso).
  • Pagamento apenas iniciado (ainda sem confirmação/liquidação) → não dispara nenhum dos dois eventos.

Entrega HTTP

AspectoValor
MétodoPOST
BodyJSON
Timeout15 s
RetentativasAté 3, intervalo de 300 s
SucessoHTTP 2xx encerra retentativas daquela URL

Headers

HeaderDescrição
X-REQUEST-IDUUID v4 (sempre) — único por tentativa de entrega
Authorization{tipo} {token} — somente se cadastrado e tipo != none

Payload — pagamento (efetivado)

Campo reservado: infoRecebedor: [] (sempre vazio). status sempre "EFETIVADO". motivo sempre null.

{
  "txid": null,
  "tpIniciacao": 1,
  "valor": "0.5",
  "chave": "[email protected]",
  "horario": "2026-07-09T14:36:52.134Z",
  "status": "EFETIVADO",
  "endToEndId": "E38297374202607091436QRJZZCLVR3H",
  "infoRecebedor": [],
  "bancoRecebedor": {
    "ispb": "38297374",
    "nome": "NUVENDE"
  },
  "nomeRecebedor": "Maria Recebedora Exemplo",
  "cpfRecebedor": "52998224725",
  "cnpjRecebedor": null,
  "bancoPagador": {
    "ispb": "38297374",
    "nome": "NUVENDE"
  },
  "nomePagador": "Guilherme Pagador Exemplo",
  "cpfPagador": "03015787020",
  "cnpjPagador": null,
  "devolucoes": [],
  "motivo": null
}

Payload — pagamento-falha

Mesma estrutura do efetivado, com diferenças:

CampoValor em pagamento-falha
statusSempre "ERRO"
motivoMensagem amigável
{
  "txid": null,
  "tpIniciacao": -1,
  "valor": "150.00",
  "chave": "[email protected]",
  "horario": "2026-09-16T12:10:00.000Z",
  "status": "ERRO",
  "endToEndId": "E38297374202609161210QRFalhaExemplo",
  "infoRecebedor": [],
  "bancoRecebedor": {
    "ispb": "38297374",
    "nome": "NUVENDE"
  },
  "nomeRecebedor": "Maria Recebedora Exemplo",
  "cpfRecebedor": "52998224725",
  "cnpjRecebedor": null,
  "bancoPagador": {
    "ispb": "38297374",
    "nome": "NUVENDE"
  },
  "nomePagador": "Guilherme Pagador Exemplo",
  "cpfPagador": "03015787020",
  "cnpjPagador": null,
  "devolucoes": [],
  "motivo": "Não foi possível concluir o pagamento: não há saldo suficiente na conta."
}

Mensagens típicas de motivo

Situação (interna)Exemplo de motivo
Sem saldoNão foi possível concluir o pagamento: não há saldo suficiente na conta.
Limite ultrapassadoNão foi possível concluir o pagamento: o limite de movimentação foi ultrapassado.
Movimentação não permitidaNão foi possível concluir o pagamento: o usuário não pode realizar esta movimentação.
OutrosDescrição do erro, como por exemplo Pagamento rejeitado pelo PSP do recebedor.

Referência de campos

CampoTipoDescrição
txidstring | nullID de conciliação do pagamento. null quando não houver
tpIniciacaointeger1 (ex.: transferência interna) ou -1 (débito). Não é o tipo SPI do recebimento (2, 3)
valornumber | stringValor (decimal). Pode vir como string ("0.5") ou número
chavestring | nullChave Pix do recebedor (destino). null em pagamento manual sem chave
horariodatetime ISO 8601Horário da operação
statusstring"EFETIVADO" (pagamento) ou "ERRO" (pagamento-falha)
endToEndIdstringIdentificador fim-a-fim (E2E)
infoRecebedorarrayReservado. Sempre [] nestes eventos
bancoPagador / bancoRecebedorobjectISPB e nome das instituições
nomePagador / nomeRecebedorstringNomes das partes
cpfPagador / cnpjPagadorstring | nullDocumento do pagador
cpfRecebedor / cnpjRecebedorstring | nullDocumento do recebedor
devolucoesarraySempre [] nestes eventos
motivostring | nullnull no efetivado; mensagem amigável na falha

No webhook de recebimento o campo reservado é infoPagador (não infoRecebedor).

Pontos de atenção

tpIniciacao

No evento pagamento / pagamento-falha, o campo não segue a mesma semântica do recebimento (QR estático 2, dinâmico 3). Valores já observados: 1 (transferência interna) e -1 (débito). Cruze chave, txid e endToEndId com o pagamento iniciado via API.

Chave do webhook vs chave do payload

ContextoSignificado de chave
URL .../webhooks/{chave} no cadastroQualquer chave da conta pagadora (integrador)
Campo chave no payloadChave Pix do recebedor (destino do pagamento)
EventoRegra de cadastro ({chave} na URL)
recebimentoWebhook na mesma chave do QR
pagamento / pagamento-falhaWebhook em qualquer chave da conta pagadora

Validar status e motivo

Cadastre URLs distintas (ou a mesma URL) para pagamento e pagamento-falha. Sempre valide status antes de operacionalizar: EFETIVADO confirma o débito; ERRO indica falha — use motivo para mensagem ao usuário/sistema, sem tratar como sucesso.

ISPB pode vir sem zero à esquerda

Se o ISPB não estiver na base de bancos conhecidos, bancoRecebedor.ispb / bancoPagador.ispb pode vir como número. Normalize para 8 dígitos ao conciliar.

Documentos

cpfRecebedor/cnpjRecebedor e cpfPagador/cnpjPagador são mutuamente exclusivos conforme o tipo de pessoa.

Idempotência no integrador (receptor)

Do lado da Nuvende, uma notificação de sucesso por URL para o mesmo pagamento — reprocessamentos internos não disparam POST duplicado se aquela URL já respondeu 2xx. Ainda assim, assuma retentativas HTTP e múltiplas URLs do mesmo evento.

Obrigação do integrador: idempotência no endpoint; validar status/motivo antes de efeitos internos.

Chave sugeridaQuando usar
endToEndId + statusPreferencial (distingue efetivado de falha)
txid + endToEndId + statusQuando txid estiver presente
X-REQUEST-IDRastreio por tentativa (complementar)

Práticas recomendadas:

  1. Persistência da chave de idempotência antes de responder 2xx.
  2. Repetição = no-op com resposta 2xx.
  3. Deduplicar no consumidor da fila.
  4. Concorrência: um único efeito por identificador + status.

Resposta do integrador

Responder HTTP 2xx (corpo opcional) o mais rápido possível — timeout de 15 s. Respostas ≥ 400, timeout ou erro de rede geram retentativa (até 3, intervalo 300 s) para aquela URL.

Resposta esperada

Qualquer status 2xx. Corpo vazio ou {} — ambos aceitos.

HTTP/1.1 200 OK

Relacionado

2025 © Nuvende - CNPJ 38.297.374/0001-93