Saltar a contenido

Caso completo: una venta en una tienda online

Una venta de principio a fin, con los mismos datos en todos los pasos, para ver cómo calzan las piezas. Cada paso enlaza a la guía que lo explica en detalle.

El caso: Ana Pérez compra en la tienda web 2 zapatillas urbanas talla 42 (código A001, $15.000 cada una con IVA incluido), paga con Webpay y recibe su boleta.

Una vez, al iniciar      0. Leer la configuración de la empresa
Mientras Ana navega      1. Mostrar el catálogo
                         2. Mostrar cuánto hay disponible
Cuando Ana va a pagar    3. Reservar los productos
Cuando Ana paga          4. Crear el pedido (nota de venta)
Al preparar el pedido    5. Emitir la boleta
                         6. Entregar el PDF y revisar el estado en el SII
Si algo sale mal         7. Cancelar o revertir

Todos los llamados van contra https://api.opentpv.cl con el header Authorization: Bearer <token de sesión>. Haz las pruebas en el ambiente que te habilita soporte (ver Primeros pasos).

Paso 0: leer la configuración

Una vez, al iniciar tu sistema, pregunta cómo trabaja la empresa:

# Cuándo reservar, cuánto duran las reservas, qué bodega usar
curl https://api.opentpv.cl/reservas/configuracion -H "Authorization: Bearer eyJhbGciOi..."

# Si la empresa trabaja cada documento con valores netos o con IVA incluido
curl https://api.opentpv.cl/api/OpcionesGenerales/iva -H "Authorization: Bearer eyJhbGciOi..."

De la primera respuesta te importa momentoReserva (en este caso CHECKOUT: reservar cuando el cliente entra a pagar). Detalle en Reservar stock.

curl -X POST https://api.opentpv.cl/Productos/buscar-avanzado \
  -H "Authorization: Bearer eyJhbGciOi..." \
  -H "Content-Type: application/json" \
  -d '{ "textoBusqueda": "", "activo": true, "vendible": true, "web": true,
        "pagina": 1, "tamañoPagina": 100 }'
{
  "productos": [
    { "codigo": "A001", "descripcion": "Zapatilla urbana 42", "valorFinal1": 15000 }
  ],
  "paginaActual": 1,
  "totalPaginas": 1,
  "totalRegistros": 1
}

Guarda codigo como identificador del producto y publica valorFinal1, que es el precio con IVA incluido. Detalle en Catálogo de productos.

Paso 2: mostrar cuánto hay disponible

curl "https://api.opentpv.cl/reservas/disponibilidad?codigos=A001&bodega=1" \
  -H "Authorization: Bearer eyJhbGciOi..."
[ { "codigo": "A001", "bodega": 1, "stockFisico": 10, "reservado": 0,
    "buffer": 0, "atpFisico": 10, "atpPublicable": 10 } ]

Muestra atpPublicable: hay 10 para vender.

Paso 3: reservar cuando Ana va a pagar

Tu sistema inventa un identificador para el carro de Ana (carro-web-8f3a2b) y aparta los productos:

curl -X POST https://api.opentpv.cl/reservas \
  -H "Authorization: Bearer eyJhbGciOi..." \
  -H "Content-Type: application/json" \
  -d '{ "token": "carro-web-8f3a2b", "bodega": 1, "origen": "ECOMMERCE",
        "lineas": [ { "codigo": "A001", "cantidad": 2 } ] }'
{ "exito": true, "token": "carro-web-8f3a2b",
  "expiraEn": "2026-08-10T10:15:00", "segundosRestantes": 900 }

Las 2 zapatillas quedan apartadas por 15 minutos. El stock de la bodega sigue en 10; lo disponible bajó a 8. Si la respuesta es 409, no había stock suficiente y no se reservó nada.

Paso 4: crear el pedido cuando Ana paga

Con el pago de Webpay confirmado, crea la nota de venta indicando el token del carro:

curl -X POST https://api.opentpv.cl/documento/notaventa \
  -H "Authorization: Bearer eyJhbGciOi..." \
  -H "Content-Type: application/json" \
  -d '{
    "tokenReserva": "carro-web-8f3a2b",
    "origen": "ECOMMERCE",
    "fechaEmision": "2026-08-10",
    "rut": "12345678", "digito": "5",
    "razonSocial": "Ana Pérez",
    "direccion": "Los Aromos 456", "comuna": "Ñuñoa", "ciudad": "Santiago",
    "email": "ana@correo.cl",
    "observaciones": "Pedido web #8912",
    "neto": 25210, "iva": 4790, "total": 30000,
    "items": [
      { "codigo": "A001", "descripcion": "Zapatilla urbana 42", "cantidad": 2,
        "precioUnitario": 15000, "totalLinea": 30000, "bodega": 1 }
    ],
    "pagos": [ { "idFormaPago": 2, "formaPago": "WEBPAY", "monto": 30000 } ]
  }'
{ "success": true, "message": "NOTA DE VENTA folio 8912 creada exitosamente",
  "data": { "folio": 8912, "idDocumento": 2150, "total": 30000, "estado": "PAGADO" } }

Guarda el folio (8912). Las zapatillas quedan apartadas a nombre del pedido por 24 horas. Si la respuesta trae data.advertencia, la reserva ya había vencido: revisa la disponibilidad antes de despachar. Detalle en Pedidos con nota de venta.

Paso 5: emitir la boleta

curl -X POST https://api.opentpv.cl/documento/notaventa/8912/documentar \
  -H "Authorization: Bearer eyJhbGciOi..." \
  -H "Content-Type: application/json" \
  -d '{ "tipoDte": 39, "codigoTerminal": "TERM-01" }'
{
  "success": true,
  "message": "Nota de venta 8912 documentada en BOLETA ELECTRONICA folio 12345.",
  "data": {
    "folio": 12345,
    "token": "a1b2c3d4...",
    "pdf": "https://api.opentpv.cl/documento/pdf/a1b2c3d4...",
    "xml": "https://api.opentpv.cl/documento/xml/a1b2c3d4...",
    "warning": ""
  }
}

Aquí baja el stock de la bodega (de 10 a 8, si la empresa activó el descuento por API) y la reserva queda cumplida. Guarda data.token: con él obtienes el PDF y el estado. Revisa siempre data.warning.

Paso 6: entregar el PDF y revisar el estado

# PDF para enviar a Ana por correo o mostrar en "Mis pedidos"
curl https://api.opentpv.cl/documento/pdf/a1b2c3d4... -H "Authorization: Bearer eyJhbGciOi..." -o boleta.pdf

# ¿El SII ya aceptó el documento?
curl https://api.opentpv.cl/documento/estado/dte/a1b2c3d4... -H "Authorization: Bearer eyJhbGciOi..."

Paso 7: si algo sale mal

Qué pasó Qué hacer
Ana abandona antes de pagar Nada: la reserva vence sola. Para devolver el stock de inmediato, DELETE /reservas/carro-web-8f3a2b.
El pago falla después de reservar Igual que el caso anterior.
Ana cancela después de pagar, antes de emitir la boleta POST /documento/notaventa/8912/anular. La reserva se libera.
Ana devuelve el producto después de emitida la boleta Nota de crédito (61) que referencia la boleta 12345. Ver Emitir documentos.
Tu sistema no recibió respuesta (timeout) al documentar Repite el llamado: un pedido no se documenta dos veces; el segundo intento responde 409 si el primero sí se procesó.

Si Ana pide factura en vez de boleta

Cambian tres cosas:

  1. El cliente. La factura exige RUT, razón social, giro y dirección de la empresa que compra. Búscala por RUT y, si no existe, créala. Ver Clientes.
  2. Los precios de las líneas. En factura van netos. O bien mantienes los precios con IVA incluido del pedido y lo avisas al documentar.
  3. El tipo de documento. tipoDte 33:
{ "tipoDte": 33, "codigoTerminal": "TERM-01", "mntBruto": true }

"mntBruto": true le dice a la API que las líneas del pedido llevan IVA incluido (como en este caso). Si tu pedido se guardó con precios netos, omítelo.

Antes de salir a producción

  • Probaste el recorrido completo en el ambiente de pruebas.
  • La tienda publica atpPublicable, no el stock físico.
  • La nota de venta siempre lleva tokenReserva.
  • Revisas advertencia y warning en las respuestas y los registras.
  • Consultas las reservas incumplidas cada cierto tiempo (ver Reservar stock).
  • La caja (codigoTerminal) tiene folios cargados para los tipos de documento que vas a emitir.
  • Acordaste con la empresa si la API descuenta stock al emitir.
  • Sabes qué hacer ante cada error (ver Cómo leer las respuestas y los errores).