API Technical Docs

Mantente al día con las innovaciones tecnológicas que están transformando el mercado.

Contrato común de entrada y salida

Mensajería remota del ciclo de Payment Order

Diseño objetivo del módulo. Su propósito es permitir que un sistema externo siga remotamente una Payment Order desde su creación hasta su resultado terminal. El lifecycle canónico pertenece a la Payment Order; el Checkout Web es el canal o sesión que la envuelve.

Estado de implementación: payment_order.created, payment_order.presented y payment_order.terminal están implementados y certificados como callbacks productivos del Web Checkout QR.

Contrato terminal público: payment_order.terminal usa únicamente result = pagado | cancelado | timeout.

1. payment_order.created

  • created — creada correctamente.
  • rejected — rechazada por validación o regla de negocio.
  • duplicate — operación equivalente ya existente por idempotencia.
  • failed — no fue posible crearla.
{
  "event": "payment_order.created",
  "result": "created",
  "message": "Payment Order created successfully.",
  "external_transaction_id": "TX-12345",
  "payment_order_uid": "po_...",
  "checkout_uid": "chk_...",
  "amount": "125.50",
  "currency": "PEN",
  "payment_method": "qr",
  "channel": "web",
  "occurred_at": "2026-08-28T03:39:50Z"
}

2. payment_order.presented

  • presented — presentado correctamente.
  • presentation_failed — no pudo presentarse.
  • expired_before_presentation — expiró antes de presentarse.
  • cancelled_before_presentation — fue cancelada antes de presentarse.
{
  "event": "payment_order.presented",
  "result": "presented",
  "message": "Payment method presented to customer.",
  "external_transaction_id": "TX-12345",
  "payment_order_uid": "po_...",
  "payment_method": "qr",
  "channel": "web",
  "presented_at": "2026-08-28T03:40:02Z",
  "occurred_at": "2026-08-28T03:40:02Z"
}

3. payment_order.terminal

  • pagado — pago confirmado.
  • cancelado — operación cancelada.
  • timeout — venció sin pago confirmado.
  • timeout — la operación agotó su ventana operativa sin confirmación.
  • No existe failed como cuarto resultado comercial terminal público.
  • rejected — reservado para medios futuros que expongan rechazo terminal explícito.
{
  "event": "payment_order.terminal",
  "result": "pagado",
  "message": "Payment confirmed.",
  "external_transaction_id": "TX-12345",
  "payment_order_uid": "po_...",
  "amount": "125.50",
  "currency": "PEN",
  "payment_method": "qr",
  "channel": "web",
  "presented_at": "2026-08-28T03:40:02Z",
  "paid_at": "2026-08-28T03:41:18Z",
  "occurred_at": "2026-08-28T03:41:18Z"
}

Datos comunes de correlación

Los mensajes deben incluir, cuando corresponda, external_transaction_id, payment_order_uid, checkout_uid, amount, currency, payment_method, channel y occurred_at. Según el evento también pueden incluir checkout_created_at, presented_at, paid_at, timeout_seconds, result y message.

Flujo conceptual: payment_order.created → payment_order.presented → payment_order.terminal.

Contrato vigente de Web Checkout

POST /v1/checkouts requiere:

  • external_transaction_id: identificador de la transacción en el sistema del comercio.
  • amount: monto.
  • currency: moneda ISO de 3 letras, por ejemplo PEN.

Campos opcionales:

  • payment_method: por defecto qr.
  • payer.first_name y payer.last_name: si el comercio conoce el nombre del pagador/cliente.
  • timeout_seconds: vigencia solicitada por el comercio.

YUPY deriva internamente channel=web y resuelve client, counter, location, instrument y policy. Para correlación comercial del Web Checkout use external_transaction_id; source_reference no debe usarse como un segundo identificador comercial.

Hoy, cuando el comercio envía timeout_seconds, ese valor reemplaza el timeout fijo de policy para esa operación. Cuando exista el motor automático de cálculo de timeout, el valor calculado por YUPY tendrá precedencia.

{
  "external_transaction_id": "TX-12345",
  "amount": "125.50",
  "currency": "PEN",
  "payment_method": "qr",
  "payer": {
    "first_name": "Juan",
    "last_name": "Perez"
  },
  "timeout_seconds": 240
}

Respuesta inmediata HTTP 201

{
  "external_transaction_id": "TX-12345",
  "checkout_uid": "chk_...",
  "checkout_token": "cks_...",
  "checkout_url": "https://api.yupy.us/v1/checkouts/browser#token=...",
  "payment_order_uid": "po_...",
  "status": "pending",
  "amount": "125.50",
  "currency": "PEN",
  "payment_method": "qr",
  "channel": "web",
  "checkout_created_at": "2026-08-28T03:39:50Z",
  "timeout_seconds": 240,
  "delivery": {}
}

Esta respuesta confirma la creación del Checkout y de la Payment Order asociada. Las notificaciones posteriores de estado se documentan por separado.

Estado documental: Propuesto.

Este documento define el contrato público común para crear y seguir una intención de cobro en YUPY. La API pública no expone el contrato interno del Payment Order Orchestrator. El integrador envía la intención de cobro al YUPY API Engine; YUPY autentica al cliente, valida e idempotentiza la solicitud, normaliza el contrato y resuelve internamente el contexto operativo necesario antes de crear la Payment Order.

Principio contractual

Toda operación de cobro en YUPY se materializa internamente como una Payment Order. El caller selecciona el medio de pago requerido; YUPY resuelve el Counter, la policy y el instrumento concreto, prepara su presentación y mantiene la trazabilidad de la orden hasta su cierre. La exclusividad o capacidad runtime depende del tipo de Counter y es administrada internamente por YUPY.

Integrador
    ↓
YUPY API Engine
    ↓
autentica
identifica Cliente
valida request
controla Idempotency-Key
normaliza contrato
resuelve contexto interno
    ↓
Adapter del origen
    ↓
Payment Order Orchestrator

API pública ≠ contrato interno del Orchestrator. Campos como client_id, counter_id, QR ID, WhatsApp Account ID, Agencia o Reconciliation Target pertenecen a la infraestructura interna de YUPY y no forman parte del request público común.

Cabeceras HTTP

Las operaciones de creación deben usar:

Authorization: Bearer <token>
Idempotency-Key: <clave-unica-del-intento-http>

Authorization autentica al integrador. Idempotency-Key controla reintentos técnicos y duplicados HTTP. No reemplaza la identidad comercial del sistema origen.

Request común de creación para Web Checkout

El contrato productivo de Web Checkout crea la intención mediante POST /v1/checkouts. El caller expresa el medio de pago; YUPY resuelve la infraestructura interna aplicable.

{
  "external_transaction_id": "ORDER-10482",
  "amount": "85.50",
  "currency": "PEN",
  "payment_method": "qr",
  "payer": {
    "first_name": "María",
    "last_name": "Ramos"
  },
  "business_context": {
    "industry": "ground_transport",
    "destination": "Arequipa",
    "route": "Lima-Arequipa"
  }
}

Campos mínimos de Web Checkout

Campo Requerido Descripción
external_transaction_id Identidad comercial de la operación en el sistema origen.
amount Monto esperado.
currency Moneda de la operación, por ejemplo PEN.

Body mínimo de Web Checkout: external_transaction_id, amount y currency. payment_method es opcional y actualmente usa qr por defecto.

payment_method No Opcional en Web Checkout; por defecto qr. Si se envía, selecciona la familia del medio solicitado dentro de las opciones públicas habilitadas.

El caller selecciona el medio, no el instrumento interno

"payment_method": "qr"

El caller de Web Checkout no envía payment_instrument_type, instrument_id, QR ID, counter_id ni policy_config. YUPY deriva el cliente autenticado, resuelve el Counter virtual Web canónico y aplica la policy correspondiente a cliente + Counter + canal + medio de pago.

El instrumento QR concreto puede variar por cliente y configuración. Yape y Plin son mecanismos con los que el pagador puede utilizar un QR compatible; no forman parte del request como instrumentos administrados separados.

Identidades: tres conceptos separados

Identificador Quién lo genera Uso
external_transaction_id Sistema del cliente Identidad comercial en el sistema origen.
Idempotency-Key Caller Control de reintentos técnicos de la operación HTTP/API.
payment_order_uid YUPY Identidad canónica de la Payment Order de punta a punta.

La misma Idempotency-Key con el mismo payload debe representar el mismo intento técnico. external_transaction_id continúa siendo la referencia comercial externa. YUPY devuelve payment_order_uid como identificador canónico de la orden.

Buyer

buyer no es universalmente obligatorio. Para QR BBVA se recomienda enviar al menos:

"buyer": {
  "first_name": "María",
  "last_name": "Ramos"
}

Estos datos pueden ayudar posteriormente en correlación, conciliación o atención operativa. Los flujos que permitan comprador anónimo pueden omitirlos según su contrato específico.

Contexto del negocio

Los datos propios de cada industria no deben contaminar el núcleo universal de Payment Orders. Deben viajar dentro de business_context.

"business_context": {
  "industry": "ground_transport",
  "destination": "Arequipa",
  "route": "Lima-Arequipa",
  "seat": "12A"
}

Otros sectores pueden utilizar claves equivalentes, por ejemplo mesa, habitación, reserva, sede o referencia de atención.

Campos internos que el caller no envía

El API Engine y los adapters resuelven internamente, según el origen:

client_id
source_system
delivery_channel
request_uid / correlación técnica
counter_id
policy aplicable
instrumento concreto
destino de entrega
configuración de conciliación

En Web Checkout, el integrador no selecciona el Counter. YUPY resuelve el Counter virtual Web canónico del cliente y el Payment Order Orchestrator administra su capacidad/concurrency runtime. No existe un pool público de Counters que el integrador deba recorrer o administrar.

Respuesta común

La respuesta pública debe mantener una separación clara entre identidad, lifecycle y datos efectivos resueltos por YUPY. Como mínimo, una creación aceptada devuelve el identificador canónico:

{
  "payment_order_uid": "pay_01JXYZ...",
  "external_transaction_id": "ORDER-10482",
  "payment_method": "qr",
  "received_at": "2026-08-09T20:15:00-05:00",
  "expires_at": "2026-08-09T20:20:00-05:00"
}

Los objetos específicos de presentación, checkout, evidencia, conciliación o canal pueden extender esta respuesta en sus contratos especializados. La API pública no expone identificadores internos de infraestructura salvo que exista una razón contractual explícita.

Timestamps y medición

Los tiempos tienen responsabilidades distintas:

Timestamp Responsable Significado
requested_at Caller Momento en que el origen pidió iniciar el cobro.
received_at YUPY Momento en que YUPY recibió la solicitud.
order_created_at YUPY Creación de la Payment Order.
instrument_resolved_at YUPY Resolución del instrumento concreto.
delivery_prepared_at YUPY Payload o instrucción listos para el canal.
presented_at Canal La instrucción de pago fue realmente presentada al pagador.
confirmed_at Conciliación Momento en que el pago quedó confirmado financieramente.

presented_at es distinto de haber creado una URL o preparado un payload. Ese momento se registra mediante el concepto público payment_instruction.presented.

Timeout y expiración

El caller no gobierna arbitrariamente el timeout de la Payment Order. Para Web Checkout, YUPY obtiene la vigencia efectiva de la policy canónica aplicable al cliente autenticado, Counter resuelto, canal y payment_method. El instrumento concreto se resuelve internamente y la configuración efectiva queda asociada a la operación:

client_id autenticado
+ counter_id resuelto
+ channel
+ payment_method
        ↓
policy canónica
        ↓
timeout_seconds
expires_at

Además, payment_order.expires_at y checkout_session.expires_at son conceptos distintos. La primera controla el lifecycle del cobro y la ocupación del Counter; la segunda controla la sesión o token Web. Pueden coincidir inicialmente, pero no deben tratarse como el mismo reloj.

Counters y capacidad

La semántica runtime depende del tipo de Counter. Un Counter físico puede conservar exclusividad operativa. El Counter virtual Web canónico permite que el Payment Order Orchestrator administre su capacidad/concurrency sin exponer al integrador un pool ni selección de Counters.

Lifecycle y confirmación financiera

Los estados terminales v1 son:

confirmed
expired
cancelled
failed

Al cerrar la orden se registra closed_at y se libera el Counter. El Payment Order Orchestrator no confirma financieramente por sí solo: la confirmación proviene de Reconciliation y se refleja en confirmed_at.

Señales como “Ya pagó”, fotografías o reclamos de pago solicitan verificación; no equivalen a pago confirmado. Del mismo modo, los pagos tardíos pueden detectarse después de que una orden expiró o fue cancelada sin reabrirla ni volver a ocupar el Counter.

Campos del contrato anterior que dejan de ser canónicos

Para este contrato común ya no son canónicos:

requested_payment_methods[]
payment_options[]
yape_qr
plin_qr
collection_profile_id como fuente del instrumento
expires_in_seconds controlado por el caller
yupy_transaction_id como identidad canónica pública

Para Web Checkout, la sustitución conceptual vigente es:

payment_method
        ↓
YUPY resuelve Counter + policy + instrumento
        ↓
timeout_seconds efectivo
payment_order_uid

Changelog

2026-08-26 — Web Checkout productivo: el contrato público de Web Checkout quedó alineado con POST /v1/checkouts y payment_method como selección del caller; YUPY resuelve internamente cliente, Counter virtual Web, policy, instrumento y timeout. Se retiró del contrato Web la selección pública de payment_instrument_type, el modelo de pool/Allocator visible y cualquier dependencia de un QR concreto como supuesto universal.