API Technical Docs

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

Crear, consultar y cancelar transacciones

Estado documental: Contrato propuesto. Las rutas y nombres de campos deben confirmarse mediante implementación y pruebas.

Separación de superficies

API pública de integración
≠ API de consola
≠ conectores internos de consulta bancaria

Los sistemas del cliente crean y consultan operaciones mediante la API pública. YUPY consulta internamente las cuentas receptoras y utiliza esos movimientos para ejecutar la conciliación.

Endpoint principal

POST <YUPY_API_BASE_URL>/v1/payment-orders
Authorization: Bearer <ACCESS_TOKEN>
Idempotency-Key: <UUID>
Content-Type: application/json

Información comercial mínima

Para crear una operación estándar:

external_transaction_id
amount
buyer_name
{
  "external_transaction_id": "ORDER-10482",
  "amount": "85.50",
  "buyer_name": "María Ramos"
}

La moneda puede heredarse de la configuración de la integración. Cuando la empresa opera con más de una moneda, currency debe enviarse expresamente.

Campos opcionales

{
  "currency": "PEN",
  "buyer": {
    "customer_id": "CUSTOMER-882",
    "phone": "+51999999999",
    "email": "maria@example.com",
    "document_type": "DNI",
    "document_number": "00000000"
  },
  "context": {
    "custom_reference_1": "ROUTE-184",
    "custom_reference_2": "SEAT-12A"
  }
}

Estos campos no son obligatorios para crear una operación válida.

Contexto opcional

context puede utilizarse para enviar ruta, asiento, pedido, mesa, unidad, producto, servicio, reserva u otras referencias.

{
  "context": {
    "custom_reference_1": "ROUTE-184",
    "custom_reference_2": "SEAT-12A"
  }
}

Con el ID de la transacción, nombre y monto, YUPY dispone de la información comercial mínima. El contexto sigue siendo opcional, pero mejora trazabilidad, búsquedas, reclamos, resolución de ambigüedades y detección de posibles duplicados.

Asiento como señal de diferenciación

Operación A
S/ 80.00
Ruta 184
Asiento 12A

Operación B
S/ 80.00
Ruta 184
Asiento 12B

Aunque el monto sea igual, el asiento permite reconocer que son ventas distintas. Enviarlo es recomendable cuando el sistema ya dispone del dato, pero no es obligatorio.

Crear una operación de Web Checkout

Solicitud mínima:

{
  "external_transaction_id": "ORDER-10482",
  "amount": "85.50",
  "buyer_name": "María Ramos",
  "integration_experience": "web_checkout"
}

Ejemplo:

curl --request POST \
  --url '<YUPY_API_BASE_URL>/v1/payment-orders' \
  --header 'Authorization: Bearer <ACCESS_TOKEN>' \
  --header 'Idempotency-Key: 72984bf7-61d8-4504-b591-c37494e381ac' \
  --header 'Content-Type: application/json' \
  --data '{
    "external_transaction_id": "ORDER-10482",
    "amount": "85.50",
    "buyer_name": "María Ramos",
    "integration_experience": "web_checkout"
  }'

Respuesta propuesta:

HTTP/1.1 201 Created
{
  "result": "created",
  "yupy_transaction_id": "ypt_01JXYZ",
  "external_transaction_id": "ORDER-10482",
  "amount": "85.50",
  "currency": "PEN",
  "buyer_name": "María Ramos",
  "checkout_session": {
    "checkout_session_id": "ycs_01JXYZ",
    "checkout_url": "https://<YUPY_CHECKOUT_HOST>/checkout/<OPAQUE_TOKEN>",
    "expires_at": "2026-07-20T14:45:02-05:00"
  },
  "state": {
    "operational": "active",
    "financial": "awaiting_payment"
  },
  "created_at": "2026-07-20T14:30:02-05:00",
  "request_id": "req_01JXYZ"
}

Con campos opcionales

{
  "external_transaction_id": "ORDER-10482",
  "amount": "85.50",
  "currency": "PEN",
  "buyer_name": "María Ramos",
  "integration_experience": "web_checkout",
  "expires_in_seconds": 900,
  "context": {
    "custom_reference_1": "ROUTE-184",
    "custom_reference_2": "SEAT-12A"
  }
}

currency, expires_in_seconds y context pueden ser opcionales según la configuración. YUPY siempre devuelve la vigencia efectiva mediante expires_at.

Crear una operación de POS vía chat mediante API

{
  "external_transaction_id": "TICKET-88412",
  "amount": "80.00",
  "buyer_name": "Carlos Vega",
  "integration_experience": "chat_pos",
  "shift_id": "SHIFT-20260720-044",
  "device_id": "DEVICE-TERMINAL-03"
}

Ejemplo:

curl --request POST \
  --url '<YUPY_API_BASE_URL>/v1/payment-orders' \
  --header 'Authorization: Bearer <ACCESS_TOKEN>' \
  --header 'Idempotency-Key: d30a47ee-a4b2-4011-93c7-f09b60f7cd57' \
  --header 'Content-Type: application/json' \
  --data '{
    "external_transaction_id": "TICKET-88412",
    "amount": "80.00",
    "buyer_name": "Carlos Vega",
    "integration_experience": "chat_pos",
    "shift_id": "SHIFT-20260720-044",
    "device_id": "DEVICE-TERMINAL-03"
  }'

Respuesta propuesta:

{
  "result": "created",
  "yupy_transaction_id": "ypt_01JABC",
  "external_transaction_id": "TICKET-88412",
  "amount": "80.00",
  "currency": "PEN",
  "buyer_name": "Carlos Vega",
  "delivery": {
    "shift_id": "SHIFT-20260720-044",
    "device_id": "DEVICE-TERMINAL-03",
    "status": "queued"
  },
  "state": {
    "operational": "active",
    "financial": "awaiting_payment",
    "delivery": "queued"
  },
  "request_id": "req_01JABC"
}

Contexto opcional

{
  "external_transaction_id": "TICKET-88412",
  "amount": "80.00",
  "buyer_name": "Carlos Vega",
  "integration_experience": "chat_pos",
  "shift_id": "SHIFT-20260720-044",
  "device_id": "DEVICE-TERMINAL-03",
  "context": {
    "custom_reference_1": "BUS-18",
    "custom_reference_2": "SEAT-24"
  }
}

shift_id y device_id son necesarios para enrutar una operación creada por API al turno correcto. No forman parte del mínimo de Web Checkout.

Consultar por ID YUPY

GET /v1/payment-orders/{yupy_transaction_id}
curl --request GET \
  --url '<YUPY_API_BASE_URL>/v1/payment-orders/ypt_01JXYZ' \
  --header 'Authorization: Bearer <ACCESS_TOKEN>' \
  --header 'Accept: application/json'
{
  "yupy_transaction_id": "ypt_01JXYZ",
  "external_transaction_id": "ORDER-10482",
  "amount": "85.50",
  "currency": "PEN",
  "buyer_name": "María Ramos",
  "state": {
    "operational": "active",
    "financial": "awaiting_payment"
  },
  "created_at": "2026-07-20T14:30:02-05:00",
  "updated_at": "2026-07-20T14:34:10-05:00",
  "request_id": "req_01JDEF"
}

Consultar por ID externo

GET /v1/payment-orders/by-external-id/{external_transaction_id}
curl --request GET \
  --url '<YUPY_API_BASE_URL>/v1/payment-orders/by-external-id/ORDER-10482' \
  --header 'Authorization: Bearer <ACCESS_TOKEN>' \
  --header 'Accept: application/json'

Cancelar una transacción

POST /v1/payment-orders/{yupy_transaction_id}/cancel
{
  "reason": "customer_cancelled",
  "external_reason": "El comprador canceló la compra."
}
curl --request POST \
  --url '<YUPY_API_BASE_URL>/v1/payment-orders/ypt_01JXYZ/cancel' \
  --header 'Authorization: Bearer <ACCESS_TOKEN>' \
  --header 'Idempotency-Key: e85afd30-fe75-456d-b97d-f575ba6bcb25' \
  --header 'Content-Type: application/json' \
  --data '{
    "reason": "customer_cancelled",
    "external_reason": "El comprador canceló la compra."
  }'
{
  "result": "cancelled",
  "yupy_transaction_id": "ypt_01JXYZ",
  "state": {
    "operational": "cancelled",
    "financial": "awaiting_payment"
  },
  "cancelled_at": "2026-07-20T14:36:00-05:00",
  "request_id": "req_01JGHI"
}

Cancelar no elimina la operación ni los movimientos, no impide detectar un pago posterior y no ejecuta una devolución.

Registrar “Ya pagó”

POST /v1/payment-orders/{yupy_transaction_id}/payment-reported
{
  "reported_by": "seller",
  "shift_id": "SHIFT-20260720-044",
  "device_id": "DEVICE-TERMINAL-03"
}
{
  "result": "payment_reported",
  "yupy_transaction_id": "ypt_01JABC",
  "state": {
    "operational": "active",
    "financial": "payment_reported"
  },
  "reported_at": "2026-07-20T14:37:00-05:00",
  "request_id": "req_01JKLM"
}

La acción registra una señal. No confirma el pago.

Enviar captura o constancia

POST /v1/payment-orders/{yupy_transaction_id}/evidence
curl --request POST \
  --url '<YUPY_API_BASE_URL>/v1/payment-orders/ypt_01JABC/evidence' \
  --header 'Authorization: Bearer <ACCESS_TOKEN>' \
  --header 'Idempotency-Key: 8e0752b4-217e-4754-a57f-dabf83cc5b32' \
  --form 'file=@payment-proof.jpg' \
  --form 'evidence_type=payment_receipt' \
  --form 'reported_by=seller' \
  --form 'shift_id=SHIFT-20260720-044' \
  --form 'device_id=DEVICE-TERMINAL-03'
{
  "result": "evidence_received",
  "yupy_transaction_id": "ypt_01JABC",
  "evidence_id": "evi_01JXYZ",
  "payment_reported": true,
  "ocr": {
    "status": "queued"
  },
  "state": {
    "operational": "active",
    "financial": "payment_reported"
  },
  "request_id": "req_01JNOP"
}

Enviar evidencia produce la señal equivalente a “Ya pagó”.

Criterios de aceptación

  1. La API pública se mantiene separada de consola y conectores bancarios.
  2. El mínimo comercial es ID externo, monto y nombre.
  3. La moneda puede heredarse.
  4. context es opcional.
  5. Ruta y asiento mejoran la detección de duplicados.
  6. POS vía chat por API requiere turno y dispositivo.
  7. Web Checkout devuelve checkout_url.
  8. La consulta puede hacerse por ID YUPY o ID externo.
  9. La cancelación conserva auditoría.
  10. La evidencia activa OCR y la señal de pago reportado.