Ir al contenido

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

Para usar la API del catálogo necesitas:

  1. Una API Key con uno de estos roles: ADMIN, SUPER-ADMIN, o FULL-API
  2. Acceso al tenant correspondiente

TipotipoComercialnaturalezaUso típico
Producto físicoPRODUCTOTANGIBLEBienes, mercadería
ServicioSERVICIOINTANGIBLEConsultoría, asesoría, honorarios

Para Boletas de Honorarios (BHE), solo se permiten servicios (tipoComercial: SERVICIO).

EstadoDescripciónVisible en búsquedas
ACTIVODisponible para usar en documentos
INACTIVODeshabilitado temporalmenteNo
BORRADOREn proceso de configuraciónNo

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
EsquemaDescripción
PRECIO_FIJOPrecio único por unidad
PRECIO_GRADUADOPrecio variable según cantidad (tramos)
SIN_PRECIOSin 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 }
]

Los descuentos pueden controlarse a dos niveles:

  1. Por Producto: aceptaDescuentos, tipoDescuentoMax, valorDescuentoMax
  2. Por Grupo/Rol: reglasDescuentoGrupo define límites por rol
"reglasDescuentoGrupo": {
"OPERADOR": { "maxDescuento": 10, "tipoMax": "PORCENTAJE" },
"ADMIN": { "maxDescuento": 25, "tipoMax": "PORCENTAJE" }
}

El campo permisoEdicion controla si el precio de un producto puede modificarse al momento de emitir documentos (BHE, BHET):

PermisoComportamiento
NO_PERMITIDAPrecio fijo. No se puede modificar al emitir
DENTRO_RANGO_DESCUENTOSe puede reducir el precio hasta el descuento máximo configurado
LIBRECualquier precio es válido (requiere rol autorizado)

Interacción con esquemaPrecio:

  • Productos con esquemaPrecio: SIN_PRECIO siempre permiten ingresar precio manualmente
  • El permisoEdicion se evalúa solo para productos con precio definido (PRECIO_FIJO o PRECIO_GRADUADO)

El modo sandbox permite probar la API sin persistir datos reales.

El modo sandbox se activa automáticamente cuando tu API Key tiene isSandbox: true.

En modo sandbox, los endpoints retornan fixtures predefinidos:

EndpointRespuesta Sandbox
GET /productos6 productos de ejemplo
POST /productosProducto simulado (no persiste)
GET /productos/grupos3 grupos de ejemplo
POST /validar-descuentoSiempre permitido: true

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
}
CampoTipoRequeridoDescripción
nombrestringNombre del producto (2-255 chars)
tipoComercialenumPRODUCTO o SERVICIO
naturalezaenumTANGIBLE o INTANGIBLE
codigoSkustringNoCódigo único (auto-generado si no se envía)
codigoBarrasstringNoCódigo de barras (EAN-13, UPC, etc.). Solo números. Único por tenant
descripcionstringNoDescripción detallada
estadoenumNoACTIVO, INACTIVO, BORRADOR (default: BORRADOR)
grupoIdstringNoID del grupo/categoría
precioBasenumberNoPrecio unitario en CLP
esquemaPrecioenumNoPRECIO_FIJO, PRECIO_GRADUADO, SIN_PRECIO
aceptaDescuentosbooleanNoPermite aplicar descuentos (default: true)
tipoDescuentoMaxenumNoPORCENTAJE o MONTO_FIJO
valorDescuentoMaxnumberNoLímite máximo de descuento
permisoEdicionenumNoNO_PERMITIDA, DENTRO_RANGO_DESCUENTO, LIBRE (default: NO_PERMITIDA)

Ejemplo con curl:

Ventana de terminal
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"
}
}

Endpoint: GET /{tenantSlug}/productos

Obtiene un listado paginado de productos con filtros opcionales.

Query Parameters:

ParámetroTipoDescripción
busquedastringBúsqueda en nombre, descripción, SKU, código de barras
tipoComercialenumPRODUCTO o SERVICIO
estadoenumACTIVO, INACTIVO, BORRADOR
grupoIdstringFiltrar por grupo/categoría
visibleEnBhebooleanSolo productos visibles en BHE
visibleEnFacturabooleanSolo productos visibles en Facturas
visibleEnBoletabooleanSolo productos visibles en Boletas
limitnumberResultados por página (1-100, default: 50)
offsetnumberRegistros a saltar (paginación)

Ejemplo con curl:

Ventana de terminal
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
}

Endpoint: GET /{tenantSlug}/productos/{id}

Obtiene el detalle completo de un producto.

Ejemplo con curl:

Ventana de terminal
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"
}
}

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:

Ventana de terminal
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"
}'

Endpoint: POST /{tenantSlug}/productos/{id}/activar

Cambia el estado del producto a ACTIVO.

Ventana de terminal
curl -X POST "https://api.redcumbre.cl/{tenantSlug}/productos/{id}/activar" \
-H "Authorization: Bearer {api_key}"

Endpoint: POST /{tenantSlug}/productos/{id}/inactivar

Cambia el estado del producto a INACTIVO.

Ventana de terminal
curl -X POST "https://api.redcumbre.cl/{tenantSlug}/productos/{id}/inactivar" \
-H "Authorization: Bearer {api_key}"

Endpoint: DELETE /{tenantSlug}/productos/{id}

Cambia el estado a INACTIVO (soft delete). El producto NO se elimina físicamente y puede reactivarse.

Ventana de terminal
curl -X DELETE "https://api.redcumbre.cl/{tenantSlug}/productos/{id}" \
-H "Authorization: Bearer {api_key}"

Endpoint: GET /{tenantSlug}/productos/autocomplete

Búsqueda rápida para usar en formularios de documentos tributarios.

Query Parameters:

ParámetroTipoRequeridoDescripción
tipoDocumentoenumBHE, FACTURA, o BOLETA
skustringNoBúsqueda por prefijo SKU
nombrestringNoBúsqueda por nombre (contains)
codigoBarrasstringNoBúsqueda por código de barras (contains)
limitnumberNoMá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:

Ventana de terminal
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
}
]
}

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
}
CampoTipoRequeridoDescripción
productoIdstringID del producto
descuentoSolicitadonumberPorcentaje o monto (0-100)
tipoDescuentoenumPORCENTAJE o MONTO_FIJO
rolUsuariostringRol del usuario solicitante
precioBasenumberPrecio 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:

permitidorequiereAutorizacionSignificado
truefalseDescuento permitido sin restricción
falsetrueRequiere aprobación de rol superior
falsefalseProducto no acepta descuentos

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" }
}
}
CampoTipoRequeridoDescripción
nombrestringNombre del grupo (2-255 chars)
descripcionstringNoDescripción del grupo
modoVisibilidadenumNoTODOS, SOLO_ROLES, EXCLUIR_ROLES
rolesVisibilidadarrayNoLista de roles para filtrar
reglasDescuentoGrupoobjectNoReglas de descuento por rol

Ejemplo con curl:

Ventana de terminal
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"
}
}

Endpoint: GET /{tenantSlug}/productos/grupos

Obtiene todos los grupos del tenant.

Ventana de terminal
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
}

Endpoint: GET /{tenantSlug}/productos/grupos/{id}

Obtiene el detalle completo de un grupo.

Ventana de terminal
curl -X GET "https://api.redcumbre.cl/{tenantSlug}/productos/grupos/{id}" \
-H "Authorization: Bearer {api_key}"

Endpoint: PATCH /{tenantSlug}/productos/grupos/{id}

Actualiza los datos de un grupo existente.

Ventana de terminal
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"
}'

Endpoint: DELETE /{tenantSlug}/productos/grupos/{id}

Elimina un grupo de productos.

Ventana de terminal
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ódigoDescripciónCausa común
200OKOperación exitosa
201CreatedRecurso creado
400Bad RequestError de validación o restricción
403ForbiddenSin autorización o acceso al tenant
404Not FoundProducto o grupo no encontrado
409ConflictSKU duplicado

Ventana de terminal
# 1. Crear grupo
curl -X POST ".../productos/grupos" \
-d '{"nombre": "Servicios de Consultoría"}'
# 2. Crear productos en el grupo
curl -X POST ".../productos" \
-d '{
"nombre": "Consultoría Tributaria",
"tipoComercial": "SERVICIO",
"naturaleza": "INTANGIBLE",
"grupoId": "uuid-grupo-creado",
"precioBase": 150000,
"estado": "ACTIVO"
}'
// 1. Buscar producto en catálogo
const productos = await fetch(
`${API_URL}/${tenant}/productos/autocomplete?tipoDocumento=BHE&nombre=consultor`
);
// 2. Usar producto al emitir BHE
const 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
})
});
Ventana de terminal
# Crear grupo con reglas de descuento
curl -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 aplicar
curl -X POST ".../productos/validar-descuento" \
-d '{
"productoId": "uuid",
"descuentoSolicitado": 10,
"tipoDescuento": "PORCENTAJE",
"rolUsuario": "OPERADOR",
"precioBase": 100000
}'
# Respuesta: { "permitido": false, "requiereAutorizacion": true }