Saque via PIX (cash-out) com segurança: chave, QR Code e allowlist de IP

Como implementar pagamentos de saída pela API Pagnovo — cash-out por chave PIX ou QR, allowlist de IP, escopos, restrição de recebedor e eventos de retorno.

Equipe Pagnovo · 2026-08-08

Receber dinheiro é relativamente seguro: no pior caso, o pagamento não acontece. Enviar dinheiro é outra história — um erro aqui significa recurso saindo da sua conta para o destino errado, muitas vezes sem volta.

Este guia cobre o cash-out da API Pagnovo com o foco certo: segurança primeiro.

Referência completa: portal.pagnovo.com/docs.

Duas formas de enviar

Por chave PIX (DICT)

POST /withdraws/cash-out

{
  "amount": 50000,
  "pixKey": "destinatario@email.com",
  "restrictReceiverDocument": true
}

Por QR Code

POST /withdraws/cash-out/qrc

Use quando o destinatário apresenta um QR (cobrança de fornecedor, por exemplo) em vez de uma chave.

E, para acompanhar:

GET /withdraws/collect/:id   → status e ciclo de vida do saque

As três camadas de proteção

O que separa uma integração de cash-out segura de um acidente esperando para acontecer:

1. Allowlist de IP

A Pagnovo permite restringir por IP as operações mais sensíveis — createWithdraw e createRefund. Com a lista configurada, uma chamada vinda de qualquer outro IP recebe:

400 "IP unauthorized"

Isso significa que, mesmo se a sua chave vazar, ela não consegue movimentar dinheiro fora dos seus servidores. É a proteção com melhor custo-benefício de toda a integração — configure antes de ir para produção.

Lista vazia = sem restrição. Não deixe assim em produção.

2. Escopos mínimos na chave

Cada chave carrega escopos: leitura exige view<Recurso>, escrita exige manage<Recurso>. Sem o escopo, a resposta é 403 "Unauthorized Permissions".

Aproveite isso: a chave que o seu checkout usa para criar cobranças não precisa poder sacar. Separe as chaves por função. Se a do front-end vazar, o estrago é limitado.

3. restrictReceiverDocument

{ "restrictReceiverDocument": true }

Com essa flag, o saque só é concluído se o CPF/CNPJ do titular da chave bater com o esperado. Protege contra o cenário clássico de fraude: alguém troca a chave PIX cadastrada e o dinheiro sai para outra pessoa.

Se você paga fornecedores ou faz repasses, use sempre.

O ciclo de vida e os eventos

Diferente do cash-in, o saque tem um estado a mais que precisa de tratamento:

Evento Significado O que fazer
cashout.success Saque concluído Baixar no seu sistema
cashout.failed Falhou Investigar, notificar, permitir nova tentativa
cashout.returned Devolvido Recreditar e investigar

O cashout.returned é o que costuma faltar nas integrações. O dinheiro saiu, foi rejeitado pelo destino (conta encerrada, chave inválida, devolução) e voltou. Se o seu sistema não trata esse evento, o saldo volta mas o seu registro continua dizendo "pago" — e a diferença só aparece na conciliação, dias depois.

O saldo que você pode sacar

Antes de disparar um saque, cheque o saldo — e leia com atenção:

GET /accounts/balance

A resposta separa disponível, em liquidação, depósitos de garantia, bloqueios cautelares e reservas de chargeback. Apenas o disponível pode ser sacado.

Somar tudo e tentar sacar o total é caminho garantido para falha — e, pior, para prometer ao seu usuário um saque que não vai acontecer.

Idempotência: crítico em cash-out

Em cobranças, um webhook duplicado gera trabalho repetido. Em saques, uma requisição duplicada gera dinheiro enviado duas vezes.

Proteja-se antes de chamar a API:

// Trave ANTES de disparar
const lock = await db.withdrawLocks.insertIfAbsent({
  key: `saque:${usuarioId}:${solicitacaoId}`,
});
if (!lock) throw new Error('Saque já solicitado');

const saque = await pagnovo.post('/withdraws/cash-out', {
  amount, pixKey, restrictReceiverDocument: true,
});

await db.withdraws.save({ ...saque, traceId: response.headers['x-trace-id'] });

Regras práticas:

Aprovação humana para valores altos

Nem tudo deve ser automático. Um padrão que evita prejuízos sérios:

valor <= limite automático  → processa direto
valor >  limite automático  → fila de aprovação humana

Some a isso limites por período (diário/mensal) e alerta para padrões atípicos — muitos saques pequenos em sequência, saque logo após troca de chave cadastrada, saque para chave nunca usada antes.

Testando no sandbox

Com sk_test_*, você pode exercitar os caminhos de falha sem risco. Teste explicitamente:

Lembre que o ambiente de teste permite 30 operações por dia (transações + saques + estornos).

Checklist


Conheça nossa API PIX, veja a documentação de saques e leia nossa Política de Prevenção à Fraude. Fale com o time.