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.

Autenticación

Incluye tu API key en el header de cada solicitud.

HTTP HEADER
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.


API Payins — Cobros
01 Overview

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:


02 Modalidades de Pago

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.

Bancos soportados: BCP, BBVA, Interbank, Yape, BANBIF.

Ideal para: E-commerce, pagos remotos, cualquier canal donde el usuario está en su dispositivo.

deposit_channel: bcp deposit_channel: bbva deposit_channel: yape

🔲 Modalidad 2: Código QR Dinámico

Usuario escanea QR con su app bancaria. Pago confirmado en 3 segundos.

Compatible con: Todas las apps bancarias, Yape, Plin, etc.

Ideal para: Punto de venta presencial, kioscos, restaurantes, tiendas, máquinas expendedoras.

deposit_channel: qr

⚡ Modalidad 3:Yape Onfile

Sistema debita automáticamente desde Yape. Si no está suscrito, lo afilia primero.

Un endpoint, dos flujos: Afiliación automática + pago recurrente

Ideal para: Suscripciones, pagos recurrentes, membresías, plataformas SaaS.

deposit_channel: yapeof
💡

Un único endpoint para los 3. Solo cambia el parámetro deposit_channel. El resto del flujo (request, response, webhook) es idéntico.

03 Flujo General

4 pasos simples — igual para CIP, QR y Yape On File. Solo cambia cómo paga el usuario.

PASO 1
🏪
Crear solicitud de pago
Tu backend invoca el endpoint con monto, usuario y canal (bcp, yape, qr, etc.)
POST /payins
PASO 2
🔑
Recibe token de pago
PagoDirecto devuelve payment_id y payment_token. Usa el token en el iframe para mostrar instrucciones.
● CREATED
PASO 3
💳
Usuario paga
Según el canal: ingresa CIP en app bancaria, escanea QR, o débito automático (Yape On File). Confirmación en segundos a minutos.
App bancaria / ATM QR Automático
PASO 4
📡
Recibes notificación (webhook)
PagoDirecto envía un POST a tu callback_url con el resultado final. Actúa solo cuando payment_status = 4 (confirmado).
● CONFIRMED (4)
💡

¿Y si no quiero esperar? Puedes consultar el estado en cualquier momento con GET /payins/{payment_id}

04 Crear Pago — POST /

Un endpoint, tres canales. Elige el canal en deposit_channel y deja que tu usuario pague.

📤 Endpoint REQUEST

POST https://api.sandbox.demo/payins
CampoTipoRequeridoDescripción
payment_reference_codestringTu identificador único para este pago.
payment_amountstringMonto en dígitos. Los últimos 2 son centavos: "10050" = PEN 100.50
payment_currencystringPEN o USD
client_emailstringEmail del usuario. PD envía aquí la confirmación de pago.
payment_conceptstringNODescripción del pago.
payment_expire_datetimestampNOExpiración en Unix timestamp. Si se omite, PD aplica un TTL por defecto.
client_namestringNONombre del usuario.
client_id_typestringNODNI o CE
client_id_numberstringNONúmero de documento.
client_citystringNOCiudad del usuario.
client_provincestringNOProvincia o región.
client_country_codestringNOCódigo de país ISO. Ej: PE
client_phone_mobilestringNOCelular del usuario.
deposit_channelstringNOCanal de pago. Ver tabla abajo. Si se omite, el iframe muestra todos los canales.
callback_urlstringNOURL donde PD enviará las notificaciones de estado.
metadataobjectNODatos adicionales clave-valor. PD los reenvía en los callbacks sin modificarlos.

Canales disponibles

deposit_channelTipoCanalDescripción
bcpCIPBCPApp, agente o ventanilla BCP.
bbvaCIPBBVAApp o agente BBVA.
ibkCIPInterbankApp o agente Interbank.
yapeCIPYapeBilletera Yape.
yapeofCIPYape On FileDébito automático desde Yape.
qrQRQRQR dinámico. Pago inmediato. Ideal para punto de venta y kiosco.

Ejemplo — CIP (Yape)

POST /
{
  "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

POST / · 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"
}
Response · 201 Created
{
  "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.

Response · 400 — Validación
{
  "status":     400,
  "error_type": "parameter_error",
  "params": [
    { "param": "payment_currency", "user_message": "value is empty" }
  ]
}
05 Consultar Estado — GET /{payment_id}

Obtén el estado y datos completos de un voucher en cualquier momento.

📥 Endpoint REQUEST

GET https://api.sandbox.demo/payins{payment_id}
Response · 200 OK
{
  "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étodoURLIdeal 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.

06 Callbacks

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.

Webhook entrante
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.

07 Estados

El campo payment_status aplica igual para CIP y QR.

ValorEstadoDescripción¿Final?
1CreatedVoucher generado. Esperando pago del usuario.Intermedio
3PaidPago recibido por el banco. PD está conciliando.Intermedio
4Confirmed✅ Pago confirmado. Activa tu lógica de negocio.✓ Final
98ExpiredEl voucher venció sin recibir pago.✓ Final
99CanceledVoucher cancelado.✓ Final
🔴

Actúa solo cuando payment_status = 4. Los estados 98 y 99 son terminales — el usuario debe iniciar un pago nuevo.

08 Ejemplos Completos

Flujo A — CIP Bancario (Yape)

1 · Crear voucher
POST /
{ "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" }
● 201 CREATED
2 · Mostrar iFrame al usuario
iFrame
https://payment.sandbox.demo/payins/{payment_token}
3 · Usuario paga con Yape
El usuario sigue las instrucciones del iframe y completa el pago desde su app Yape.
4 · Recibes el callback → acreditas al usuario
Webhook
{ "payment_status": 4 } // ✅ Confirmar y acreditar

Flujo B — QR (Punto de venta)

1 · Crear voucher QR
POST /
{ "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" }
● 201 CREATED
2 · Mostrar QR en pantalla de caja
iFrame
https://payment.sandbox.demo/payins/{payment_token}
3 · Cliente escanea el QR
El cliente escanea con su app bancaria (BCP, BBVA, Yape…). Pago confirmado en segundos.
4 · Recibes el callback → confirmas la venta
Webhook
{ "payment_status": 4 } // ✅ Venta confirmada

Método Especial — Yape On File
¿Qué es Yape On File?

Dé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.

PASO 1 · Tu Backend → PagoDirecto
🏪
Invocas endpoint con yapeof
Llamas al endpoint de Payins con deposit_channel: "yapeof". PagoDirecto recibe la solicitud y genera un payment_id.
POST /payins deposit_channel: yapeof
PASO 2 · PagoDirecto valida suscripción
🔍
Decisión automática interna
PagoDirecto valida si el usuario ya está suscrito a débitos automáticos en Yape. Aquí ocurre la magia: el sistema decide qué flujo seguir sin que tú hagas nada.
● SUBSCRIPTION_CHECK
PASO 3A · Si NO está suscrito
📱
Inicia afiliación automática
Se inicia el flujo de afiliación a débitos automáticos. El usuario autoriza en Yape. Al terminar, se ejecuta automáticamente el pago.
● SUBSCRIPTION_REQUIRED → Subscription Flow
PASO 3B · Si YA está suscrito
Ejecuta pago directo
No necesita afiliación. El sistema ejecuta el débito automático de inmediato en la cuenta Yape del usuario.
→ Direct Deposit Flow
PASO 4 · PagoDirecto → Tu Backend
📡
Notificación con resultado final
Cuando el pago se completa (hayan pasado 30 segundos o varios minutos), PD envía un webhook a tu callback_url con el estado final.
● CONFIRMED (4) = Éxito ● CANCELED (99) = Fallo

Endpoint — Crear pago con Yape On File

Usa el mismo endpoint de Payins. Solo cambia el campo deposit_channel.

POST /
{
  "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"
}
Response · 201 Created
{
  "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.

payment_id + token

Flujo iniciado

⚠️ No indica resultado final

📡 Webhook (callback)

Enviado de forma asíncrona cuando el pago se completa.

payment_status: 4

Pago confirmado ✅

✅ Resultado definitivo

Estados del flujo Yape On File

EstadoSignificado¿Qué significa?¿Final?
1CreatedFlujo iniciado. Sistema validando suscripción.Intermedio
2Subscription RequiredUsuario no suscrito. Afiliación en progreso.Intermedio
3PaidPago recibido. PD conciliando con Yape.Intermedio
4Confirmed✅ Pago confirmado. Acredita al usuario.✓ Final
98ExpiredFlujo expiró sin completarse.✓ Final
99CanceledUsuario 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.

1 · Tu backend invoca endpoint
POST /payins
{ "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" }
● 201 CREATED
2 · Sistema detecta: usuario NO suscrito
PagoDirecto valida internamente. Resultado: usuario no tiene débitos automáticos activados. Inicia afiliación automática.
3 · Usuario autoriza afiliación en Yape
En segundo plano, PD abre el flujo de afiliación en Yape. El usuario ve: "Autorizar débitos automáticos para [Tu App]". Presiona OK.
User action: Yape app authorization
4 · Afiliación completa → Pago se ejecuta
Una vez autorizado, el sistema ejecuta automáticamente el débito de PEN 200.00 desde Yape.
● DEPOSIT_PROCESSING
5 · Recibes webhook con resultado final
Webhook
{ "payment_status": 4, "payment_reference_code": "NEW-USER-001" }
// ✅ Acredita al usuario PEN 200.00
⏱️

Tiempo 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.

1 · Tu backend invoca endpoint (idéntico)
POST /payins
{ "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" }
● 201 CREATED
2 · Sistema detecta: usuario YA suscrito
PagoDirecto valida internamente. Resultado: usuario ya tiene débitos automáticos activados. Omite afiliación y procede directo.
3 · Pago ejecuta de inmediato
Sin necesidad de que el usuario haga nada. El sistema debita PEN 150.00 automáticamente de su Yape.
● DEPOSIT_PROCESSING
4 · Recibes webhook 30 seg - 2 min después
Webhook
{ "payment_status": 4, "payment_reference_code": "RECURRENT-001" }
// ✅ Acredita al usuario PEN 150.00

Tiempo 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.

1 · Invocas endpoint
Tu backend envía solicitud de pago.
2 · Validación falla
Posibles razones: Email incorrecto, usuario Yape desactivado, fondos insuficientes, límite de débito excedido, etc.
3 · Recibes webhook con error
Webhook
{ "payment_status": 99, "payment_reference_code": "FAILED-001",
  "payment_notes": "Yape account not found or inactive" }
// ❌ Pago cancelado
4 · Tu acción
Informa al usuario del problema específico (ver payment_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.


API Payouts — Desembolsos
01 Qué es

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.
02 Flujo
PASO 1 · Tu Backend → PagoDirecto
📤
Enviar solicitud de desembolso
Envías los datos del destinatario (nombre, documento, CCI) y el monto.
POST /api/payouts account_cci payment_amount
PASO 2 · PagoDirecto valida y encola
⚙️
PD confirma la recepción
PD valida los datos y devuelve 201 Created. El payment_id viene en el header Location — sin body.
Location: /api/payouts/{id} ● QUEUED
PASO 3 · PagoDirecto procesa la transferencia
🏦
Transferencia bancaria
PD valida el CCI, verifica el destinatario y procesa la transferencia al banco destino.
● SENT (4)
PASO 4 · PagoDirecto → Tu Backend
📡
Notificación del resultado
PD te notifica cuando el payout llega a un estado final: éxito (Archive) o fallo (Void). Los estados intermedios no generan callback.
● ARCHIVE (5) = Éxito ● VOID (6) = Fallo
03 Crear Payout — POST /api/payouts

📤 Endpoint REQUEST

POST https://api.sandbox.demo/payouts
CampoTipoRequeridoDescripción
payment_referencestringTu identificador único para este payout.
customer_namestringNombre completo del destinatario.
customer_id_typestringTipo de documento: DNI, CE o Pasaporte
customer_id_numberstringNúmero de documento.
account_ccistring (20 dígitos)CCI de la cuenta bancaria destino.
account_currencystringMoneda de la cuenta: SOLES o USD
payment_amountstringMonto con 2 decimales. Ej: "150.00"
payment_currencystringMoneda del pago: PEN o USD
customer_emailstringNOEmail del destinatario.
customer_referencestringNOTu referencia interna del cliente.
callback_urlstringNOURL donde PD enviará la notificación del resultado.
Request
{
  "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"
}
Response · 201 Created
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.

Response · 400 — Validación
{
  "message": "Validation Failed",
  "errors": [
    { "field": "payment_amount",   "message": "Amount can not be empty" },
    { "field": "payment_currency", "message": "Currency can not be empty" }
  ]
}
04 Consultar Estado — GET /api/payouts/{payment_id}
Response · 200 OK
{
  "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"
}
05 Webhooks

PD notifica solo cuando el payout llega a un estado final. Los estados intermedios no generan callback.

Webhook · Éxito
{ "payment_status": "5", "payment_final_status": "1",
  "payment_notes": "Transferencia completada." }  // ✅
Webhook · Fallo
{ "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.).

06 Estados

Estado operativo — payment_status

ValorEstadoDescripción¿Final?
1PendingEn revisión. No reenvíes — espera el callback.Intermedio
2ProcessEncolado para procesamiento.Intermedio
4SentEnviado al banco, esperando confirmación.Intermedio
5Archive✅ Transferencia completada.✓ Final
6Void❌ Transferencia fallida. Ver payment_notes.✓ Final

Estado contable — payment_final_status

ValorEstadoDescripción
3Not SetPayout en proceso, aún no liquidado.
1CapturedFondos entregados correctamente.
2CancelledFondos no entregados.
07 Ejemplo Completo

Marketplace paga PEN 150.00 a la cuenta BCP de un vendedor.

1 · Crear payout
POST /api/payouts
{ "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" }
● 201 CREATEDpayment_id: 5574200
2 · PD procesa la transferencia
PD valida el CCI, verifica el destinatario y envía la transferencia al banco BCP.
● SENT (4)
3 · Recibes el callback → notificas al vendedor
Webhook
{ "payment_status": "5", "payment_final_status": "1" } // ✅

Bancos Aceptados

Cuentas CCI de estos bancos pueden recibir desembolsos vía API Payouts.

002Banco de Crédito (BCP)
011BBVA Continental
003Interbank
009Scotiabank
049Mi Banco
038BANBIF
035Banco Pichincha
054Banco Falabella
055Banco Ripley
043CrediScotia
058Banco Azteca
018Banco de la Nación
023Banco de Comercio
056Santander Perú
800Caja Metropolitana Lima
801CMAC Piura
803Caja Arequipa
805CMAC Sullana
806CMAC Cuzco
808CMAC Huancayo
902Plin
PagoDirecto · Documentación pública v1 · 2026