Referência: webhooks Pix
Resposta rápida: Registre a URL com
PUT /webhook/{chave}e leia de volta comGET; o BACEN acrescenta/pixao caminho registrado, o payload chega em mais de um formato e a autenticação é por secret na URL ou em header — não há assinatura.
Endpoints
| Método | Path | Uso |
|---|---|---|
| PUT | /webhook/{chave} | Registrar a URL de notificação da chave Pix |
| GET | /webhook/{chave} | Ler o que está registrado |
| DELETE | /webhook/{chave} | Remover o registro |
O registro é por chave Pix, não por aplicação. Uma chave, uma URL. Recursos de recorrência (Pix Automático) têm webhooks próprios e independentes destes — fora do escopo deste pack.
O sufixo /pix
O BACEN acrescenta /pix ao caminho registrado. Registrando https://seu.app/webhooks/psp, a entrega chega em https://seu.app/webhooks/psp/pix.
Consequência prática: as duas rotas precisam existir. A base serve o probe do registro; a com /pix recebe as entregas. Se a base não responde, o PUT pode falhar; se a de entrega não responde, todo callback vira 404.
Payload: não assuma um formato só
O padrão BACEN descreve {"pix": [ { "endToEndId": ..., "txid": ..., "valor": ..., "horario": ... } ]}. Em produção também chegam:
- o objeto pix plano na raiz, sem o array;
- um envelope
{"type": "...", "data": { ... }}.
Um parser que aceita só o formato do padrão descarta os outros em silêncio e ainda responde 200 — o que cancela o retry do PSP e transforma pagamento recebido em pedido travado. Trate os três formatos, e logue o shape do body (as chaves de primeiro nível) quando nenhum casar.
Autenticação: secret, não assinatura
Não há cabeçalho de assinatura. Dois caminhos funcionam:
| Caminho | Nota |
|---|---|
| Secret na query string da URL registrada | Sobrevive ao round-trip do PUT; o GET devolve a URL com o parâmetro intacto |
Header combinado (ex.: x-webhook-secret) | Mais limpo; depende de o canal permitir header customizado |
O secret é filtro, não prova. Antes de creditar qualquer coisa, confirme a liquidação com GET /pix/{endToEndId} autenticado. Assim um webhook forjado não faz nada além de provocar uma releitura da verdade.
Entregas repetidas
O PSP pode entregar o mesmo evento mais de uma vez para um único pagamento. Idempotência por endToEndId é obrigatória, e o teste dela é parte do happy path, não um extra.
Canal do painel pausa sozinho
Quando o registro também existe no painel do banco, o formulário traz "pausar envio de webhooks ao detectar falha" marcado por padrão. Uma falha — um 404 do sufixo, um deploy fora do ar — desliga o canal, e daí em diante o silêncio é indistinguível de "o banco nunca tentou". Ao investigar entrega ausente, cheque se o canal foi pausado antes de suspeitar da rede.
Contrato
Notas Modobank
- Registro via API funciona e é o caminho recomendável; o painel tem canais próprios da API de contas (saldo, extrato, pagamentos) que não são o webhook de cobrança.
- Stubs locais:
snippets/node/webhook-receiver.mjs,snippets/python/webhook_receiver.py.