Órdenes de pago y Web Checkout
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 ejemploPEN.
Campos opcionales:
payment_method: por defectoqr.payer.first_nameypayer.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: Implementado y verificado en Producción.
Crear Web Checkout
| Audiencia | Método | Ruta | Uso |
|---|---|---|---|
| Backend del integrador | POST |
/v1/checkouts |
Crear Web Checkout + Payment Order asociada. |
Requiere:
Authorization: Bearer <ACCESS_TOKEN>
Idempotency-Key: <UNIQUE_KEY>
Request mínimo:
{
"amount": "85.50",
"currency": "PEN",
"payment_method": "qr"
}
Referencia opcional:
{
"source_reference": "ORDER-10482"
}
Resolución interna
El caller no selecciona client_id, counter_id, location_id, instrument_id, QR ID, pool, slot ni timeout.
Respuesta
{
"checkout_uid": "chk_...",
"payment_order_uid": "po_...",
"checkout_token": "<OPAQUE_CHECKOUT_TOKEN>",
"checkout_url": "https://api.yupy.us/v1/checkouts/browser#token=...",
"status": "pending",
"delivery": {
"type": "qr",
"image_url": "https://..."
}
}
SDK
<script src="https://api.yupy.us/v1/checkouts/browser/sdk.js"></script>
const result = await YupyCheckout.open(checkoutUrl);
Browser interno
| Método | Ruta | Uso interno |
|---|---|---|
POST |
/v1/checkouts/browser/context |
Cargar contexto browser-safe. |
POST |
/v1/checkouts/browser/presented |
Registrar presentación efectiva. |
POST |
/v1/checkouts/browser/status |
Consultar estado canónico. |
Estos endpoints son internos a la experiencia alojada; el integrador utiliza checkout_url y SDK.
Presented
QR image onload
→ /browser/presented
→ POO presented_at
Polling y “Ya pagué”
Browser consulta status aproximadamente cada 2 segundos. “Ya pagué” registra PAYMENT_DECLARED mediante el boundary Browser/Web API → POO y luego continúa el polling del estado canónico. La declaración es no terminal y no fuerza pagado.
Timeout
POO entrega expires_at. Browser lo usa para countdown y, al llegar a cero, vuelve a consultar status.
Estados terminales
pagado
cancelado
timeout
failed
Bridge SDK
Mensaje interno: yupy.checkout.result.
{
"status": "pagado",
"terminal": true,
"source": "yupy_checkout"
}
Cierre manual:
{
"status": "cancelled_by_user",
"terminal": false,
"source": "yupy_sdk"
}
Seguridad
No exponer al parent SDK checkout_token, counter_id, client_id, payment_order_uid ni instrument_id.