PagnovoPagnovodocs

Referência da API

Saque por chave PIX

Envia uma transferência PIX para a chave do destinatário. Suporta CPF, CNPJ, telefone, e-mail e chave aleatória. A transferência é liquidada em tempo real pelo SPI do Bacen.

POST/withdraws/cash-out
IP allowlist obrigatório
Authorization API keys com a permissão `createWithdraw` precisam ser pareadas com IP allowlist no dashboard. Requisições de qualquer outro IP são rejeitadas com `400 IP unauthorized` mesmo que a chave seja válida. É a diferença entre 'fraude em cinco minutos' e 'fraude exige comprometer sua infraestrutura'.

Autenticação

HTTP Basic Auth. Envie sua secret key no header:

Authorization: Basic {base64(secret:SUA_SECRET_KEY)}

Parâmetros

amountnumberobrigatório

Valor do saque em centavos. Mínimo 1.

Exemplo: 10000

pixKeystringobrigatório

Chave PIX do destinatário. O formato depende de `pixType`.

Exemplo: maria@exemplo.com

pixType'CPF' | 'CNPJ' | 'PHONE' | 'EMAIL' | 'RANDOM'obrigatório

Tipo da chave PIX.

Exemplo: EMAIL

documentstringopcional

CPF/CNPJ esperado do destinatário. Se você também setar `restrictReceiverDocument: true`, a transferência só é executada quando o documento retornado pelo DICT bate com esse valor. Use para evitar pagamento à pessoa errada em caso de reatribuição de chave.

Exemplo: 98765432100

restrictReceiverDocumentbooleanopcional

Quando true, exige que o CPF/CNPJ resolvido pelo DICT bata com o campo `document`. Padrão: false.

Exemplo: true

externalIdstringopcional

Sua referência para esse saque (ID de payout, ID de lote etc). Retornada em webhooks e em `GET /withdraws/collect/:id?searchBy=externalId`.

Exemplo: saque-789

postbackUrlstringopcional

URL de webhook para eventos desse saque. Se omitido, usa a URL global.

Exemplo: https://seu-dominio.com/webhook

Body da requisição

Content-Type: application/json

JSON
{
  "amount": 10000,
  "pixKey": "maria@exemplo.com",
  "pixType": "EMAIL",
  "document": "98765432100",
  "restrictReceiverDocument": true,
  "externalId": "saque-789",
  "postbackUrl": "https://seu-dominio.com/webhook"
}

Respostas

201

Saque aceito. Status inicial é WITHDRAW_REQUEST. O resultado final chega por webhook em segundos (típico) a alguns minutos (pior caso).

JSON
{
  "id": "withdraw-id-1234",
  "externalId": "saque-789",
  "status": "WITHDRAW_REQUEST",
  "amount": 10000,
  "totalAmount": 10050,
  "institution": "ITAÚ UNIBANCO",
  "receiverPix": "maria@exemplo.com",
  "receiverName": "Maria Souza",
  "receiverDocument": "98765432100",
  "postbackUrl": "https://seu-dominio.com/webhook",
  "createdAt": "2026-04-08T15:00:00.000Z"
}
400

Body inválido, saldo insuficiente, IP fora do allowlist ou divergência em restrictReceiverDocument: true.

JSON
{
  "statusCode": 400,
  "message": "IP unauthorized"
}
401

API key inválida ou ausente.

JSON
{ "statusCode": 401, "message": "Unauthorized" }
403

API key sem a permissão createWithdraw.

JSON
{
  "statusCode": 403,
  "message": "You do not have permission to access this resource"
}

Exemplos

cURL
curl -X POST "https://api.pagnovo.com/withdraws/cash-out" \
  -H "Authorization: Basic $(echo -n 'secret:SUA_SECRET_KEY' | base64)" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 10000,
    "pixKey": "maria@exemplo.com",
    "pixType": "EMAIL",
    "document": "98765432100",
    "restrictReceiverDocument": true,
    "externalId": "saque-789"
  }'
JavaScript
const token = Buffer.from("secret:" + process.env.PAGNOVO_SECRET_KEY).toString("base64");

const res = await fetch("https://api.pagnovo.com/withdraws/cash-out", {
  method: "POST",
  headers: {
    Authorization: `Basic ${token}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    amount: 10000,
    pixKey: "maria@exemplo.com",
    pixType: "EMAIL",
    document: "98765432100",
    restrictReceiverDocument: true,
    externalId: "saque-789",
  }),
});

const traceId = res.headers.get("x-trace-id");

if (!res.ok) {
  const err = await res.json();
  throw new Error(`saque falhou: ${err.message} (trace: ${traceId})`);
}

const w = await res.json();
console.log("id do saque:", w.id, "status inicial:", w.status);
// resultado final chega via webhook cashout.success / cashout.failed