Retiro vía PIX (cash-out) con seguridad: clave, código QR y lista blanca de IP

Cómo implementar pagos de salida con la API Pagnovo — cash-out por clave PIX o QR, lista blanca de IP, permisos, restricción de receptor y eventos de devolución.

Equipo Pagnovo · 2026-08-08

Recibir dinero es relativamente seguro: en el peor caso, el pago no ocurre. Enviar dinero es otra historia — un error aquí significa fondos saliendo de tu cuenta hacia el destino equivocado, muchas veces sin vuelta.

Esta guía cubre el cash-out de la API Pagnovo con el foco correcto: seguridad primero.

Referencia completa: portal.pagnovo.com/docs.

Dos formas de enviar

Por clave PIX (DICT)

POST /withdraws/cash-out

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

Por código QR

POST /withdraws/cash-out/qrc

Úsalo cuando el destinatario presenta un QR (un cobro de proveedor, por ejemplo) en vez de una clave.

Y para hacer seguimiento:

GET /withdraws/collect/:id   → estado y ciclo de vida del retiro

Las tres capas de protección

Lo que separa una integración de cash-out segura de un accidente esperando ocurrir:

1. Lista blanca de IP

Pagnovo permite restringir por IP las operaciones más sensibles — createWithdraw y createRefund. Con la lista configurada, una llamada desde cualquier otra IP recibe:

400 "IP unauthorized"

Eso significa que, incluso si tu clave se filtra, no puede mover dinero fuera de tus servidores. Es la protección con mejor costo-beneficio de toda la integración — configúrala antes de ir a producción.

Lista vacía = sin restricción. No la dejes así en producción.

2. Permisos mínimos en la clave

Cada clave lleva permisos: la lectura exige view<Recurso>, la escritura manage<Recurso>. Sin el permiso, la respuesta es 403 "Unauthorized Permissions".

Aprovéchalo: la clave que tu checkout usa para crear cobros no necesita poder retirar. Separa las claves por función. Si la del front se filtra, el daño es acotado.

3. restrictReceiverDocument

{ "restrictReceiverDocument": true }

Con esta bandera, el retiro solo se concreta si el CPF/CNPJ del titular de la clave coincide con lo esperado. Protege contra el escenario clásico de fraude: alguien cambia la clave PIX registrada y el dinero sale hacia otra persona.

Si pagas a proveedores o haces transferencias, úsala siempre.

El ciclo de vida y sus eventos

A diferencia del cash-in, el retiro tiene un estado más que necesita tratamiento:

Evento Significado Qué hacer
cashout.success Retiro concluido Registrarlo en tu sistema
cashout.failed Falló Investigar, notificar, permitir reintento
cashout.returned Devuelto Reacreditar e investigar

El cashout.returned es el que suele faltar en las integraciones. El dinero salió, fue rechazado por el destino (cuenta cerrada, clave inválida, devolución) y volvió. Si tu sistema no trata este evento, el saldo vuelve pero tu registro sigue diciendo "pagado" — y la diferencia solo aparece en la conciliación, días después.

El saldo que realmente puedes retirar

Antes de disparar un retiro, revisa el saldo — y léelo con atención:

GET /accounts/balance

La respuesta separa disponible, en liquidación, depósitos de garantía, bloqueos cautelares y reservas de contracargo. Solo el disponible puede retirarse.

Sumar todo e intentar retirar el total es camino garantizado al fallo — y peor, a prometerle a tu usuario un retiro que no va a ocurrir.

Idempotencia: crítica en cash-out

En cobros, un webhook duplicado genera trabajo repetido. En retiros, una petición duplicada genera dinero enviado dos veces.

Protégete antes de llamar a la API:

// Bloquea ANTES de disparar
const lock = await db.withdrawLocks.insertIfAbsent({
  key: `retiro:${usuarioId}:${solicitudId}`,
});
if (!lock) throw new Error('Retiro ya solicitado');

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

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

Reglas prácticas:

Aprobación humana para importes altos

No todo debe ser automático. Un patrón que evita perjuicios serios:

importe <= límite automático  → procesa directo
importe >  límite automático  → cola de aprobación humana

Suma a eso límites por período (diario/mensual) y alertas para patrones atípicos — muchos retiros pequeños en secuencia, retiro justo después de cambiar la clave registrada, retiro hacia una clave nunca usada antes.

Probar en el sandbox

Con sk_test_* puedes ejercitar los caminos de fallo sin riesgo. Prueba explícitamente:

Recuerda que el entorno de pruebas permite 30 operaciones por día (transacciones + retiros + reembolsos).

Checklist


Conoce nuestra API PIX, consulta la documentación de retiros y lee nuestra Política de Prevención de Fraude. Habla con el equipo.