Catálogo de Productos
Catálogo de Productos
Sección titulada «Catálogo de Productos»El Catálogo de Productos permite gestionar los productos y servicios que tu organización ofrece. Estos productos pueden usarse al emitir documentos tributarios (BHE, Facturas, Boletas) para estandarizar descripciones, precios y reglas de descuento.
El catálogo incluye:
- Productos y Servicios con precios, reglas de descuento y visibilidad por documento
- Grupos para organizar productos en categorías
Requisitos Previos
Sección titulada «Requisitos Previos»Para usar la API del catálogo necesitas:
- Una API Key con uno de estos roles:
ADMIN,SUPER-ADMIN, oFULL-API - Acceso al tenant correspondiente
Conceptos Clave
Sección titulada «Conceptos Clave»Productos vs Servicios
Sección titulada «Productos vs Servicios»| Tipo | tipoComercial | naturaleza | Uso típico |
|---|---|---|---|
| Producto físico | PRODUCTO | TANGIBLE | Bienes, mercadería |
| Servicio | SERVICIO | INTANGIBLE | Consultoría, asesoría, honorarios |
Para Boletas de Honorarios (BHE), solo se permiten servicios (tipoComercial: SERVICIO).
Estados del Producto
Sección titulada «Estados del Producto»| Estado | Descripción | Visible en búsquedas |
|---|---|---|
ACTIVO | Disponible para usar en documentos | Sí |
INACTIVO | Deshabilitado temporalmente | No |
BORRADOR | En proceso de configuración | No |
Grupos (Categorías)
Sección titulada «Grupos (Categorías)»Los grupos permiten organizar productos jerárquicamente. Cada grupo puede definir:
- Reglas de descuento por rol: Límites máximos según el rol del usuario
- Visibilidad: Qué roles pueden ver los productos del grupo
Esquemas de Precio
Sección titulada «Esquemas de Precio»| Esquema | Descripción |
|---|---|
PRECIO_FIJO | Precio único por unidad |
PRECIO_GRADUADO | Precio variable según cantidad (tramos) |
SIN_PRECIO | Sin precio predefinido (se ingresa al emitir) |
Ejemplo de tramos (PRECIO_GRADUADO):
"tramosPrecios": [ { "cantidadDesde": 1, "cantidadHasta": 10, "precioUnitario": 45000 }, { "cantidadDesde": 11, "cantidadHasta": 50, "precioUnitario": 40000 }, { "cantidadDesde": 51, "cantidadHasta": null, "precioUnitario": 35000 }]Reglas de Descuento
Sección titulada «Reglas de Descuento»Los descuentos pueden controlarse a dos niveles:
- Por Producto:
aceptaDescuentos,tipoDescuentoMax,valorDescuentoMax - Por Grupo/Rol:
reglasDescuentoGrupodefine límites por rol
"reglasDescuentoGrupo": { "OPERADOR": { "maxDescuento": 10, "tipoMax": "PORCENTAJE" }, "ADMIN": { "maxDescuento": 25, "tipoMax": "PORCENTAJE" }}Permisos de Edición de Precio
Sección titulada «Permisos de Edición de Precio»El campo permisoEdicion controla si el precio de un producto puede modificarse al momento de emitir documentos (BHE, BHET):
| Permiso | Comportamiento |
|---|---|
NO_PERMITIDA | Precio fijo. No se puede modificar al emitir |
DENTRO_RANGO_DESCUENTO | Se puede reducir el precio hasta el descuento máximo configurado |
LIBRE | Cualquier precio es válido (requiere rol autorizado) |
Interacción con esquemaPrecio:
- Productos con
esquemaPrecio: SIN_PRECIOsiempre permiten ingresar precio manualmente - El
permisoEdicionse evalúa solo para productos con precio definido (PRECIO_FIJOoPRECIO_GRADUADO)
Modo Sandbox (Testing)
Sección titulada «Modo Sandbox (Testing)»El modo sandbox permite probar la API sin persistir datos reales.
Activación
Sección titulada «Activación»El modo sandbox se activa automáticamente cuando tu API Key tiene isSandbox: true.
Datos de Prueba
Sección titulada «Datos de Prueba»En modo sandbox, los endpoints retornan fixtures predefinidos:
| Endpoint | Respuesta Sandbox |
|---|---|
GET /productos | 6 productos de ejemplo |
POST /productos | Producto simulado (no persiste) |
GET /productos/grupos | 3 grupos de ejemplo |
POST /validar-descuento | Siempre permitido: true |
Endpoints de Productos
Sección titulada «Endpoints de Productos»Crear Producto
Sección titulada «Crear Producto»Endpoint: POST /{tenantSlug}/productos
Crea un nuevo producto en el catálogo.
Request Body:
{ "nombre": "Consultoría Tributaria Mensual", "descripcion": "Servicio de asesoría tributaria mensual", "codigoSku": "CONSULT-TRIB-001", "tipoComercial": "SERVICIO", "naturaleza": "INTANGIBLE", "estado": "BORRADOR", "grupoId": "uuid-grupo", "precioBase": 150000, "esquemaPrecio": "PRECIO_FIJO", "aceptaDescuentos": true, "tipoDescuentoMax": "PORCENTAJE", "valorDescuentoMax": 20}| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
nombre | string | Sí | Nombre del producto (2-255 chars) |
tipoComercial | enum | Sí | PRODUCTO o SERVICIO |
naturaleza | enum | Sí | TANGIBLE o INTANGIBLE |
codigoSku | string | No | Código único (auto-generado si no se envía) |
codigoBarras | string | No | Código de barras (EAN-13, UPC, etc.). Solo números. Único por tenant |
descripcion | string | No | Descripción detallada |
estado | enum | No | ACTIVO, INACTIVO, BORRADOR (default: BORRADOR) |
grupoId | string | No | ID del grupo/categoría |
precioBase | number | No | Precio unitario en CLP |
esquemaPrecio | enum | No | PRECIO_FIJO, PRECIO_GRADUADO, SIN_PRECIO |
aceptaDescuentos | boolean | No | Permite aplicar descuentos (default: true) |
tipoDescuentoMax | enum | No | PORCENTAJE o MONTO_FIJO |
valorDescuentoMax | number | No | Límite máximo de descuento |
permisoEdicion | enum | No | NO_PERMITIDA, DENTRO_RANGO_DESCUENTO, LIBRE (default: NO_PERMITIDA) |
Ejemplo con curl:
curl -X POST "https://api.redcumbre.cl/{tenantSlug}/productos" \ -H "Authorization: Bearer {api_key}" \ -H "Content-Type: application/json" \ -d '{ "nombre": "Consultoría Tributaria", "tipoComercial": "SERVICIO", "naturaleza": "INTANGIBLE", "precioBase": 150000 }'Response (201 Created):
{ "success": true, "data": { "id": "uuid-producto", "nombre": "Consultoría Tributaria", "codigoSku": "PROD-ABC123", "codigoBarras": null, "tipoComercial": "SERVICIO", "naturaleza": "INTANGIBLE", "estado": "BORRADOR", "precioBase": 150000, "createdAt": "2024-01-15T10:30:00Z" }}Listar Productos
Sección titulada «Listar Productos»Endpoint: GET /{tenantSlug}/productos
Obtiene un listado paginado de productos con filtros opcionales.
Query Parameters:
| Parámetro | Tipo | Descripción |
|---|---|---|
busqueda | string | Búsqueda en nombre, descripción, SKU, código de barras |
tipoComercial | enum | PRODUCTO o SERVICIO |
estado | enum | ACTIVO, INACTIVO, BORRADOR |
grupoId | string | Filtrar por grupo/categoría |
visibleEnBhe | boolean | Solo productos visibles en BHE |
visibleEnFactura | boolean | Solo productos visibles en Facturas |
visibleEnBoleta | boolean | Solo productos visibles en Boletas |
limit | number | Resultados por página (1-100, default: 50) |
offset | number | Registros a saltar (paginación) |
Ejemplo con curl:
curl -X GET "https://api.redcumbre.cl/{tenantSlug}/productos?tipoComercial=SERVICIO&estado=ACTIVO&limit=20" \ -H "Authorization: Bearer {api_key}"Response (200 OK):
{ "success": true, "data": [ { "id": "uuid-1", "nombre": "Consultoría Tributaria", "codigoSku": "CONSULT-001", "codigoBarras": "7501234567890", "tipoComercial": "SERVICIO", "estado": "ACTIVO", "precioBase": 150000 } ], "total": 25, "limit": 20, "offset": 0}Obtener Detalle de Producto
Sección titulada «Obtener Detalle de Producto»Endpoint: GET /{tenantSlug}/productos/{id}
Obtiene el detalle completo de un producto.
Ejemplo con curl:
curl -X GET "https://api.redcumbre.cl/{tenantSlug}/productos/{id}" \ -H "Authorization: Bearer {api_key}"Response (200 OK):
{ "success": true, "data": { "id": "uuid-producto", "nombre": "Consultoría Tributaria", "descripcion": "Servicio de asesoría tributaria", "codigoSku": "CONSULT-001", "codigoBarras": "7501234567890", "tipoComercial": "SERVICIO", "naturaleza": "INTANGIBLE", "estado": "ACTIVO", "precioBase": 150000, "esquemaPrecio": "PRECIO_FIJO", "aceptaDescuentos": true, "tipoDescuentoMax": "PORCENTAJE", "valorDescuentoMax": 20, "grupoId": "uuid-grupo", "createdAt": "2024-01-15T10:30:00Z", "updatedAt": "2024-01-15T10:30:00Z" }}Actualizar Producto
Sección titulada «Actualizar Producto»Endpoint: PATCH /{tenantSlug}/productos/{id}
Actualiza los datos de un producto existente. Solo envía los campos a modificar.
Request Body:
{ "nombre": "Consultoría Tributaria Actualizada", "precioBase": 160000, "estado": "ACTIVO"}Ejemplo con curl:
curl -X PATCH "https://api.redcumbre.cl/{tenantSlug}/productos/{id}" \ -H "Authorization: Bearer {api_key}" \ -H "Content-Type: application/json" \ -d '{ "precioBase": 160000, "estado": "ACTIVO" }'Activar Producto
Sección titulada «Activar Producto»Endpoint: POST /{tenantSlug}/productos/{id}/activar
Cambia el estado del producto a ACTIVO.
curl -X POST "https://api.redcumbre.cl/{tenantSlug}/productos/{id}/activar" \ -H "Authorization: Bearer {api_key}"Inactivar Producto
Sección titulada «Inactivar Producto»Endpoint: POST /{tenantSlug}/productos/{id}/inactivar
Cambia el estado del producto a INACTIVO.
curl -X POST "https://api.redcumbre.cl/{tenantSlug}/productos/{id}/inactivar" \ -H "Authorization: Bearer {api_key}"Desactivar Producto (Soft Delete)
Sección titulada «Desactivar Producto (Soft Delete)»Endpoint: DELETE /{tenantSlug}/productos/{id}
Cambia el estado a INACTIVO (soft delete). El producto NO se elimina físicamente y puede reactivarse.
curl -X DELETE "https://api.redcumbre.cl/{tenantSlug}/productos/{id}" \ -H "Authorization: Bearer {api_key}"Autocomplete de Productos
Sección titulada «Autocomplete de Productos»Endpoint: GET /{tenantSlug}/productos/autocomplete
Búsqueda rápida para usar en formularios de documentos tributarios.
Query Parameters:
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
tipoDocumento | enum | Sí | BHE, FACTURA, o BOLETA |
sku | string | No | Búsqueda por prefijo SKU |
nombre | string | No | Búsqueda por nombre (contains) |
codigoBarras | string | No | Búsqueda por código de barras (contains) |
limit | number | No | Máximo resultados (1-50, default: 10) |
Filtros automáticos por tipo de documento:
- BHE: Solo servicios visibles en BHE, sin código ILA
- FACTURA: Solo productos visibles en Facturas
- BOLETA: Solo productos visibles en Boletas
Ejemplo con curl:
curl -X GET "https://api.redcumbre.cl/{tenantSlug}/productos/autocomplete?tipoDocumento=BHE&nombre=consultor" \ -H "Authorization: Bearer {api_key}"Response (200 OK):
{ "success": true, "data": [ { "id": "uuid-1", "codigoSku": "CONSULT-001", "codigoBarras": "7501234567890", "nombre": "Consultoría Tributaria", "esquemaPrecio": "PRECIO_FIJO", "precioBase": 150000, "tipoComercial": "SERVICIO", "aceptaDescuentos": true, "valorDescuentoMax": 20 } ]}Validar Descuento
Sección titulada «Validar Descuento»Endpoint: POST /{tenantSlug}/productos/validar-descuento
Verifica si un descuento puede aplicarse a un producto según las reglas configuradas.
Request Body:
{ "productoId": "uuid-producto", "descuentoSolicitado": 15, "tipoDescuento": "PORCENTAJE", "rolUsuario": "OPERADOR", "precioBase": 50000}| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
productoId | string | Sí | ID del producto |
descuentoSolicitado | number | Sí | Porcentaje o monto (0-100) |
tipoDescuento | enum | Sí | PORCENTAJE o MONTO_FIJO |
rolUsuario | string | Sí | Rol del usuario solicitante |
precioBase | number | Sí | Precio base para calcular % |
Response (200 OK):
{ "success": true, "data": { "permitido": true, "requiereAutorizacion": false, "maxSinAutorizacion": 20, "razon": "Descuento dentro de los límites permitidos" }}Respuestas posibles:
permitido | requiereAutorizacion | Significado |
|---|---|---|
true | false | Descuento permitido sin restricción |
false | true | Requiere aprobación de rol superior |
false | false | Producto no acepta descuentos |
Endpoints de Grupos
Sección titulada «Endpoints de Grupos»Crear Grupo
Sección titulada «Crear Grupo»Endpoint: POST /{tenantSlug}/productos/grupos
Crea un nuevo grupo (categoría) para organizar productos.
Request Body:
{ "nombre": "Servicios Profesionales", "descripcion": "Servicios de consultoría y asesoría", "modoVisibilidad": "TODOS", "reglasDescuentoGrupo": { "OPERADOR": { "maxDescuento": 10, "tipoMax": "PORCENTAJE" }, "ADMIN": { "maxDescuento": 25, "tipoMax": "PORCENTAJE" } }}| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
nombre | string | Sí | Nombre del grupo (2-255 chars) |
descripcion | string | No | Descripción del grupo |
modoVisibilidad | enum | No | TODOS, SOLO_ROLES, EXCLUIR_ROLES |
rolesVisibilidad | array | No | Lista de roles para filtrar |
reglasDescuentoGrupo | object | No | Reglas de descuento por rol |
Ejemplo con curl:
curl -X POST "https://api.redcumbre.cl/{tenantSlug}/productos/grupos" \ -H "Authorization: Bearer {api_key}" \ -H "Content-Type: application/json" \ -d '{ "nombre": "Servicios Profesionales", "descripcion": "Servicios de consultoría y asesoría" }'Response (201 Created):
{ "success": true, "data": { "id": "uuid-grupo", "nombre": "Servicios Profesionales", "descripcion": "Servicios de consultoría y asesoría", "modoVisibilidad": "TODOS", "createdAt": "2024-01-15T10:30:00Z" }}Listar Grupos
Sección titulada «Listar Grupos»Endpoint: GET /{tenantSlug}/productos/grupos
Obtiene todos los grupos del tenant.
curl -X GET "https://api.redcumbre.cl/{tenantSlug}/productos/grupos" \ -H "Authorization: Bearer {api_key}"Response (200 OK):
{ "success": true, "data": [ { "id": "uuid-grupo-1", "nombre": "Servicios Profesionales", "descripcion": "Servicios de consultoría", "cantidadProductos": 15 }, { "id": "uuid-grupo-2", "nombre": "Productos", "cantidadProductos": 8 } ], "total": 2}Obtener Grupo
Sección titulada «Obtener Grupo»Endpoint: GET /{tenantSlug}/productos/grupos/{id}
Obtiene el detalle completo de un grupo.
curl -X GET "https://api.redcumbre.cl/{tenantSlug}/productos/grupos/{id}" \ -H "Authorization: Bearer {api_key}"Actualizar Grupo
Sección titulada «Actualizar Grupo»Endpoint: PATCH /{tenantSlug}/productos/grupos/{id}
Actualiza los datos de un grupo existente.
curl -X PATCH "https://api.redcumbre.cl/{tenantSlug}/productos/grupos/{id}" \ -H "Authorization: Bearer {api_key}" \ -H "Content-Type: application/json" \ -d '{ "nombre": "Servicios Profesionales Actualizado" }'Eliminar Grupo
Sección titulada «Eliminar Grupo»Endpoint: DELETE /{tenantSlug}/productos/grupos/{id}
Elimina un grupo de productos.
curl -X DELETE "https://api.redcumbre.cl/{tenantSlug}/productos/grupos/{id}" \ -H "Authorization: Bearer {api_key}"Error si tiene productos:
{ "statusCode": 400, "message": "No se puede eliminar: grupo tiene 5 productos asociados"}Códigos de Error
Sección titulada «Códigos de Error»| Código | Descripción | Causa común |
|---|---|---|
| 200 | OK | Operación exitosa |
| 201 | Created | Recurso creado |
| 400 | Bad Request | Error de validación o restricción |
| 403 | Forbidden | Sin autorización o acceso al tenant |
| 404 | Not Found | Producto o grupo no encontrado |
| 409 | Conflict | SKU duplicado |
Casos de Uso
Sección titulada «Casos de Uso»Crear Catálogo Inicial
Sección titulada «Crear Catálogo Inicial»# 1. Crear grupocurl -X POST ".../productos/grupos" \ -d '{"nombre": "Servicios de Consultoría"}'
# 2. Crear productos en el grupocurl -X POST ".../productos" \ -d '{ "nombre": "Consultoría Tributaria", "tipoComercial": "SERVICIO", "naturaleza": "INTANGIBLE", "grupoId": "uuid-grupo-creado", "precioBase": 150000, "estado": "ACTIVO" }'Integrar con Emisión de BHE
Sección titulada «Integrar con Emisión de BHE»// 1. Buscar producto en catálogoconst productos = await fetch( `${API_URL}/${tenant}/productos/autocomplete?tipoDocumento=BHE&nombre=consultor`);
// 2. Usar producto al emitir BHEconst bhe = await fetch(`${API_URL}/${tenant}/bhe`, { method: 'POST', body: JSON.stringify({ emisorTributarioId: '...', destinatarioRut: '78012039-8', detalle: producto.nombre, montoTotal: producto.precioBase, productoId: producto.id // Referencia al catálogo })});Configurar Descuentos por Rol
Sección titulada «Configurar Descuentos por Rol»# Crear grupo con reglas de descuentocurl -X POST ".../productos/grupos" \ -d '{ "nombre": "Servicios Premium", "reglasDescuentoGrupo": { "OPERADOR": { "maxDescuento": 5, "tipoMax": "PORCENTAJE" }, "ADMIN": { "maxDescuento": 15, "tipoMax": "PORCENTAJE" }, "SUPER-ADMIN": { "maxDescuento": 30, "tipoMax": "PORCENTAJE" } } }'
# Validar descuento antes de aplicarcurl -X POST ".../productos/validar-descuento" \ -d '{ "productoId": "uuid", "descuentoSolicitado": 10, "tipoDescuento": "PORCENTAJE", "rolUsuario": "OPERADOR", "precioBase": 100000 }'# Respuesta: { "permitido": false, "requiereAutorizacion": true }