API Technical Docs

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

POS vía chat, turnos, dispositivos y entregas

POS vía chat, turnos, dispositivos y entregas

Estado documental: Contrato propuesto. Las rutas, campos, límites y tiempos pasan a estado confirmado solo después de su implementación y verificación.

Objetivo: Inventariar turnos, dispositivos/terminales, entregas y configuración administrativa del POS vía chat manteniendo separadas la identidad de la Persona, la Cuenta WhatsApp/canal, el Counter y la Payment Order.

Regla de turno

Un turno
= una Persona identificada
+ un dispositivo o terminal operativo
+ un canal/contexto de atención
+ una ventana operativa

La Persona y la Cuenta WhatsApp son identidades diferentes. La Persona se identifica con sus propias credenciales; la Cuenta WhatsApp conserva su identidad y routing aunque cambie la persona que atiende. Un número operativo no identifica a una Persona.

No existe cambio de Persona dentro de un turno. Para otro vendedor se cierra el turno actual y se abre uno nuevo. El turno registra quién está operando y desde qué contexto operativo, sin convertir a la Cuenta WhatsApp en propietaria de la Payment Order ni del QR.

Turnos

Audiencia Método Ruta propuesta Uso Idempotencia Eventos o callbacks relacionados
Integración POST /v1/shifts Abrir turno después de identificar a la Persona. Obligatoria shift.opened
Integración GET /v1/shifts Listar turnos. No Ninguno
Integración GET /v1/shifts/{shift_id} Consultar turno. No Ninguno
Integración POST /v1/shifts/{shift_id}/close Cerrar turno. Obligatoria shift.closed
Integración GET /v1/shifts/{shift_id}/payment-orders Consultar Payment Orders del turno. No Ninguno
Integración GET /v1/shifts/{shift_id}/pending-cases Consultar pendientes del turno. No Ninguno
Integración GET /v1/shifts/{shift_id}/summary Obtener resumen operativo. No Ninguno

Ejemplo: abrir turno

POST /v1/shifts
Idempotency-Key: 1cf08e71-6484-4d08-b772-45573a4beec4

{
  "username": "david",
  "pin": "<PROTECTED_VALUE>",
  "device_id": "dev_01JXYZ",
  "channel": "whatsapp"
}
{
  "shift_id": "shf_01JXYZ",
  "person_id": "per_01JXYZ",
  "device_id": "dev_01JXYZ",
  "channel": "whatsapp",
  "opened_at": "2026-08-09T08:00:00-05:00",
  "maximum_duration_seconds": 28800,
  "expiration_mode": "warning_and_renewal",
  "status": "active",
  "request_id": "req_01JXYZ"
}

username + PIN identifican a la Persona. El valor protegido nunca debe almacenarse en texto plano. El contexto de canal/routing —por ejemplo la Cuenta WhatsApp desde la que opera el turno— se resuelve y conserva de forma separada de person_id.

Crear una Payment Order para el turno

La Payment Order se crea mediante POST /v1/payment-orders. El caller expresa la intención de cobro y el contexto público necesario; no selecciona el QR concreto ni envía counter_id, QR ID, WhatsApp Account ID o Agencia.

{
  "external_transaction_id": "TICKET-88412",
  "amount": "80.00",
  "currency": "PEN",
  "payment_method": "qr",
  "payment_instrument_type": "qr_bbva",
  "requested_at": "2026-08-09T08:14:25-05:00",
  "buyer": {
    "first_name": "Carlos",
    "last_name": "Vega"
  },
  "business_context": {
    "shift_id": "shf_01JXYZ",
    "device_id": "dev_01JXYZ"
  }
}

El API Engine autentica, identifica al cliente, valida, aplica idempotencia y normaliza. El Adapter del origen resuelve el contexto interno y el Counter correspondiente. Mientras la Payment Order permanezca abierta, el Counter asignado es exclusivo para esa orden y se libera al llegar a un estado terminal.

En el flujo QR actual, payment_method = "qr" y payment_instrument_type = "qr_bbva". Yape y Plin son mecanismos que el pagador puede utilizar para pagar ese QR, no instrumentos concretos pares de qr_bbva.

Dispositivos y entregas

Audiencia Método Ruta propuesta Uso Idempotencia Eventos o callbacks relacionados
Integración GET /v1/devices/{device_id} Consultar dispositivo/terminal autorizado. No Ninguno
Integración GET /v1/devices/{device_id}/active-shift Consultar turno activo. No Ninguno
Integración GET /v1/devices/{device_id}/inbox Consultar operaciones por entregar. No Ninguno
Integración POST /v1/devices/{device_id}/inbox/{item_id}/acknowledge Confirmar recepción operacional. Obligatoria device.delivery_received
Integración GET /v1/devices/{device_id}/pending-cases Consultar pendientes operativos. No Ninguno
Integración POST /v1/payment-orders/{id}/deliveries Crear entrega de instrucciones de una Payment Order. Obligatoria delivery.queued
Integración GET /v1/payment-orders/{id}/deliveries Listar entregas. No Ninguno
Integración GET /v1/deliveries/{delivery_id} Consultar estado de entrega. No Ninguno
Integración POST /v1/deliveries/{delivery_id}/retry Reintentar entrega fallida. Obligatoria delivery.queued
Integración POST /v1/deliveries/{delivery_id}/cancel Cancelar antes del envío. Obligatoria delivery.cancelled

Ejemplo: crear entrega

POST /v1/payment-orders/pay_01JXYZ/deliveries

{
  "delivery_target": {
    "type": "shift_device",
    "shift_id": "shf_01JXYZ",
    "device_id": "dev_01JXYZ"
  },
  "content_type": "payment_instructions"
}
{
  "delivery_id": "dly_01JXYZ",
  "payment_order_uid": "pay_01JXYZ",
  "status": "queued",
  "request_id": "req_01JXYZ"
}

delivery.queued y device.delivery_received describen el flujo operativo de entrega. No prueban por sí solos que la instrucción haya sido presentada efectivamente a la persona que cobra o al pagador. Cuando corresponda, la presentación efectiva se registra de forma separada mediante payment_instruction.presented, con datos como presented_at, delivery_channel, ack_type y external_reference.

Personas/usuarios administrativos

Las rutas administrativas de /v1/admin/users se conservan como nomenclatura propuesta de esta biblioteca, pero el recurso representa la identidad de la Persona/usuario operativo. No representa una Cuenta WhatsApp, un número telefónico ni un destino de routing.

Audiencia Método Ruta propuesta Uso Idempotencia Eventos o callbacks relacionados
Administración POST /v1/admin/users Registrar Persona/usuario operativo. user.created
Administración GET /v1/admin/users Listar Personas/usuarios. No Ninguno
Administración GET /v1/admin/users/{id} Consultar Persona/usuario. No Ninguno
Administración PATCH /v1/admin/users/{id} Actualizar datos permitidos. user.updated
Administración POST /v1/admin/users/{id}/activate Activar Persona/usuario. user.activated
Administración POST /v1/admin/users/{id}/deactivate Desactivar Persona/usuario. user.deactivated
Administración POST /v1/admin/users/{id}/reset-credential Restablecer credencial de identificación. security.user_credential_reset
Administración GET /v1/admin/users/{id}/history Consultar auditoría. No Ninguno

Dispositivos administrativos

Audiencia Método Ruta propuesta Uso Idempotencia Eventos o callbacks relacionados
Administración POST /v1/admin/devices Registrar dispositivo/terminal. device.created
Administración GET /v1/admin/devices Listar dispositivos/terminales. No Ninguno
Administración GET /v1/admin/devices/{id} Consultar dispositivo/terminal. No Ninguno
Administración PATCH /v1/admin/devices/{id} Actualizar configuración. device.updated
Administración POST /v1/admin/devices/{id}/activate Activar. device.activated
Administración POST /v1/admin/devices/{id}/deactivate Desactivar. device.deactivated
Administración POST /v1/admin/devices/{id}/pair Vincular canal o terminal. device.paired
Administración POST /v1/admin/devices/{id}/unpair Desvincular. device.unpaired
Administración POST /v1/admin/devices/{id}/assign-supervisor Asignar supervisor. device.supervisor_assigned
Administración GET /v1/admin/devices/{id}/history Consultar auditoría. No Ninguno

Política de turnos y alertas

Audiencia Método Ruta propuesta Uso Idempotencia Eventos o callbacks relacionados
Administración GET /v1/admin/shift-policy Consultar duración y modalidad. No Ninguno
Administración PATCH /v1/admin/shift-policy Configurar política de turnos. shift_policy.updated
Administración POST /v1/admin/shift-policy/test Probar política. Ninguno
Administración POST /v1/admin/alert-rules Crear regla de alerta. alert_rule.created
Administración GET /v1/admin/alert-rules Listar reglas. No Ninguno
Administración GET /v1/admin/alert-rules/{id} Consultar regla. No Ninguno
Administración PATCH /v1/admin/alert-rules/{id} Modificar regla. alert_rule.updated
Administración DELETE /v1/admin/alert-rules/{id} Desactivar regla. alert_rule.deactivated
Administración POST /v1/admin/alert-rules/{id}/test Enviar alerta de prueba. alert.test_sent
Administración GET /v1/admin/alerts Consultar historial. No Ninguno
Administración POST /v1/admin/alerts/{id}/acknowledge Registrar atención. alert.acknowledged

Ejemplo: política de turnos

PATCH /v1/admin/shift-policy

{
  "maximum_duration_seconds": 28800,
  "expiration_mode": "warning_and_renewal",
  "warning_after_each_transaction": true,
  "auto_close": false
}

Ejemplo: regla de alerta

{
  "event_types": [
    "payment.late_detected",
    "payment.amount_difference"
  ],
  "recipients": [
    {
      "type": "seller"
    },
    {
      "type": "supervisor"
    }
  ],
  "channels": [
    "whatsapp",
    "email"
  ],
  "active": true
}

Errores principales

HTTP Código Descripción
404 shift_not_available Turno inexistente o no disponible.
409 shift_closed El turno ya fue cerrado.
409 shift_device_mismatch Dispositivo distinto al del turno.
403 user_not_authorized Persona/usuario sin autorización.
404 device_not_available Dispositivo no disponible.
404 delivery_not_found Entrega inexistente.
409 delivery_retry_not_allowed La entrega no puede reintentarse.

Changelog — Payment Order / API Engine

2026-08-09 — Payment Order / API Engine v1.0: se separaron explícitamente Persona, Cuenta WhatsApp/canal, dispositivo/terminal y Counter; el ejemplo de turno pasó de la identidad genérica user_id + PIN a identificación de Persona mediante username + PIN y respuesta con person_id; se retiró integration_experience de la creación activa de Payment Order; se incorporaron payment_method, payment_instrument_type, qr_bbva, requested_at y business_context; las entregas usan payment_order_uid/pay_... en lugar del identificador histórico ypt_...; se documentó que el Adapter resuelve internamente el Counter y que el caller no envía IDs internos de QR/WhatsApp/Agencia; y se separó la entrega/recepción operacional de payment_instruction.presented.