> ## Documentation Index
> Fetch the complete documentation index at: https://firespark.cloud/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Productos

> Ítems individuales del menú — lo que el cliente agrega al pedido.

Un **producto** es un ítem vendible en el menú: una burger, un combo, una bebida, un side. Lleva **precio**, **descripción**, **grupos de modificadores** (elecciones que el cliente debe o puede hacer) y **disponibilidad** por tienda.

## Qué debe saber el equipo comercial

| Tema | En la práctica |
| - | - |
| Precios | Precio de lista, impuestos, límites de cantidad, precio ancla y configuración de modificadores por contexto |
| Ítems incluidos | Productos en combos o bundles, con reglas de reembolso si el cliente quita un ítem |
| Disponibilidad | Cuando un ítem se 86 en el POS, debe desaparecer donde el cliente pida |
| Imagen y copy | Canales propios muestran tus assets; agregadores tienen reglas de layout propias |

Los productos son donde **merchandising y operación se encuentran**. Marketing promociona ítems concretos; cocina debe recibir exactamente lo configurado.

## Grupos de modificadores y modificadores

La personalización de un producto se organiza en **grupos de modificadores**. Cada grupo le hace una pregunta al cliente; cada respuesta dentro del grupo es un **modificador**.

| Concepto | Qué es | Ejemplo |
| - | - | - |
| **Grupo de modificadores** | Conjunto de opciones relacionadas en un producto — a menudo con reglas (obligatorio, elige uno, elige varios, min/máx) | “Elige tu bebida”, “Agrega extras”, “Selecciona tamaño” |
| **Modificador** | Una opción seleccionable dentro de ese grupo | Coca-Cola, Sprite, agua embotellada |

El grupo es el **marco** (“¿qué bebida quieres?”). Los modificadores son las **opciones** que el cliente elige.

### Los modificadores pueden ser productos del catálogo

En muchos menús, cada modificador no es solo una etiqueta — apunta a un **producto real** del catálogo. El combo no embebe un “Coke” inventado; ofrece el mismo **producto Coca-Cola** que vendes suelto, con su SKU, delta de precio y mapeo en cocina.

```
Combo (producto)
└── Grupo: "Elige tu bebida" (obligatorio · elige 1)
    ├── Coca-Cola (modificador → producto bebida)
    ├── Sprite (modificador → producto bebida)
    └── Agua sin gas (modificador → producto bebida)
```

Ese patrón importa comercial y operativamente:

* **Combos y bundles** — Ítem base + el cliente elige bebida, side o postre desde ítems reales del catálogo.
* **Upsell** — “Agrega tocino” o “Tamaño grande” como grupos opcionales con modificadores con precio.
* **Precisión en cocina** — El ticket nombra el producto que la línea prepara o sirve, no una nota informal.
* **Inventario y 86** — Si el agua no está en stock en el POS, ese modificador desaparece del grupo en todos los canales.

Los grupos pueden ser **obligatorios** (el cliente debe elegir bebida) u **opcionales** (extra queso). Reglas como “elige exactamente uno” vs “hasta tres toppings” viven en el grupo, no en cada modificador.

Fire spark sincroniza productos, grupos de modificadores y modificadores desde tu operación. La misma estructura puede aparecer en menús compuestos distintos por canal, tienda, fulfillment u horario — sin duplicar maestros en el POS.

## Variantes y grupos de variantes

Algunos POS guardan cada configuración de un ítem como un producto distinto. Una pizza de pepperoni mediana de masa delgada tiene un PLU y una grande de masa gruesa tiene otro. El cliente igual espera una sola tarjeta ("Pizza de pepperoni") y un par de preguntas. Las **variantes** modelan eso: las respuestas no agregan extras, revelan qué producto se está comprando realmente.

| Concepto | Qué es | Ejemplo |
| - | - | - |
| **Grupo de variantes** | Una pregunta sobre el producto base, definida en `variant_groups` | "Tamaño", "Masa" |
| **Variante** | Una respuesta del grupo, con los productos a los que puede llevar | "Grande" → `pep-l-thin`, `pep-l-thick` |
| **Producto base** | La tarjeta que abre el cliente; define `pricing.variant_group_ids` | `pepperoni` |
| **Producto variante** | El PLU real que llega a cocina; define `pricing.variants` | `pep-l-thick` |

```
Pizza de pepperoni (producto base · variant_group_ids: size, crust)
├── Tamaño: Mediana | Grande
└── Masa:   Delgada | Gruesa
        ↓ Grande + Gruesa
    pep-l-thick (producto variante · su propio precio y grupos de modificadores)
```

En qué se diferencian de los modificadores:

* **La base solo sirve para elegir.** Nunca entra al carrito. La línea del pedido es el producto variante resuelto, con su propio precio, impuesto, disponibilidad y grupos de modificadores.
* **Una respuesta por grupo.** Los grupos de variantes no tienen cantidades ni reglas de mínimo/máximo. Hay que responder todos los grupos de la base.
* **Las variantes van primero.** Los canales hacen las preguntas de variantes antes de mostrar los grupos de modificadores del producto resuelto.
* **Un producto base no puede tener modificadores.** Un producto con `variant_group_ids` no puede definir también `modifier_group_ids`; pon los grupos de modificadores en cada producto variante.
* **Las bases también sirven como modificadores.** Un grupo de modificadores puede listar un producto base, por ejemplo una base "Refresco" en el grupo de bebida de un combo. La entrada de `pricing.modifiers` de la base para ese grupo define los límites de cantidad y el valor por defecto. El cliente responde las preguntas de variantes de la base dentro del modificador, y la línea del carrito es el producto variante resuelto, junto con sus propios grupos de modificadores. La entrada de `pricing.modifiers` de esa variante para el grupo define el precio cobrado y el impuesto; si no la tiene, se usa su propio `pricing.price`.
* **Solo se ofrecen combinaciones reales.** A medida que el cliente responde, desaparecen las opciones sin producto. Las opciones cuyo producto está agotado se muestran deshabilitadas. Los productos variante ocultos o inactivos se tratan como inexistentes.
* **Precio desde.** Si se omite, el `starting_price` de la base es el precio desde de su variante seleccionable más barata.

Ambos lados del vínculo son explícitos para que la sincronización pueda verificarlos. Cada variante lista sus `product_ids`, y cada producto variante indica en `pricing.variants` el `product_id` de la base y los `variant_group_option_ids` que lo seleccionan. Un producto puede ser variante de más de una base.

Los productos variante no necesitan aparecer en una categoría, grupo de modificadores ni recomendación. Basta con que la base sea alcanzable: la sincronización cuenta sus productos variante como referenciados, y la búsqueda de los canales lista tanto la base como cada producto variante.

### Validaciones de variantes en la sincronización

Una sincronización de menú se rechaza, con un error que nombra la entidad, si falla alguna de estas reglas:

| Regla |
| - |
| Los ids de grupos de variantes son únicos y los ids de variantes son únicos en todo el menú |
| Cada `variant_group_ids` existe y no se repite; cada grupo de variantes lo usa algún producto |
| Un producto base no tiene `modifier_group_ids` ni `pricing.variants` (no hay variantes anidadas) |
| Cada `product_ids` existe y no se repite dentro de una variante |
| Cada entrada de `pricing.variants` apunta a una base existente, una sola vez por base |
| Los vínculos de variantes no pueden ser circulares: un producto no puede resolverse desde sí mismo, ni directo ni pasando por otros productos |
| Sus `variant_group_option_ids` eligen exactamente una opción de cada grupo de la base y nada más |
| Las opciones elegidas listan el producto en sus `product_ids`, y toda opción que lista un producto tiene su entrada correspondiente |
| Dos productos variante de la misma base no comparten combinación; cada base tiene al menos un producto variante |
| Los grupos de modificadores no pueden volver a un producto, ni siquiera pasando por una base y sus productos variante |

Mira el [ejemplo de sincronización con variantes](https://firespark.cloud/docs/es/integrations-api/examples/menu-sync/variants.md) para ver un payload completo.

## Precios y bundles

Cada producto lleva un objeto **pricing** por canal, tienda y contexto de fulfillment:

| Campo | Significado |
| - | - |
| `price` | Precio de lista que ve el cliente |
| `is_tax_inclusive` / `tax_rate` | Si el impuesto está incluido y a qué tasa |
| `minimum_quantity` / `maximum_quantity` | Límites de pedido para este ítem |
| `anchor_price` / `anchor_price_percentage` | Precio de referencia y descuento para merchandising |
| `starting_price` | Precio más bajo que puede pagar el cliente al elegir los modificadores obligatorios |
| `modifier_group_ids` | Grupos de modificadores del producto |
| `modifiers` | Overrides de precio por modificador (cantidad por defecto, tipo de display, reglas de cobro) |
| `variant_group_ids` | Grupos de variantes que se preguntan en este producto base |
| `variants` | Productos base y opciones que seleccionan este producto como variante |

### Precio desde

Algunos productos no se pueden pedir a su `price` de lista porque un grupo de modificadores obligatorio agrega un cargo, por ejemplo una pizza donde todos los tamaños tienen costo extra. `starting_price` es el precio de referencia que ve el cliente en ese caso. Las tarjetas de producto muestran **"Desde \$X"** en lugar de `price` cuando `starting_price` es mayor que `price`.

| Valor que envías | Resultado |
| - | - |
| Omitido | Fire spark lo calcula durante el sync del menú con la selección más barata que cumple todos los grupos y mínimos obligatorios |
| Un número | Fire spark usa ese número tal cual |
| `null` | Sin precio desde; las tarjetas siempre muestran `price` |

El cálculo usa las mismas reglas que el checkout: `minimum_quantity` por modificador y por grupo, `maximum_quantity` del modificador, `charge_above_quantity` y grupos obligatorios anidados. El log de cada sync de menú registra a cuántos productos se les calculó el precio desde.

Los **bundled\_items** modelan combos: cada entrada referencia un producto real del catálogo con `included_quantity` y `refund_price` si el cliente inicia un reclamo sobre el bundle.

## Conceptos relacionados

> [card] [Categorías](https://firespark.cloud/docs/es/concepts/categories.md)
>
> Dónde aparecen los productos en el menú

> [card] [Menús](https://firespark.cloud/docs/es/concepts/menus.md)
>
> Catálogo completo sincronizado a canales

> [card] [Pedidos](https://firespark.cloud/docs/es/concepts/orders.md)
>
> Productos y elecciones de modificadores en una compra


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.