Guía de Integración para Desarrolladores
API Payins (depósitos CIP + QR) · API Payouts CCI · v1 · 2026
Bienvenido a PagoDirecto. Esta guía te explica todo lo necesario para integrar cobros (Payins) y desembolsos (Payouts) en tu plataforma. Cada sección incluye el flujo completo, los campos requeridos y ejemplos listos para usar.
Incluye tu API key en el header de cada solicitud.
Authorization: Bearer {TU_API_KEY} Content-Type: application/json
Tu API key te la proporciona el equipo de PagoDirecto durante el proceso de onboarding. La misma key también autentica los callbacks que PD envía a tu servidor.
Tres modalidades de pago. Un único endpoint. Elige según tu caso de uso.
La API Payins permite a tus usuarios pagar dinero directamente desde sus cuentas bancarias o billetera digital. No requiere tarjeta de crédito. Tienes 3 modalidades que funcionan con el mismo endpoint:
Selecciona qué método usar con el parámetro deposit_channel.
💳 Modalidad 1: CIP Bancario
Usuario ingresa código de pago (20 dígitos) en su app bancaria, agente ATM o ventanilla.
Ideal para: E-commerce, pagos remotos, cualquier canal donde el usuario está en su dispositivo.
🔲 Modalidad 2: Código QR Dinámico
Usuario escanea QR con su app bancaria. Pago confirmado en 3 segundos.
Ideal para: Punto de venta presencial, kioscos, restaurantes, tiendas, máquinas expendedoras.
⚡ Modalidad 3:Yape Onfile
Sistema debita automáticamente desde Yape. Si no está suscrito, lo afilia primero.
Ideal para: Suscripciones, pagos recurrentes, membresías, plataformas SaaS.
Un único endpoint para los 3. Solo cambia el parámetro deposit_channel. El resto del flujo (request, response, webhook) es idéntico.
4 pasos simples — igual para CIP, QR y Yape On File. Solo cambia cómo paga el usuario.
bcp, yape, qr, etc.)payment_id y payment_token. Usa el token en el iframe para mostrar instrucciones.callback_url con el resultado final. Actúa solo cuando payment_status = 4 (confirmado).¿Y si no quiero esperar? Puedes consultar el estado en cualquier momento con GET /payins/{payment_id}
Un endpoint, tres canales. Elige el canal en deposit_channel y deja que tu usuario pague.
📤 Endpoint REQUEST
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| payment_reference_code | string | SÍ | Tu identificador único para este pago. |
| payment_amount | string | SÍ | Monto en dígitos. Los últimos 2 son centavos: "10050" = PEN 100.50 |
| payment_currency | string | SÍ | PEN o USD |
| client_email | string | SÍ | Email del usuario. PD envía aquí la confirmación de pago. |
| payment_concept | string | NO | Descripción del pago. |
| payment_expire_date | timestamp | NO | Expiración en Unix timestamp. Si se omite, PD aplica un TTL por defecto. |
| client_name | string | NO | Nombre del usuario. |
| client_id_type | string | NO | DNI o CE |
| client_id_number | string | NO | Número de documento. |
| client_city | string | NO | Ciudad del usuario. |
| client_province | string | NO | Provincia o región. |
| client_country_code | string | NO | Código de país ISO. Ej: PE |
| client_phone_mobile | string | NO | Celular del usuario. |
| deposit_channel | string | NO | Canal de pago. Ver tabla abajo. Si se omite, el iframe muestra todos los canales. |
| callback_url | string | NO | URL donde PD enviará las notificaciones de estado. |
| metadata | object | NO | Datos adicionales clave-valor. PD los reenvía en los callbacks sin modificarlos. |
Canales disponibles
| deposit_channel | Tipo | Canal | Descripción |
|---|---|---|---|
bcp | CIP | BCP | App, agente o ventanilla BCP. |
bbva | CIP | BBVA | App o agente BBVA. |
ibk | CIP | Interbank | App o agente Interbank. |
yape | CIP | Yape | Billetera Yape. |
yapeof | CIP | Yape On File | Débito automático desde Yape. |
qr | QR | QR | QR dinámico. Pago inmediato. Ideal para punto de venta y kiosco. |
Ejemplo — CIP (Yape)
{
"payment_reference_code": "ORDER-001",
"payment_currency": "PEN",
"payment_amount": "10050", // PEN 100.50
"client_email": "usuario@correo.com",
"deposit_channel": "yape",
"callback_url": "https://tuapp.com/webhooks/payins"
}
Ejemplo — QR
{
"payment_reference_code": "CAJA-001",
"payment_currency": "PEN",
"payment_amount": "15075", // PEN 150.75
"client_email": "usuario@correo.com",
"deposit_channel": "qr", // ← activa QR dinámico
"callback_url": "https://tuapp.com/webhooks/payins"
}
{
"object": "payins",
"payment_id": 4005197,
"payment_token": "72c925c3-e002-f111-b905-000d3a42271a"
}
Mismo token para CIP y QR. El payment_token funciona igual en ambas modalidades. El iframe detecta el canal y muestra automáticamente el código CIP o el QR.
{
"status": 400,
"error_type": "parameter_error",
"params": [
{ "param": "payment_currency", "user_message": "value is empty" }
]
}
Obtén el estado y datos completos de un voucher en cualquier momento.
📥 Endpoint REQUEST
{
"object": "payins",
"payment_status": 4, // ← campo clave
"payment_paid_date": "2024-11-23T14:30:00Z", // null si pendiente
"payment_reference_code": "ORDER-001",
"payment_currency": "PEN",
"payment_amount": "10050",
"payment_concept": "Pago por Orden #001",
"client_name": "Carlos Gómez",
"client_email": "usuario@correo.com",
"metadata": { "order_id": "001" }
}
Mostrar Voucher al Usuario
Dos formas de presentar las instrucciones de pago: iframe embebido o página HTML directa.
| Método | URL | Ideal para |
|---|---|---|
| iFrame RECOMENDADO | https://payment.sandbox.demo/payins/{token} |
Checkout web, embebido en tu página |
| HTML directo | GET https://api.sandbox.demo/payinspayins/{token} |
Apps móviles con WebView, pantallas dedicadas |
Ambas opciones muestran el mismo contenido: instrucciones CIP con datos bancarios, o el QR escaneable según el canal seleccionado al crear el voucher.
PD envía un POST a tu callback_url cada vez que el estado del pago cambia. El formato es el mismo para CIP y QR.
Verificación: Cada callback incluye tu API key en el header Authorization. Verifica siempre que coincida antes de procesar el evento.
POST /webhooks/payins HTTP/1.1 Authorization: Bearer {TU_API_KEY} { "payment_id": 4005197, "payment_status": 4, // ✅ Pago confirmado "payment_reference_code": "ORDER-001", "payment_amount": "10050", "payment_currency": "PEN", "metadata": { "order_id": "001" } }
Reintentos automáticos: Si tu endpoint no responde o devuelve un error, PD reintenta la entrega. Tu handler debe ser idempotente y responder siempre con HTTP 200.
El campo payment_status aplica igual para CIP y QR.
| Valor | Estado | Descripción | ¿Final? |
|---|---|---|---|
1 | Created | Voucher generado. Esperando pago del usuario. | Intermedio |
3 | Paid | Pago recibido por el banco. PD está conciliando. | Intermedio |
4 | Confirmed | ✅ Pago confirmado. Activa tu lógica de negocio. | ✓ Final |
98 | Expired | El voucher venció sin recibir pago. | ✓ Final |
99 | Canceled | Voucher cancelado. | ✓ Final |
Actúa solo cuando payment_status = 4. Los estados 98 y 99 son terminales — el usuario debe iniciar un pago nuevo.
Flujo A — CIP Bancario (Yape)
{ "payment_reference_code": "TXN-001", "payment_amount": "15000",
"payment_currency": "PEN", "client_email": "usuario@correo.com",
"deposit_channel": "yape", "callback_url": "https://tuapp.com/webhooks/payins" }
https://payment.sandbox.demo/payins/{payment_token}{ "payment_status": 4 } // ✅ Confirmar y acreditarFlujo B — QR (Punto de venta)
{ "payment_reference_code": "CAJA-001", "payment_amount": "15075",
"payment_currency": "PEN", "client_email": "usuario@correo.com",
"deposit_channel": "qr", "callback_url": "https://tuapp.com/webhooks/payins" }
https://payment.sandbox.demo/payins/{payment_token}{ "payment_status": 4 } // ✅ Venta confirmadaDébito automático desde Yape con validación inteligente de suscripción.
Yape On File es un método de pago que automatiza el flujo de cobro usando Yape. Lo especial es que tu sistema invoca un único endpoint, y PagoDirecto internamente:
- Valida si el usuario ya está suscrito a débitos automáticos.
- Si no está suscrito: inicia el proceso de afiliación automáticamente y luego ejecuta el pago.
- Si ya está suscrito: ejecuta el pago de inmediato.
- El resultado final llega vía webhook/callback de forma asíncrona.
Un endpoint, dos flujos internos. No necesitas escribir lógica condicional. Solo llamas al endpoint una vez y PD maneja automáticamente la afiliación si es necesaria.
Flujo de procesamiento
El sistema entiende automáticamente si necesita afiliación. Tú invocas un único endpoint.
deposit_channel: "yapeof". PagoDirecto recibe la solicitud y genera un payment_id.callback_url con el estado final.Endpoint — Crear pago con Yape On File
Usa el mismo endpoint de Payins. Solo cambia el campo deposit_channel.
{
"payment_reference_code": "SUB-2024-001",
"payment_currency": "PEN",
"payment_amount": "15000", // PEN 150.00
"client_email": "usuario@correo.com",
"client_name": "Juan Pérez",
"deposit_channel": "yapeof", // ← Yape On File
"callback_url": "https://tuapp.com/webhooks/payins"
}
{
"object": "payins",
"payment_id": 4005200,
"payment_token": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Respuesta inmediata vs. resultado final
📤 Response API (201)
Recibida inmediatamente cuando llamas al endpoint.
↓
Flujo iniciado
⚠️ No indica resultado final
📡 Webhook (callback)
Enviado de forma asíncrona cuando el pago se completa.
↓
Pago confirmado ✅
✅ Resultado definitivo
Estados del flujo Yape On File
| Estado | Significado | ¿Qué significa? | ¿Final? |
|---|---|---|---|
1 | Created | Flujo iniciado. Sistema validando suscripción. | Intermedio |
2 | Subscription Required | Usuario no suscrito. Afiliación en progreso. | Intermedio |
3 | Paid | Pago recibido. PD conciliando con Yape. | Intermedio |
4 | Confirmed | ✅ Pago confirmado. Acredita al usuario. | ✓ Final |
98 | Expired | Flujo expiró sin completarse. | ✓ Final |
99 | Canceled | Usuario o sistema canceló el flujo. | ✓ Final |
Ejemplos Completos
Ejemplo 1 — Usuario Nuevo (con Afiliación)
Usuario instala tu app por primera vez. No tiene débitos automáticos autorizados en Yape.
{ "payment_reference_code": "NEW-USER-001", "payment_amount": "20000",
"payment_currency": "PEN", "client_email": "juan@correo.com",
"deposit_channel": "yapeof", "callback_url": "https://tuapp.com/webhooks/payins" }
{ "payment_status": 4, "payment_reference_code": "NEW-USER-001" }
// ✅ Acredita al usuario PEN 200.00Tiempo total: ~2-5 minutos. El usuario autoriza en Yape (1-2 min), el pago se procesa (30 segundos a 2 minutos).
Ejemplo 2 — Usuario ya Afiliado (flujo rápido)
Usuario ya autorizó débitos automáticos anteriormente. Esta vez solo se ejecuta el pago.
{ "payment_reference_code": "RECURRENT-001", "payment_amount": "15000",
"payment_currency": "PEN", "client_email": "juan@correo.com",
"deposit_channel": "yapeof", "callback_url": "https://tuapp.com/webhooks/payins" }
{ "payment_status": 4, "payment_reference_code": "RECURRENT-001" }
// ✅ Acredita al usuario PEN 150.00Tiempo total: ~30 segundos a 2 minutos. Sin interacción del usuario, ejecución pura automática.
Ejemplo 3 — Error de Validación
Datos inválidos, fondos insuficientes, o cuenta desactivada.
{ "payment_status": 99, "payment_reference_code": "FAILED-001",
"payment_notes": "Yape account not found or inactive" }
// ❌ Pago canceladopayment_notes). Opcionalmente, ofrece reintentar con otros canales (CIP, QR).Espera solo webhooks con status final. Los estados intermedios (1, 2, 3) no generan callback. Actúa solo cuando recibas status 4 (confirmado) o estados de error 98, 99.
Envía dinero directamente a cuentas bancarias peruanas usando el CCI.
La API Payouts te permite desembolsar fondos a cualquier cuenta bancaria peruana usando el CCI (Código de Cuenta Interbancario) — el número interbancario estándar de 20 dígitos.
Casos de uso:
- Pagos a vendedores de un marketplace.
- Comisiones o pagos de afiliados.
- Reembolsos a clientes.
- Planillas o desembolsos masivos.
201 Created. El payment_id viene en el header Location — sin body.Archive) o fallo (Void). Los estados intermedios no generan callback.📤 Endpoint REQUEST
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| payment_reference | string | SÍ | Tu identificador único para este payout. |
| customer_name | string | SÍ | Nombre completo del destinatario. |
| customer_id_type | string | SÍ | Tipo de documento: DNI, CE o Pasaporte |
| customer_id_number | string | SÍ | Número de documento. |
| account_cci | string (20 dígitos) | SÍ | CCI de la cuenta bancaria destino. |
| account_currency | string | SÍ | Moneda de la cuenta: SOLES o USD |
| payment_amount | string | SÍ | Monto con 2 decimales. Ej: "150.00" |
| payment_currency | string | SÍ | Moneda del pago: PEN o USD |
| customer_email | string | NO | Email del destinatario. |
| customer_reference | string | NO | Tu referencia interna del cliente. |
| callback_url | string | NO | URL donde PD enviará la notificación del resultado. |
{
"payment_reference": "PAYOUT-001",
"customer_name": "María Torres Flores",
"customer_id_type": "DNI",
"customer_id_number": "12345678",
"account_cci": "00219213866047808638",
"account_currency": "SOLES",
"payment_amount": "150.00",
"payment_currency": "PEN",
"callback_url": "https://tuapp.com/webhooks/payouts"
}
Location: https://api.sandbox.demo/payouts/5574127 // Sin body. El payment_id es el número al final del path → 5574127
Importante: La respuesta exitosa no tiene body. Extrae el payment_id del header Location y guárdalo de inmediato.
{
"message": "Validation Failed",
"errors": [
{ "field": "payment_amount", "message": "Amount can not be empty" },
{ "field": "payment_currency", "message": "Currency can not be empty" }
]
}
{
"payment_id": "5574127",
"payment_reference": "PAYOUT-001",
"payment_amount": "150.00",
"payment_currency": "PEN",
"payment_status": "5", // ← estado operativo
"payment_final_status": "1", // ← estado contable
"payment_notes": "Transferencia completada exitosamente.",
"customer_name": "María Torres Flores",
"account_cci": "00219213866047808638"
}
PD notifica solo cuando el payout llega a un estado final. Los estados intermedios no generan callback.
{ "payment_status": "5", "payment_final_status": "1",
"payment_notes": "Transferencia completada." } // ✅
{ "payment_status": "6", "payment_final_status": "2",
"payment_notes": "Bank account validation failed." } // ❌
Cuando el payout falla (payment_status = 6), revisa payment_notes — contiene la razón del fallo (cuenta inexistente, validación fallida, etc.).
Estado operativo — payment_status
| Valor | Estado | Descripción | ¿Final? |
|---|---|---|---|
1 | Pending | En revisión. No reenvíes — espera el callback. | Intermedio |
2 | Process | Encolado para procesamiento. | Intermedio |
4 | Sent | Enviado al banco, esperando confirmación. | Intermedio |
5 | Archive | ✅ Transferencia completada. | ✓ Final |
6 | Void | ❌ Transferencia fallida. Ver payment_notes. | ✓ Final |
Estado contable — payment_final_status
| Valor | Estado | Descripción |
|---|---|---|
3 | Not Set | Payout en proceso, aún no liquidado. |
1 | Captured | Fondos entregados correctamente. |
2 | Cancelled | Fondos no entregados. |
Marketplace paga PEN 150.00 a la cuenta BCP de un vendedor.
{ "payment_reference": "PAYOUT-001",
"customer_name": "María Torres Flores", "customer_id_type": "DNI",
"customer_id_number": "12345678", "account_cci": "00219213866047808638",
"account_currency": "SOLES", "payment_amount": "150.00", "payment_currency": "PEN",
"callback_url": "https://tuapp.com/webhooks/payouts" }
{ "payment_status": "5", "payment_final_status": "1" } // ✅Cuentas CCI de estos bancos pueden recibir desembolsos vía API Payouts.