Combora — Manual de usuario
Guía completa de la app de packs y descuentos para Shopify: los 8 tipos de oferta, cada opción de configuración, lo que ve tu cliente en la tienda, y un anexo técnico para desarrolladores. Todas las capturas provienen de la tienda demo pública de Combora —la misma que puedes probar tú— tomadas en agosto de 2026, y las de la app muestran la interfaz en el idioma de este manual.
1Qué es Combora
Combora crea packs (bundles) y ofertas automáticas en tu tienda Shopify: agrupa productos, aplica el descuento correcto en el carrito y el checkout, y muestra la oferta en tu tema con bloques listos para usar. Tú configuras la oferta en el admin, y el descuento lo calcula una Shopify Function en el propio checkout — el precio cobrado es el que calcula la propia plataforma, no un script en el navegador.
Hay 8 tipos de pack. Esta tabla te ayuda a elegir:
| Tipo | Qué hace | Cuándo usarlo |
|---|---|---|
| Pack fijo | Un conjunto cerrado de productos con precio de pack o descuento. Crea un producto comprable de 1 clic en tu catálogo. | Kits y sets curados: "el dúo", "el kit de iniciación". |
| Combina y ahorra (mix & match) | El cliente elige N artículos de un grupo y recibe un descuento. | "Elige 3 camisetas y ahorra 20%". |
| Descuento por volumen | Niveles: cuanto más compra, más ahorra (2+ → 10%, 4+ → 20%…). | Subir unidades por pedido de un mismo producto o grupo. |
| Compra X, llévate Y (BOGO) | Al comprar X unidades, las siguientes Y salen con recompensa (gratis, % o precio fijo). | "Compra 2 y llévate 1 gratis". |
| Regalo por compra (GWP) | Añade un regalo gratis automáticamente cuando el carrito cumple una condición. | "Regalo sorpresa en pedidos de $50+". |
| Arma tu caja (build-a-box) | El cliente llena una caja de tamaño fijo; se cobra con descuento o a precio de caja. | Cajas de 4, 6, 12… snacks, velas, cervezas. |
| Complementos (FBT) | "Comprados juntos habitualmente": un producto principal sugiere añadidos con descuento. | Cross-sell en la ficha de producto. |
| Combo | Apila dos o más de las ofertas anteriores en un solo pack; dentro del combo sí se suman. | Campañas: "volumen + regalo a partir de $1,000". |
Si dudas entre tipos, la propia app trae una guía: en Crear pack, el enlace "¿No sabes cuál elegir?" abre un asistente, y cada tipo tiene un panel "Ver cómo funciona" con ejemplos.
2Primeros pasos
2.1 Qué crea la app al instalarse
Al instalar Combora no cambia nada visible en tu tienda. La app prepara en segundo plano las
estructuras de datos donde publicará tus packs (metaobjetos y metafields con el prefijo
combora — el detalle técnico está en el anexo para desarrolladores)
y un único descuento automático llamado "Combora" en Descuentos, que es el que aplica todos los
precios. No lo borres ni lo edites a mano: la app lo mantiene sola.
2.2 Activar el motor de regalos (app embed)
Si vas a usar Regalo por compra (o combos con regalo), activa el app embed Combora Gift: Tienda online → Personalizar → Configuración del tema → App embeds → Combora Gift. Es el componente que añade y retira el regalo del carrito automáticamente. Sin él, el descuento del regalo seguiría siendo correcto, pero el producto-regalo no se añadiría solo.
2.3 Añadir los bloques al tema
Cada tipo de pack se muestra en la tienda con un bloque de tema. Se añaden una sola vez en Tienda online → Personalizar, en la plantilla correspondiente:
| Bloque | Tipos que muestra | Dónde añadirlo |
|---|---|---|
| Combora bundle | Pack fijo y Combo ("Available bundles") | Plantilla de producto |
| Combora mix & match | Combina y ahorra · Arma tu caja | Plantilla de producto |
| Combora volume table | Volumen · Compra X llévate Y | Plantilla de producto |
| Combora complements | Complementos | Plantilla de producto (y carrito) |
| Combora gift offer | Regalo por compra (la oferta) | Plantilla de producto |
| Combora gift progress | Barra de progreso del regalo | Plantilla del carrito |
| Combora Gift (app embed) | El motor que añade/quita el regalo | App embeds (toda la tienda) |
No hace falta memorizarlo: el editor de cada pack incluye una tarjeta "Dónde aparece" que nombra el bloque correcto y un enlace "Ver en tu tema publicado" que abre el editor de temas con ese bloque ya preparado para insertarse en la plantilla adecuada.
3Tour de la app
La app vive en Apps → Combora. El menú tiene seis entradas — Inicio, Packs, Analítica, Planes, Ayuda y Ajustes — más el chat de soporte, que está en todas las pantallas:
Inicio
La pantalla de bienvenida y el pulso de tu instalación. Mientras terminas la puesta en marcha muestra un checklist de tres pasos — crear tu primer pack, publicarlo y (si tu oferta es un regalo por compra) activar el motor de regalos en el tema. El checklist no es decorativo: cada paso se marca solo cuando de verdad ocurrió en tu tienda, el botón de acción vive únicamente en el paso que toca, y si más tarde despublicas todo, el checklist reaparece reflejando la realidad. Al completarlo, Inicio lo celebra con un enlace directo a ver tu tienda (puedes descartar la nota cuando quieras).
Debajo del checklist: tus packs más recientes con su estado, una banda de atención si algún pack necesita revisión (por ejemplo, porque archivaste un producto que lo componía — la app lo detecta sola y te lo señala sin despublicar nada), y una tira con tu plan actual.
Packs
La lista de todos tus packs: búsqueda por nombre, filtro por estado (Publicado / Borrador), acciones por fila (duplicar, publicar/pasar a borrador, eliminar) y selección múltiple con acciones masivas. Desde aquí se crea todo con Crear pack.
Analítica
Métricas de rendimiento de tus packs sobre pedidos reales: ingresos atribuidos, % de pedidos con pack, ahorro entregado, valor medio de pedido y un gráfico temporal. Detalle en la sección 17.
Planes
Tu plan actual y las opciones de upgrade. El plan Gratis permite 3 packs publicados simultáneamente; los planes de pago no tienen límite (sección 18).
Ayuda
Preguntas frecuentes y explicaciones de conceptos (arbitraje entre packs, regalos, bloques).
Diagnóstico (pestaña dentro de Ayuda)
El panel de salud y soporte vive como pestaña dentro de Ayuda (selector "Guías | Diagnóstico" arriba): chequeos en vivo de toda la instalación, el registro de eventos y el informe de soporte que copias cuando algo va mal (sección 19).
Chat de soporte (burbuja flotante)
En la esquina inferior derecha de todas las pantallas hay una burbuja de chat 💬 para hablar directamente con soporte: conversaciones por tema, historial, y aviso de si soporte está disponible o ausente. Solo se comparte lo que escribes — nunca datos de tus clientes.
Ajustes
Idioma de la app (7 idiomas), el Diseño de widgets (la plantilla de estilo de toda la tienda — sección 13), la sincronización manual de descuentos y el acceso para desarrolladores.
4Anatomía del editor
Todos los tipos comparten el mismo editor; cambia solo la sección de productos y precio. Al crear un pack nuevo se ve así:
4.1 Datos básicos
- Nombre del pack
- Interno. Solo tú lo ves; sirve para encontrarlo en tu lista.
- Título en la tienda
- Lo que ve el cliente como nombre de la oferta en el carrito y el checkout. Es traducible. También es el texto de la línea de descuento (recortado a 100 caracteres).
- Texto de la etiqueta
- Una insignia corta opcional ("Mejor valor") que tu tema puede mostrar como destacado.
4.2 Programación
Fechas de inicio y fin opcionales. Vacías = la oferta se activa al publicar y no caduca. Un pack publicado fuera de su ventana deja de aplicar el descuento automáticamente y vuelve a aplicarlo al entrar en ventana, sin tocar nada.
4.3 Productos
Según el tipo, eliges productos concretos (y, dentro de cada producto, puedes marcar solo algunas de sus variantes) o una colección. El alcance "cualquier producto de la tienda" existe solo en el regalo por compra, como condición. El selector de Shopify es el estándar:
4.4 Precio
Cada tipo tiene su propia sección (porcentaje, importe, precio fijo, niveles, recompensa…). Se documenta en el capítulo de cada tipo. En todos los casos el precio que se cobra lo calcula Shopify en el checkout con la configuración publicada: lo que muestran los bloques es informativo.
4.5 Suscripciones
Por defecto un cliente no puede comprar un artículo del pack como suscripción (protege el checkout de precios de suscripción mezclados con descuentos de pack). En los tipos donde tiene sentido (mix & match, arma tu caja y regalo por compra) hay un opt-in avanzado "Permitir suscripciones en este pack (avanzado)"; al activarlo, el editor muestra un aviso recordando lo que implica.
4.6 El rail derecho (y dos secciones del cuerpo)
Además de Guardar (y Guardar como borrador en un pack aún no publicado), con la barra de Cambios sin guardar / Guardar / Descartar arriba, el editor organiza así el resto:
- Estado + acción (rail)
- Publicar (o Actualizar pack si ya está publicado) y Pasar a borrador. Publicar pone la oferta en vivo; pasar a borrador la retira conservando toda la configuración.
- Modo prueba (cuerpo)
- Marca "Publicar en modo prueba" para probar el pack sin exponerlo a tus clientes. Los widgets se muestran solo en el editor de temas — abre ahí la plantilla de producto y el pack aparece justo donde va a quedar. En tu tienda nunca se muestran, ni siquiera por el enlace de vista previa de un tema borrador. Mientras el pack esté en modo prueba el descuento se calcula solo para clientes con la etiqueta
combora-test; para el resto, el pack es como si no existiera. Para recorrer el checkout completo, añade esa etiqueta a tu propio cliente de pruebas (Admin → Clientes) e inicia sesión con él en la tienda. Al desmarcar la casilla y pulsar Actualizar pack pasa a en vivo y se aplica a cualquiera que cumpla las condiciones. En la lista, un pack en prueba lleva la insignia Modo prueba. - Visibilidad en el catálogo (cuerpo)
- Solo en packs fijos: si el producto padre del pack aparece en tu catálogo o no (sección 5).
- Antes de publicar (rail)
- La checklist que bloquea la publicación hasta completar lo imprescindible (título, productos, precio…).
- Lo que ve tu cliente (rail)
- Mientras a la oferta le falta algo, esta tarjeta explica qué falta y anticipa el contenido. Cuando la oferta está completa, la tarjeta cede el sitio a la vista previa real del widget en Ver vista previa. El aspecto final depende de tu tema.
- Estilo de la vista previa (rail, solo packs ya creados)
- Nombra el diseño activo del widget de este pack y trae Ver vista previa (el widget a tamaño real en un modal) y Personalizar diseño (el estudio de diseño de este pack: presets, orden de los elementos y estilo por elemento — sección 13). En un pack recién creado aparece tras el primer guardado.
- Dónde aparece (rail)
- El bloque de tema que muestra este tipo y el enlace directo al editor de temas.
El pack con programación muestra además su insignia de ventana (Programada / Activa / Finalizada) y el botón Quitar programación para volver a "activo al publicar".
4.7 Avisos que puede mostrar el editor
- Solapamiento: si los productos del pack ya están en otros packs publicados, un banner avisa: "En el checkout solo se aplica la mejor oferta por línea: los packs no se acumulan". No es un error — es información (ver sección 14).
- Sin ahorro / precio 0: en un pack fijo con precio de pack, si el precio elegido no ahorra nada (o es 0), el editor lo señala antes de publicar.
- Pool vacío: una colección sin productos elegibles se refleja como nota en la vista previa y, si intentas publicar, como error con la explicación.
4.8 Editar un pack publicado
Al editar un pack publicado, tus cambios se guardan sin llegar a tu tienda. El editor muestra tu edición, tus clientes siguen viendo la versión publicada a su precio publicado, y el pack queda marcado como Cambios sin publicar en tu lista. Pulsa “Actualizar pack” para publicarlos, o descártalos desde el aviso del editor. Así puedes preparar cambios con calma. "Pasar a borrador" retira la oferta de la tienda al momento; volver a publicar la restaura tal cual.
5Pack fijo
Un conjunto cerrado de productos que se vende como una unidad. Es el único tipo que además crea un producto comprable de 1 clic en tu catálogo: un producto "padre" (bundle nativo de Shopify) cuyos componentes se expanden automáticamente en el checkout.
5.1 Configuración
- Productos: añade los componentes (variantes concretas) y la cantidad de cada uno. Máximo 30 componentes por pack.
- Precio — dos modos excluyentes:
- Precio fijo del pack: escribes el precio total (p. ej. $1,299.00). El ahorro se calcula contra la suma de los componentes.
- Aplicar un descuento: porcentaje o importe sobre la suma de los componentes.
- Visibilidad en el catálogo: los packs fijos son productos de Shopify de verdad, así que
decides si el pack aparece además en tu catálogo o solo se llega a él desde el widget:
- Oculto — solo desde el widget (por defecto): el pack no sale en colecciones, ni en la búsqueda de la tienda, ni en las recomendaciones. Su ficha sigue viva, para que el botón del widget funcione.
- Visible — un producto normal del catálogo: aparece en colecciones y búsqueda como cualquier producto.
- Publica. Al publicar, Combora crea (o actualiza) el producto padre en tu catálogo — y, si el pack aún no tiene imagen, le copia la del primer componente, en AMBOS modos de visibilidad (un pack oculto se sigue viendo en el carrito, el checkout y los emails del pedido). Nunca pisa una imagen que hayas puesto tú; cámbiala cuando quieras en Admin → Productos.
5.2 Qué ve tu cliente
5.3 Detalles y limitaciones del tipo
- Los componentes deben ser variantes con stock; el producto padre hereda la disponibilidad.
- El producto padre se gestiona solo: al pasar a borrador o eliminar el pack, se retira de la tienda (verificado durante este manual). No lo borres a mano.
- Por defecto el padre está oculto en el catálogo. Antes de que existiera esa opción,
aparecía en
/collections/allcomo una tarjeta sin imagen; los packs que ya tenías publicados se pasaron a "Oculto" automáticamente. Si prefieres el comportamiento anterior, cámbialo a Visible. - Máximo 30 componentes. El precio fijo se reparte entre componentes con redondeo exacto (la suma de las partes siempre iguala el total).
- El pack fijo también aplica si el cliente añade los componentes por separado en las cantidades exactas — el checkout agrupa y descuenta igual.
6Combina y ahorra (mix & match)
El cliente elige al menos N artículos de un grupo y todo el grupo sale con descuento.
6.1 Configuración
- Productos: el grupo elegible puede ser productos concretos — marcando, si quieres, solo algunas variantes de cada uno dentro del selector — o una colección (se actualiza sola).
- Cantidad: el mínimo de artículos para calificar, y opcionalmente un máximo (por encima del máximo, los artículos extra se pagan a precio normal).
- Descuento: porcentaje o importe, aplicado a todos los artículos elegibles del carrito cuando se alcanza el mínimo.
6.2 Qué ve tu cliente
6.3 Detalles del tipo
- Un carrito por debajo del mínimo no se bloquea: el cliente paga precio completo hasta calificar.
- Con máximo definido, el selector bloquea marcar más casillas al llegar al tope, y en el carrito solo las primeras unidades hasta el máximo reciben descuento.
- Las cantidades cuentan por unidades: 3 unidades de un mismo producto elegible también califican un mínimo de 3.
7Descuento por volumen
Niveles de precio por cantidad: "compra al menos 2 → 10%, al menos 4 → 20%". El nivel se decide por producto: la cantidad de cada producto elegible en el carrito determina su propio nivel, y el descuento alcanzado se aplica a las unidades de ese producto. Ejemplo con "4+ → 20%": 4 unidades de la misma tabla → 20% sobre las 4; pero 2 unidades de una tabla + 2 de otra → cada producto está en el nivel de 2+ (10%), no en el de 4+. Las cantidades de productos distintos no se suman entre sí.
7.1 Configuración
- Productos: productos concretos o una colección (igual que mix). Si de un producto solo quieres algunas variantes, márcalas dentro del selector al elegirlo.
- Niveles: cada nivel es "Compra al menos N" + descuento (porcentaje o importe). Añade tantos como necesites con "Agregar nivel" (hasta 50).
7.2 Qué ve tu cliente
7.3 Detalles del tipo
- Solo aplica el nivel más alto alcanzado (no se suman niveles).
- Los niveles pueden mezclar tipos de valor (unos %, otros importe).
- El importe fijo de descuento se reparte entre las líneas de forma proporcional y exacta.
8Compra X, llévate Y (BOGO)
Al comprar X unidades, las siguientes Y unidades salen con recompensa. La recompensa puede ser gratis (100%), un porcentaje, un importe de descuento o un precio fijo por unidad.
8.1 Configuración
8.2 Qué ve tu cliente
8.3 Detalles del tipo
- La oferta se repite por bloques completos: con "2+1", 6 unidades = 2 gratis; 5 unidades = 1 gratis.
- El bloque de tema que la muestra es Combora volume table (presenta el "compra X, llévate Y" como una tabla de ahorro).
- La recompensa "precio fijo" cobra ese precio exacto por cada unidad recompensada.
9Regalo por compra (GWP)
Añade un producto de regalo (a $0.00) automáticamente cuando el carrito cumple la condición, y lo retira si deja de cumplirla. Es el tipo con más automatismo: el app embed Combora Gift gestiona el regalo sin que el cliente haga nada.
9.1 Configuración
- El regalo: una variante concreta que se agrega cuando el cliente califica.
- Condición para desbloquear — cuatro opciones:
- Por gasto mínimo: el carrito alcanza un importe (p. ej. $1,000).
- Por cantidad de productos: alcanza N unidades.
- Gasto y cantidad (ambas): se exigen las dos.
- Por llevar una combinación de productos: una lista concreta de artículos (de 2 a 5; una unidad de cada uno) que debe estar completa en el carrito.
- Qué cuenta para la condición: cualquier producto de la tienda, productos específicos o colecciones.
9.2 Qué ve tu cliente
La barra tiene cuatro estados y, desde el carrito vacío, nombra el regalo y lo que cuenta: antes de empezar enuncia la regla ("gasta $1,000 en esa tabla y llévate la cera gratis"), a medio camino dice qué falta, al pasar el umbral anuncia el regalo por su nombre, y si el cliente lo quita a mano lo dice en vez de quedarse en "aplicando". Cuando cuentan más de tres productos, la barra dice productos elegibles y añade un desplegable "¿Qué productos cuentan?" que los lista.
{{ amount }} (lo que falta),
{{ qty }} (artículos que faltan), {{ scope }} (los productos que cuentan),
{{ gift }} (el nombre del regalo) y {{ threshold }} (el umbral completo). El
editor previsualiza el resultado con las cifras de tu propio pack y no deja publicar un comodín
desconocido ni un mensaje de más de 160 caracteres.9.3 Detalles y protecciones del tipo
- El propio regalo no cuenta para el gasto que califica.
- El umbral se mide sobre el precio de lista de lo que califica, no sobre lo que el cliente acaba pagando, así que otra oferta que rebaje esas mismas líneas nunca se lo come. La barra, el regalo automático y el checkout leen el mismo número.
- Si el cliente elimina el regalo a mano, la app lo respeta y no lo vuelve a añadir en esa sesión; la barra del carrito lo dice tal cual ("Regalo retirado") en vez de quedarse "aplicando".
- Si retiras la oferta (pasar a borrador, fin de la ventana) con carritos abiertos que ya llevaban el regalo, el motor retira solo esa línea huérfana en cuanto el carrito vuelve a moverse — nunca se convierte en un cobro.
- Si el regalo se queda sin stock, la oferta simplemente no lo añade (no bloquea la compra).
- Protección anticobro: una validación en el checkout impide pagar un regalo que figura como regalo pero llegó con precio — el comprador nunca paga por error un artículo marcado de regalo. La validación actúa solo en el checkout, nunca mientras se navega.
- Cuando "qué cuenta" son colecciones, la app resuelve los productos de la colección al publicar (y los refresca cada noche, o al momento si re-publicas — las dos velocidades de la sección 4.3), así que la barra de progreso y el regalo automático funcionan igual que con productos concretos. Única excepción: una colección enorme (más de ~150 productos) no se predice desde el navegador — la barra no se muestra para esa oferta, pero el regalo y el precio siguen siendo correctos (los decide el servidor).
- Un regalo cuyo "qué cuenta" es cualquier producto de la tienda puede anunciarse con el bloque Combora gift offer en todas las fichas de producto: al elegir ese alcance, el editor muestra la casilla "Mostrar esta oferta de regalo en todas las fichas de producto". Desactivada (el valor por defecto), la oferta solo se ve en el carrito — la barra de progreso y el regalo automático funcionan igual; activada, además se anuncia con una tarjeta en cada ficha (la oferta no tiene productos concretos que marcar, así que el bloque la lee del índice publicado de la tienda). La excepción, a propósito, sigue siendo la ficha del propio producto-regalo: un premio no es un gancho.
10Arma tu caja (build-a-box)
El cliente llena una caja de tamaño fijo (p. ej. 3 artículos) con lo que elija de un grupo. Cada caja completa se cobra con descuento o a un precio de caja cerrado.
10.1 Configuración
10.2 Qué ve tu cliente
Usa el mismo bloque Combora mix & match y el mismo selector con contador que la sección 6: "selecciona 3", contador de progreso, CTA con cantidad. La diferencia es la matemática: aquí las cajas se cobran por caja completa — con caja de 3, seis artículos son dos cajas; siete artículos son dos cajas y un artículo a precio normal.
10.3 Detalles del tipo
- Grupo elegible: productos concretos (con sus variantes, si marcas solo algunas) o una colección (el selector visual aparece con cualquier alcance, como en mix — con colecciones la lista se resuelve al publicar y se refresca cada noche).
- El precio de caja se reparte entre los artículos de forma exacta; con monedas sin decimales (JPY) o con tres decimales (BHD) el reparto respeta la moneda.
- Admite el opt-in de suscripciones (apartado 4.5).
11Complementos (comprados juntos habitualmente)
Un producto principal sugiere productos complementarios; si el cliente se lleva el conjunto, recibe un descuento. Es el clásico "frequently bought together" de la ficha de producto.
11.1 Configuración
11.2 Qué ve tu cliente
11.3 Detalles del tipo
- El descuento se aplica cuando el principal y al menos un complemento están en el carrito; cubre las líneas del conjunto.
- El bloque también puede añadirse a la plantilla del carrito como último empujón de cross-sell.
- Los complementos agotados aparecen deshabilitados con su aviso, nunca se pre-marcan.
12Combo
El tipo avanzado: apila dos o más subofertas (de cualquiera de los otros tipos) en un solo pack. La diferencia clave con publicar packs separados: dentro de un combo las subofertas se suman — el cliente puede recibir el descuento por volumen y el regalo a la vez.
12.1 Configuración
Cada fila se despliega en el sitio con la flecha y la suboferta se edita en línea: sus propios productos, sus propios tramos o su recompensa. Cada suboferta solo afecta a sus propios productos.
12.2 Qué ve tu cliente
Un combo no se anuncia como card en el bloque Combora bundle: ese bloque lista packs fijos, que tienen un precio y un botón, y un combo no tiene ninguno de los dos. Cada suboferta se promociona con su propio bloque — la tabla de volumen para una suboferta de volumen, la barra de regalo para una de regalo — y el combo enseña su efecto completo en el carrito, donde cada parte actúa con su propia etiqueta: el descuento de volumen en sus líneas y el regalo auto-añadido a $0.00.
Medido en la tienda demo sobre un combo que suma "2 o más de esta tabla → 15% menos" y "un gorro gratis en cuanto lleves $900.00 de ella": dos tablas pasan de $1,040.00 a $850.00 — el 15% y el gorro a $0.00 — y tres pasan de $1,540.00 a $1,275.00. Dos packs separados nunca harían las dos cosas sobre la misma línea; dentro de un combo las subofertas se suman (sección 14).
12.3 Detalles del tipo
- Las subofertas se suman dentro del combo, pero el combo compite como un todo contra los demás packs por la regla de la mejor oferta por línea.
- El regalo de una suboferta GWP usa el mismo motor auto-add que el tipo regalo.
- Límite de tamaño: el conjunto aplanado de productos del combo no puede superar 50 entradas (el editor lo muestra: "Usa X de 50").
- El editor trae el modal "Cómo funcionan los combos" con un ejemplo guiado, y cada suboferta define "Productos a los que se aplica esta oferta" — una suboferta sin productos concretos muestra un aviso porque no podrá preciar.
- Una suboferta BOGO dentro de un combo ofrece recompensa en porcentaje o importe (el "precio fijo por unidad" es exclusivo del BOGO independiente).
13Diseñar el widget
Los bloques de Combora salen de fábrica con un aspecto que encaja en cualquier tema, pero puedes diseñarlos desde la app, sin tocar CSS: elegir un estilo, reordenar y ocultar elementos, y ajustar colores, tamaños y formas elemento por elemento. Todo con una vista previa que usa el mismo motor de dibujo que tu tienda, así que lo que ves es lo que se publica.
13.1 Dos sitios donde se diseña
| Dónde | Alcance | Cuándo usarlo |
|---|---|---|
| Ajustes → Diseño de widgets → Editar plantilla de widgets | La plantilla de toda la tienda: la heredan todos los packs. | Lo normal. Defines tu estilo una vez y todos los packs lo siguen. |
| Editor del pack → Personalizar diseño | Solo ese pack. Lo que definas aquí gana sobre la plantilla, campo a campo. | Un pack que necesita destacar (una campaña, un color distinto). |
Un pack que no ha tocado nada muestra el aviso "Este pack sigue la plantilla de widgets de tu tienda". En cuanto eliges un preset ahí, ese pack va por su cuenta.
13.2 Los estilos (presets)
- Plantilla de la tienda
- Solo en el diseño de un pack: sigue lo que hayas definido en Ajustes. Es el valor de partida. Si aún no hay plantilla, aplican los ajustes del bloque en el editor de temas.
- Editor de temas
- Mandan los ajustes del propio bloque en tu editor de temas (acento, esquinas, modo de estilo). Es el comportamiento clásico, el que tenías antes de que existiera el estudio.
- Combora
- El look pulido de Combora: tarjeta con fondo, bordes y sombras propias. Consistente en cualquier tema.
- Como el tema
- Mínimo adorno: dominan la tipografía y los colores de tu tema. Para temas con personalidad fuerte.
- Sin estilo
- Markup limpio, sin decoración, para que tu desarrollador escriba su propio CSS (editor de temas → CSS personalizado). Los ganchos son la clase
.combora-wy las variables--combora-*. - Personalizado
- Abre los controles de abajo: disposición, estilo global y ajuste fino por elemento.
13.3 Disposición: reordenar y ocultar
Con el preset Personalizado aparece Disposición: una lista de los elementos del widget que puedes arrastrar (o mover con las flechas) para cambiar su orden, y un icono de ojo para ocultar los que sean opcionales.
Los elementos dependen del tipo de pack, porque cada tipo dibuja un widget distinto:
| Tipo de pack | Elementos que puedes reordenar |
|---|---|
| Pack fijo · Combo | Título · Productos incluidos · Precio · Ahorro · Botón |
| Combina y ahorra · Arma tu caja | Título · Contador de progreso · Lista de opciones · Nota · Botón |
| Descuento por volumen | Título · Escalera de tramos |
| Compra X, llévate Y | Título · Regla de la oferta |
| Regalo por compra | Título · Regalo · Condición de desbloqueo |
| Complementos | Título · Lista de artículos · Ahorro · Botón |
13.4 Estilo global y ajuste fino
Estilo global es lo que cambia de una vez todo el widget: color de acento, fondo de la tarjeta, color del texto, esquinas (rectas / suaves / redondas), sombra (ninguna / suave / media) y densidad.
Ajuste fino por elemento abre cada elemento por separado — título, precio, ahorro, insignia, botón, tarjeta, miniaturas, etiquetas — con lo que tenga sentido en cada uno: tamaño, grosor, color, mayúsculas, relleno, forma, color del borde, color del precio tachado… Cada control tiene un "Volver al tema" para deshacer solo ese ajuste, y abajo hay un "Restablecer toda la personalización".
- Si no defines el Ahorro, sigue el estilo de la Insignia.
- El color del texto del botón no se puede elegir: se deriva automáticamente por contraste sobre el fondo que elijas, para que nunca quede ilegible.
- Los valores están acotados a rangos sensatos: no puedes escribir un tamaño que rompa el widget en el móvil.
13.5 La vista previa (y qué NO es)
A la derecha hay un panel marcado "Solo vista previa". Es importante entender la diferencia:
- Izquierda = tu diseño. Lo que ajustas ahí se guarda y sale a la tienda.
- Derecha = la lente. Fondo del preview (claro / oscuro / un color a medida), tamaño del texto base, ancho del hueco (columna estrecha de producto vs. sección ancha) y una aproximación de tu tipografía. Sirve para comprobar que tu diseño aguanta en distintos sitios. No cambia nada de tu tienda ni de tu diseño.
Y en el rail del editor del pack, la tarjeta "Estilo de la vista previa" te dice qué diseño está activo ("Diseño activo: Combora") y trae dos botones: Ver vista previa, que abre el widget a tamaño real en un modal ("Así se verá en tu tienda"), y Personalizar diseño, que entra al estudio de este pack. La tipografía y el fondo reales los pone tu tema, así que para el visto bueno final mira el widget en el editor de temas.
14Combinar packs entre sí
Puedes publicar tantos packs como tu plan permita, incluso sobre los mismos productos. Las reglas de convivencia son fijas y predecibles:
- La mejor oferta por línea. Para cada artículo del carrito, Shopify aplica la oferta que más le descuenta a ese artículo. Nunca se suman dos packs sobre la misma línea.
- Packs distintos pueden convivir en el mismo carrito — cada uno sobre sus líneas. Un descuento mix en las tablas y un regalo por gasto pueden aplicarse a la vez porque actúan sobre líneas distintas.
- En empate, gana el pack más antiguo (el primero que creaste).
- La excepción es el combo: sus subofertas sí se suman entre ellas (sección 12).
¿Y los descuentos que no son de Combora? La regla anterior gobierna los packs de Combora entre sí. Con descuentos ajenos manda Shopify, y lo hemos verificado en tienda: dos descuentos de producto (un pack de Combora y un descuento automático o código de producto tuyo) nunca se suman sobre el mismo artículo — Shopify aplica solo el mayor de los dos, aunque ambos estén marcados como combinables; pueden convivir en líneas distintas del mismo pedido. Un descuento de pedido (por ejemplo un código de −10% sobre todo el pedido) sí se resta después, sobre los precios ya rebajados — el comportamiento estándar de Shopify con cualquier app.
Ejemplo numérico real (verificado en la tienda)
| Carrito | Ofertas candidatas | Resultado |
|---|---|---|
| 3 × Cascade Freeride ($300.00) | BOGO 2+1 gratis | $900.00 → $600.00 (una unidad gratis) |
| 4 × Oxygen ($1,000.00) | Volumen 4+ → 20% | $4,000.00 → $3,200.00 |
| 2 × Oxygen | Volumen 2+ → 10% (no se alcanza el tramo 4+) | $2,000.00 → $1,800.00 |
| 3 tablas elegibles | Mix & match, mínimo 3 → 20% | $1,050.00 → $840.00 ($400.00 → $320.00, y así) |
| 3 × la tabla a la que va atado un regalo ($1,050.00) | Regalo por encima de $1,000 de esa tabla | La cera de $20.00 entra a $0.00: $1,070.00 → $1,050.00 |
| 2 × la tabla del combo | Dentro de un combo: volumen 15% y regalo | Aplican las dos: $1,040.00 → $850.00 |
En la tienda demo hay un producto que pertenece a dos packs a propósito: la tabla que es componente del pack fijo es también el sujeto del de volumen. Por su cuenta se lleva el tramo de volumen que le dé su cantidad; junto al otro componente del pack fijo, en las cantidades exactas, el pack fijo entra también como candidato y la línea se queda con la mejor de las dos. Mismo producto, dos packs, un precio por línea — nunca los dos.
15Creación masiva
Desde la galería de Crear pack hay dos flujos para crear muchos packs de golpe. Ambos crean borradores: nada sale a la tienda hasta que revisas y publicas.
15.1 Generar desde una colección
- Elige la colección.
- Elige la plantilla: "Un multipack por cada producto" (un pack fijo de N unidades por cada producto) o "Un solo pack para toda la colección".
- Configura unidades y descuento, y pulsa Crear borradores.
Qué crea exactamente cada plantilla
Un multipack por cada producto recorre la colección y crea un pack fijo en borrador por producto: N unidades de la primera variante de ese producto (por orden de posición), con el descuento que elegiste aplicado a la suma. Cada borrador es un pack fijo normal — ábrelo para cambiar la variante, pasar a un precio de pack cerrado, añadir una insignia… — y al publicarlo se convierte en su propio producto comprable de 1 clic, como cualquier pack fijo (sección 5).
Un solo pack para toda la colección crea exactamente un borrador del tipo flexible que elijas (descuento por volumen, combina y ahorra, arma tu caja o compra X, llévate Y) cuyo pool elegible es la propia colección. La pertenencia sigue a tu catálogo: el pool se resuelve al publicar y se refresca cada noche (o al momento, al republicar), así que los productos que añadas más tarde a la colección entran en la oferta sin tocar el pack.
Un producto se salta — y la banda de resultado te lo dice — cuando no está Activo en tu catálogo, cuando no tiene ninguna variante comprable, y cuando es a su vez un producto de pack de Combora: un pack generado nunca anida otro pack.
Ejemplos resueltos
La misma pantalla, siete configuraciones, y exactamente qué produce cada una:
| Configuración | Qué se crea |
|---|---|
| Colección de 12 productos · multipack · 3 unidades · 15% | 12 borradores, uno por producto, llamados "Producto — pack de 3". Cada uno contiene 3× la primera variante del producto y cobra (3 × precio) − 15% en el checkout una vez publicado. |
| Igual, pero descuento = importe fijo 5 | 12 borradores donde cada pack cobra (3 × precio) − 5 en la moneda de tu tienda. Si un producto es tan barato que el descuento se come el precio, revisa ese borrador antes de publicar. |
| Colección de 9 donde un producto es un pack de Combora y otro no está Activo | 7 borradores; la banda informa de los saltados y del motivo de cada uno. |
| Repetir exactamente la misma configuración al mes siguiente | Solo los productos nuevos en la colección reciben borrador; cada producto que ya tiene un pack generado idéntico se informa como duplicado y se salta. Repetir la generación es siempre seguro. |
| Colección de 250 productos · multipack | Los primeros 100 borradores (el tope por ejecución) más un aviso; publica o elimina algunos y vuelve a ejecutarlo para el resto. |
| Plantilla de pack único · volumen · cantidad mínima 3 · 15% | Un borrador "Descuento por volumen de {colección}": 3 o más unidades de la misma variante llevan un 15% de descuento — cada producto de la colección escala por su cuenta (el volumen cuenta por línea, sección 7). Para premiar mezclar productos distintos, usa combina y ahorra: su mínimo cuenta sobre toda la selección. |
| Plantilla de pack único · compra X, llévate Y · compra 2, llévate 1 · recompensa 100% | Un borrador: por cada 2 unidades compradas de la colección, la siguiente unidad sale gratis. Con una recompensa del 50% saldría a mitad de precio. |
15.2 Importar desde un CSV
Para catálogos grandes o para migrar de otra app. La página incluye la referencia completa del formato, una plantilla descargable con un ejemplo por tipo y un botón de exportación (baja todos tus packs en el mismo formato, listo para reimportar en otra tienda).
type, title, discount_kind, discount_value, components, collection, min_qty, min_items, slots, buy_qty, get_qty.
Se puede subir un archivo o pegar el CSV directamente.- Tipos importables:
fixed,volume,mix_and_match,build_a_box,bogo(los tipos con regalo/ancla/subofertas se crean en el editor). - Referencias por handle de producto/colección o por GID de Shopify.
- En
components(solo fixed):handle:cantidadseparados por|. - Hasta 200 filas por importación; un archivo mayor se recorta y lo avisa.
16Gestión diaria
16.1 La lista
Búsqueda por nombre, filtro por estado y, en cada fila: Duplicar (crea una copia en borrador), Publicar / Pasar a borrador y Eliminar. La fecha de cada fila es la última actualización (tooltip al pasar el cursor).
16.2 Acciones masivas
16.3 Ciclo de vida de un pack
- Borrador
- Invisible para la tienda. Se puede editar sin límite.
- Publicado
- Oferta activa (dentro de su ventana de programación). Editar no cambia nada en vivo hasta pulsar Actualizar pack.
- Pasar a borrador
- Retira la oferta al momento; la configuración se conserva íntegra para republicar.
- Eliminar
- Borra el pack y retira su descuento (y el producto padre, si era un pack fijo). No se puede deshacer. La analítica de pedidos pasados se conserva.
16.4 Lo que Combora hace solo, mientras duermes
Cuatro procesos automáticos mantienen tu tienda al día sin que hagas nada. No tienes que configurarlos ni vigilarlos — están aquí para que sepas por qué las cosas "se arreglan solas":
| Proceso | Cuándo | Qué hace por ti |
|---|---|---|
| Ventanas de programación | cada 15 min | Activa y desactiva los packs programados a su hora (en tu zona horaria) y mantiene el catálogo público al día. Un pack "del 1 al 15" empieza y termina solo. |
| Refresco del plan | 03:00 | Confirma con Shopify tu plan real (upgrade, cancelación, fin de prueba) para que límites e insignia siempre reflejen la verdad. |
| Pools por colección | 04:00 | Actualiza la lista visible de los packs dirigidos a una colección con los productos que entraron o salieron (el precio de esos productos ya era correcto desde el primer momento — sección 4.3). |
| Limpieza y autocuración | 04:30 | Borra datos caducados (chats cerrados a los 90 días, registros técnicos), retira restos de packs eliminados, y repara el contrato público: si alguien alteró por accidente los esquemas de datos que usan los desarrolladores o la insignia del plan, los restaura y deja constancia. |
17Analítica
| Métrica | Qué mide exactamente |
|---|---|
| Ingresos atribuidos | Los ingresos de las líneas de pedido que llevaron descuento de Combora (no el total del pedido). |
| % de pedidos con pack | Porcentaje de los pedidos del rango que incluyeron al menos un pack. |
| Pedidos con pack | La fracción literal: pedidos con pack / pedidos totales. |
| Ahorro entregado | El descuento total que tus packs dieron a los clientes. |
| Valor medio del pedido | Sobre todos los pedidos del rango. |
| Valor del pedido con pack | El promedio solo de los pedidos que llevaron pack — compáralo con el anterior para ver el efecto de tus ofertas. |
| Pedidos con regalo | Pedidos que incluyeron un regalo gratis (GWP o combo). |
Si vendes en varias monedas, un selector de moneda acompaña a las métricas: las cifras de dinero se muestran en la moneda elegida (los contadores de pedidos son globales).
Debajo de las métricas hay tres gráficas del rango elegido, todas con una marca por día y tooltip:
- "Pedidos con pack en el tiempo" — barras, con el valor impreso sobre las barras con datos.
- "Ingresos atribuidos por día" — línea, para ver la tendencia.
- "Ahorro entregado por día" — barras: cuánto descuento dieron tus packs cada día.
18Ajustes y planes
18.1 Ajustes
- Idioma de la app: 7 idiomas (inglés, español, francés, alemán, italiano, portugués, neerlandés). Afecta al admin; lo que ve tu cliente sigue el idioma de tu tema/mercado.
- Diseño de widgets: Editar plantilla de widgets abre el estudio de diseño de toda la tienda — el estilo que heredan todos tus packs (sección 13). Guardar aquí re-sincroniza los packs publicados.
- Sincronizar descuentos: no necesitas pulsarlo — todo se sincroniza solo al publicar. Está ahí como red de seguridad: si algún día un pack dejara de descontarse, esto regenera el descuento de Shopify a partir de todos tus packs publicados. Es seguro usarlo las veces que quieras, y si no había nada que arreglar lo dice: "Todo estaba ya al día."
- Acceso para desarrolladores: los datos públicos que tu tema puede leer (anexo 22). La documentación del contrato está abierta para todos los planes.
18.2 Planes
Precios planos: nunca cobramos un porcentaje de tus ventas, y el precio no depende de tu plan de Shopify — una tienda Basic y una Plus pagan lo mismo.
- Gratis ($0/mes): hasta 3 packs publicados a la vez (los borradores no cuentan) con los 8 tipos incluidos. Al intentar publicar el 4º, la app lo bloquea con el aviso correspondiente: pasa otro a borrador o mejora el plan. En el plan gratis, los bloques muestran una insignia discreta "Powered by Combora".
- Pro ($14.99/mes): packs publicados ilimitados y sin insignia.
- Plus ($39.99/mes): todo lo de Pro, más soporte prioritario, importación/exportación CSV masiva (hasta 200 packs por archivo) y soporte directo de integración para tu desarrollador (storefronts headless y temas a medida).
La facturación va por Shopify (Managed Pricing) — se gestiona y cancela desde la propia página de Planes. Los planes de pago incluyen 7 días de prueba gratis, y si cancelas, conservas el plan hasta el final del ciclo ya pagado. Las tiendas fundadoras (las primeras 100 instalaciones) conservan el producto completo gratis para siempre.
19Diagnóstico y soporte
Diagnóstico (la segunda pestaña de Ayuda) es tu primera parada cuando algo no cuadra — y lo que soporte te pedirá si abres un ticket. Combora registra automáticamente, por tienda, todo lo que falla por debajo (en el servidor y en tu tienda online) aunque el cliente nunca lo vea, y este panel lo pone a tu alcance. No guarda ningún dato de tus clientes.
19.1 Chequeos de salud
El estado en vivo de lo que soporte pregunta primero, verificado contra Shopify en cada carga:
| Chequeo | Qué verifica |
|---|---|
| Packs | Errores de sincronización y packs publicados con cambios sin publicar (editaste y no pulsaste "Actualizar pack"). |
| Descuento automático en Shopify | Que el descuento "Combora" existe y está ACTIVO — es el que cobra los precios en el checkout. |
| Índice publicado de la tienda | Que los datos públicos que leen los bloques del tema están al día (packs en vivo vs. esperados). |
| App embed Combora Gift | Que el motor del regalo está activado en tu tema. |
| Descuento aplicado en pedidos recientes | Pedidos de los últimos 7 días con pack: si TODOS llegaran sin descuento, algo falla en el checkout. |
| Canal de errores de la tienda | Que los bloques de tu tienda pueden reportar fallos aquí (fecha del último evento recibido). |
| Tareas en segundo plano | Trabajos nocturnos fallidos. |
19.2 Registro de eventos
Cada entrada es algo que pasó y quedó guardado: un fallo al publicar, un regalo que Shopify rechazó añadir (con el motivo exacto), un descuento que colisionó con otro, un webhook que falló… Filtra por nivel (Info = esperado pero relevante, como el límite del plan; Aviso; Error) y por área (publicación, descuentos, plan y facturación, tienda, sincronización…). Un registro vacío es buena señal: solo se llena cuando algo va mal. Los eventos se conservan 30 días.
19.3 El informe de soporte
Un único documento con todo lo que hace falta para diagnosticar tu tienda de una pasada: los chequeos de salud, tu plan y configuración (sin datos sensibles), el estado de publicación de cada pack y los últimos eventos. Cuando contactes con soporte, pulsa Copiar informe (o Descargar como archivo) y adjúntalo al ticket — con eso, quien te atiende ve exactamente lo que pasó sin pedirte capturas ni accesos.
- El informe no incluye datos de clientes ni claves: solo salud, configuración de packs y eventos técnicos.
- Si el botón de copiar no funciona en tu navegador, el texto queda seleccionado — pulsa Ctrl+C (Cmd+C en Mac) — o usa la descarga.
/apps/combora/log (App Proxy firmado por Shopify). Es un canal interno de soporte con
catálogo cerrado de códigos y límite diario — no es parte del contrato público del
anexo 22.20Limitaciones y reglas importantes
La referencia única de límites, verificados contra el código de la app:
| Límite / regla | Valor | Qué pasa al tocarlo |
|---|---|---|
| Packs publicados (plan Gratis) | 3 | La publicación del 4º se bloquea con aviso. Los borradores no cuentan. |
| Componentes de un pack fijo | 30 | El editor no deja añadir más. |
| Productos de un combo (aplanados) | 50 entradas | El editor muestra el consumo ("Usa X de 50") y bloquea el exceso. |
| Colecciones por selector | 100 | Validación al guardar. |
| Combinación del regalo (GWP) | 2–5 artículos | Validación al guardar. |
| Título como mensaje de descuento | 100 caracteres | Se recorta el texto mostrado en el checkout (el título completo se conserva). |
| Generar desde colección | 100 borradores | Se recorta y lo avisa. |
| Importación CSV | 200 filas | Se recorta y lo avisa para dividir el archivo. |
| Ofertas visibles por bloque | 1–8 (por defecto 3) | Ajustable en cada bloque del tema; prioriza las ofertas que declaran precio/ahorro. |
| Configuración total publicada | ≈19,8 KB (2 bloques de 9,9 KB) | Con muchísimos packs enormes a la vez, los más nuevos quedarían publicados sin precio activo hasta liberar espacio (caso extremo; la app prioriza los packs más antiguos y reparte la configuración en dos bloques automáticamente). |
Reglas de dinero (siempre exactas)
- Los porcentajes truncan hacia abajo el descuento (nunca se redondea a favor de cobrar de más).
- Los importes y precios fijos se reparten entre líneas con resto exacto: la suma de las partes siempre iguala el total.
- Los decimales dependen de la moneda de la tienda (JPY sin decimales, BHD con tres…) — nunca se asume "2 decimales".
- El precio cobrado lo calcula Shopify en el checkout con la configuración publicada. Lo que muestran los bloques del tema es informativo.
Multimoneda (Shopify Markets)
Si vendes en varias monedas, no tienes que configurar nada: tú defines precios, umbrales y descuentos en la moneda de tu tienda, y Combora hace el resto. Un cliente que compra en otra moneda ve los importes de los widgets convertidos a la suya (el umbral del regalo, el precio del pack, el ahorro de cada tramo), y en el checkout el descuento se convierte con el tipo de cambio de Shopify del momento — el mismo que convierte los precios de tus productos. La regla de oro se mantiene: lo que el cliente ve anunciado es exactamente lo que el checkout le cobra, en su moneda.
Otras reglas
- Las suscripciones están bloqueadas en líneas de pack salvo opt-in explícito (apartado 4.5).
- El regalo de un GWP no se anuncia en la ficha del propio producto-regalo (un premio no es un gancho).
- Los packs publicados fuera de su ventana de programación no aplican descuento (se reactivan solos).
21Solución de problemas
- No veo la oferta en la tienda
- ① ¿El pack está Publicado (no borrador) y dentro de su ventana de fechas? ② ¿Añadiste el bloque correcto a la plantilla (tarjeta "Dónde aparece" del editor)? ③ Si editaste un pack publicado, ¿pulsaste Actualizar pack?
- El regalo no se añade solo
- ① ¿Está activado el app embed Combora Gift? ② ¿El carrito cumple la condición contando solo lo que califica (el regalo no cuenta)? ③ ¿El cliente lo quitó a mano en esta sesión? ④ ¿El regalo tiene stock?
- El descuento del carrito no coincide con lo que esperaba
- Recuerda la regla: solo la mejor oferta por línea. Si dos packs compiten por el mismo artículo, gana el que más descuenta (y en empate, el más antiguo). Las sumas solo ocurren dentro de un combo.
- La app avisa: "Tienes otro descuento automático activo"
- Es información, no un error. Significa que tienes tus propios descuentos automáticos de producto en Shopify. Donde un pack de Combora y uno de esos descuentos caigan sobre el mismo producto, Shopify aplica solo el mejor de los dos — apilar dos descuentos de producto en el mismo artículo requiere Shopify Plus. Es una regla de Shopify, no de Combora. Tus packs sí se combinan con tus descuentos de pedido y de envío, y con descuentos de producto que caigan sobre otros productos. El aviso nombra el descuento concreto que solapa, para que sepas cuál mirar.
- Publiqué y dice "límite del plan"
- El plan Gratis permite 3 packs publicados a la vez. Pasa otro a borrador o mejora el plan.
- La barra de progreso del regalo no aparece
- Se muestra en la plantilla del carrito (bloque Combora gift progress) y solo para ofertas cuyo criterio puede evaluarse en el navegador. Con colecciones también funciona, porque la app resuelve sus productos al publicar; la excepción es una colección muy grande (más de ~150 productos), donde la barra no se muestra aunque el regalo sigue funcionando.
- El selector de casillas no aparece en mix / caja
- El selector se pinta con cualquier alcance: con variantes específicas muestra exactamente esas casillas, y con productos o una colección la lista se resuelve al publicar (y se refresca cada noche, o al momento si re-publicas). Si aun así sale vacío, el grupo elegible no tiene productos comprables — míralo en la nota de la vista previa del editor. En cualquier caso el cliente puede añadir productos con normalidad y el descuento entra al calificar.
- Errores al importar CSV
- Cada fila fallida se lista con su motivo. Corrige esas filas y vuelve a ejecutar solo con ellas — las filas buenas ya se crearon.
- Sospecho que un descuento quedó "huérfano"
- Ajustes → Sincronizar descuentos repara el estado. Nunca edites a mano el descuento "Combora" en la sección Descuentos de Shopify.
22Anexo para desarrolladores: el contrato público
Combora publica los datos de tus packs en tu tienda como metaobjetos y metafields con el
namespace combora, con lectura pública desde el storefront. Cualquier desarrollador
puede construir una UI 100% propia leyendo estos datos desde Liquid o la Storefront API — sin llamar a
ninguna API de la app. Este contrato es versionado y solo-aditivo (versión actual:
public.v1): los campos existentes nunca se renombran ni se retipan.
22.1 Qué se crea al instalar
La instalación aprovisiona las definiciones (los "esquemas") — visibles en Configuración → Metafields y metaobjetos y en Contenido → Metaobjetos:
- Metaobjetos:
combora_bundle(el pack),combora_component(cada línea de componente) ycombora_tier(cada nivel de volumen/umbral). Los tres con acceso storefrontPUBLIC_READ, publicables y traducibles. - Metafields de tienda:
combora.indexycombora.manifest(JSON, lectura pública), ycombora.all_pdp_gwps(list.metaobject_reference→combora_bundle): los regalos de tienda entera que optaron por anunciarse en todas las fichas de producto. - Metafield de producto:
combora.bundles(list.metaobject_reference→combora_bundle) — el índice inverso producto → sus packs.
list.metaobject_reference de tienda (como all_pdp_gwps) no
resuelve a metaobjetos en el Liquid de temas (el de producto sí; los JSON de tienda sí).
Para pintar esos regalos en Liquid, lee las entradas del index con
"all_pdp": true y resuelve cada pack por handle:
metaobjects['combora_bundle'][entry.handle]. Por Storefront API GraphQL la referencia
sí resuelve normal.
all_pdp_gwps).22.2 Qué pasa al publicar / actualizar / retirar
| Evento | Efecto en el contrato |
|---|---|
| Publicar un pack | Se crean/actualizan sus metaobjetos (hijos primero, padre después, con handles deterministas), se regeneran combora.index y combora.manifest, se escribe el metafield combora.bundles de cada producto participante y se siembran las traducciones de los campos traducibles (los idiomas habilitados en tu tienda de los 7 que trae la app; nunca pisa una traducción que hayas personalizado en Translate & Adapt). El índice nunca anuncia un pack cuya escritura falló. |
| Actualizar pack | Re-proyección idempotente completa: reescribe la proyección del pack desde la configuración (por eso también sirve como reparación). La lista de referencias del padre se reescribe en el mismo paso — el storefront nunca ve una referencia colgante —, y los metaobjetos hijos que queden atrás los retira el barrido nocturno. |
| Pasar a borrador | El metaobjeto pasa a estado draft (deja de resolverse en storefront), el pack sale del índice y su precio se apaga. La configuración se conserva. |
| Eliminar | Se borran sus metaobjetos, se limpia combora.bundles en sus productos y, si era un pack fijo, se retira el producto padre. |
| Desinstalar la app | Los metaobjetos y metafields combora son propiedad de la tienda y permanecen (tu tema no se rompe; los datos quedan congelados en su último estado). Los metafields privados $app:* los elimina Shopify automáticamente y el descuento "Combora" queda inerte. Al reinstalar, la app reutiliza y reconcilia todo — no se duplica nada. |
22.3 combora_bundle campo a campo
| Campo | Tipo | Traducible | Contenido |
|---|---|---|---|
title | texto | sí | Título en tienda (requerido). |
description | rich text | sí | ⚠️ La definición existe pero la app aún no escribe este campo: hoy llega siempre vacío — renderiza tolerante a blank. |
badge_label | texto | sí | La etiqueta ("Mejor valor"). |
test | booleano | no | Modo prueba. "true" ⇒ los widgets solo pintan este pack en el editor de temas y en temas cuyo rol no sea el publicado. Ausente o "false" ⇒ en vivo. |
style | json | no | Estilo precompilado del widget (estudio de diseño): {"v":1,"source":"app","vars":"--combora-…","mode_class":"combora-w--styled","model":{…}}. Copia vars al atributo style de tu raíz y mode_class como clase. Con "source":"block" (o el campo ausente) mandan los ajustes del bloque en el editor de temas. |
cta_label | texto | sí | Texto del botón (opcional). |
disclaimer | rich text | sí | ⚠️ Igual que description: definido pero aún sin contenido — tolera blank. |
bundle_type | texto (choices) | no | Uno de: fixed · mix_and_match · volume · bogo · gwp · build_a_box · fbt · combo. |
min_items / max_items | entero | no | Mix (mín/máx) y arma-tu-caja (tamaño en min_items). |
threshold | entero | no | Umbral del GWP en unidades menores (centavos), siempre en la moneda de la tienda — ver la regla de multimoneda en 22.9. |
discount_value | json | no | {"kind":"percentage","bps":1500} (basis points: 1500 = 15%) o {"kind":"fixed_amount","amount":500} (unidades menores). |
config | json | no | Escalares por tipo: price (fixed en modo precio), buy_qty/get_qty (bogo), gift_variant/threshold/min_qty/combination/qualify (gwp — la condición completa vive aquí: gasto en unidades menores, unidades mínimas, ambas, o combinación), slots/box_price (caja), anchor_variant (fbt), eligible (descriptor del pool), of (combo). |
components | lista de referencias | — | → combora_component (variant, quantity, role: component/option/anchor/gift/suggestion, position, label…). |
tiers | lista de referencias | — | → combora_tier (min_qty, discount_value, position, tier_label…). |
product | referencia a producto | no | Producto ancla (el padre del fixed, el principal del FBT). |
image | referencia a archivo | no | Media opcional del pack. |
revision / contract_version | entero / texto | no | Revisión publicada y versión del contrato (public.v1). |
combora_bundle en Contenido → Metaobjetos: título,
estado Active, handle determinista combora-bundle-{id}.
discount_value como JSON en basis points, las referencias a
componentes, el producto ancla y contract_version = public.v1.22.4 El descriptor eligible
El pool elegible del pack, con la misma forma en todos los tipos:
{ "mode": "all" | "products" | "collections" | "variants",
"variants": ["gid://shopify/ProductVariant/…"],
"products": ["gid://shopify/Product/…"],
"collections":["gid://shopify/Collection/…"],
"resolved_count": 12, "total_count": 12, "truncated": false }
Solo van las listas no vacías. Las tres claves de resolución son informativas (en pools por
colección dicen cuántos miembros se materializaron y si el snapshot se recortó) — puedes ignorarlas.
Ojo con la convención: el config del metaobject usa snake_case
(gift_variant, min_qty), mientras el objeto gwp del
index usa camelCase (giftVariant, minQty) — son el
mismo dato en dos superficies distintas.
Ojo: los hijos role:"option" de un pool por colección son una foto tomada al
publicar; la pertenencia viva (y el precio) la resuelve siempre la Function en el checkout.
22.5 combora.index y combora.manifest
shop.metafields.combora.index — la tabla de ruteo de packs publicados (existe para que
nunca tengas que iterar metaobjects.combora_bundle.values, que Liquid recorta a 50
en silencio):
{ "schema": 1, "revision_highwater": 128, "generated_at": "…",
"bundles": [
{ "id": "f3062319-9d6e-…", "handle": "combora-bundle-f3062319-9d6e-…", "type": "fixed",
"gid": "gid://shopify/Metaobject/…", "status": "active", "revision": 42 }
] }
El id es un identificador en texto, no un número. Solo se anuncian los packs
publicados y dentro de su ventana de programación, así que el índice va en paralelo con
el precio del checkout. Algunas entradas llevan campos extra: gwp (la oferta de
regalo, solo en packs de tipo regalo), gwps (las ofertas de regalo de un combo, en
orden de suboferta) y test (true si el pack está en modo prueba: el JS
del escaparate lo salta en el tema publicado).
shop.metafields.combora.manifest — el descriptor del contrato que una herramienta lee
una vez: contract_version, schema_version, el contador de packs y los
GIDs de las tres definiciones. Puede llevar powered_by_badge: true, que es lo que
enciende la insignia "Powered by Combora" en los bloques (solo en tiendas del plan Gratis; en
las demás el campo se omite).
22.6 Leerlo desde Liquid
{%- comment -%} En una ficha de producto: los packs de ESTE producto {%- endcomment -%}
{%- for bundle in product.metafields.combora.bundles.value -%}
<h3>{{ bundle.title.value | escape }}</h3>
{%- if bundle.badge_label.value != blank -%}
<span class="badge">{{ bundle.badge_label.value | escape }}</span>
{%- endif -%}
<ul>
{%- for component in bundle.components.value -%}
{%- comment -%} label es opcional: si falta, cae al título de la variante y
después al del producto. OJO: si el producto NO está publicado en el canal
Online Store, su referencia no resuelve en Liquid y TODOS los fallbacks
devuelven blank — guarda el nombre final o pintarás "1× " vacío. {%- endcomment -%}
{%- assign name = component.label.value -%}
{%- if name == blank -%}{%- assign name = component.variant.value.title -%}{%- endif -%}
{%- if name == blank or name == 'Default Title' -%}{%- assign name = component.variant.value.product.title -%}{%- endif -%}
{%- if name != blank -%}
<li>{{ component.quantity.value }}× {{ name | escape }}</li>
{%- endif -%}
{%- endfor -%}
</ul>
{%- endfor -%}
{%- comment -%} O por handle directo, en cualquier plantilla {%- endcomment -%}
{%- assign bundle = metaobjects.combora_bundle['combora-bundle-{id}'] -%}
Ambas rutas son lecturas acotadas (lista propia del producto o handle directo) — jamás el
.values global. Dos gotchas de Liquid que ahorran una tarde: (1) un for
sobre una lista de referencias trunca a 50 en silencio — los packs de Combora nunca llegan
(el mayor cap es 50 entradas totales), pero no iteréis colecciones ajenas confiando en verlo todo;
(2) los campos opcionales (label, badge_label, cta_label)
llegan vacíos a menudo — guarda con != blank como arriba.
22.7 Leerlo desde la Storefront API (localizado)
query BundleByHandle @inContext(language: FR) {
metaobject(handle: { type: "combora_bundle", handle: "combora-bundle-{id}" }) {
title: field(key: "title") { value }
badge_label: field(key: "badge_label") { value }
components: field(key: "components") {
references(first: 25) {
nodes { ... on Metaobject {
label: field(key: "label") { value }
quantity: field(key: "quantity") { value }
} }
}
}
}
}
@inContext devuelve las traducciones sembradas por la app; lo no traducido cae al
idioma base automáticamente.
22.8 Usos posibles
- UI de bundle 100% a medida en el tema, sin los bloques de Combora, leyendo título, badge, componentes y ahorro del metaobjeto.
- Landing de campañas: una página que lista los packs activos desde
combora.indexy pinta cada uno por handle. - Headless / Hydrogen: misma lectura vía Storefront API con localización por mercado.
- Integraciones (feeds, apps de recomendación): el
manifestdeclara la versión del contrato y dónde está todo.
22.9 Reglas para el desarrollador
- El precio es de la Function. Los campos del metaobjeto son display: no sumes
discount_valuede un combo ni recalcules precios en el tema — el checkout manda. - Solo-aditivo: pueden aparecer campos nuevos; los existentes no cambian. Programa lecturas tolerantes a campos desconocidos.
- Combos: agrupa los hijos por
positiondividido entre 1000 (cada suboferta ocupa un tramo de 1000) o porconfig.of[].index— nunca porrole, que puede repetirse. - Estilo: si montas tu propia UI, ignora
styley escribe tu CSS. Si en cambio quieres respetar el diseño que el comerciante eligió en la app, copiastyle.varsal atributostylede tu raíz ystyle.mode_classcomo clase; el estilo "Sin estilo" del estudio existe justo para el caso contrario (markup limpio, CSS tuyo, con.combora-wy las variables--combora-*como ganchos). - Privado ≠ contrato: los metafields
$app:runtime,$app:fnvarsy$app:validationdel descuento son internos de las Functions, sin acceso storefront, y su forma puede cambiar sin aviso. No construyas sobre ellos. - Multimoneda (Shopify Markets): todos los importes del contrato —
config.price,threshold,fixed_amount.amount,box_price— van siempre en la moneda de la tienda, en unidades menores. Si tu tienda vende en varias monedas, convierte al presentar (en Liquid, multiplica porcart.currency.rate; en JS, porShopify.currency.rate) antes de formatear; pintar el número tal cual con la moneda de presentación del comprador enseña un precio equivocado. El descuento real del checkout lo calcula la app y siempre es correcto — esta regla es solo para lo que TU widget muestra. - No escribas en el espacio
combora. Shopify te da permiso de escritura sobre él (es tu tienda), pero la app lo regenera en cada publicación y una revisión nocturna restaura los campos que gobiernan el plan. Cualquier cosa tuya, en tu propio namespace. - Este anexo es la referencia completa del contrato para desarrolladores externos. Si algo no está aquí y lo necesitas, escríbenos por el chat de la app o a soporte y lo documentamos.
23Anexo para desarrolladores: un widget por tipo, en Liquid
El anexo anterior describe qué contiene el contrato; este muestra cómo renderizar cada tipo de pack con él. Todo el código de abajo lee solo el contrato público — ninguna API de la app, ninguno de los bloques propios de Combora —, así que puedes pegarlo en un snippet o en un bloque Liquid personalizado de la plantilla de producto y adaptar el markup con libertad. Tres reglas aplican a todo lo de esta página:
- El precio es de la Function. Todo lo de aquí es display; el importe que se cobra de verdad lo calcula la Shopify Function de Combora en el checkout. Nunca recalcules un total y lo presentes como el precio.
- Los importes son unidades menores en la moneda de la tienda. Multiplica por
cart.currency.rateantes de formatear, o un comprador navegando en otra moneda verá un número equivocado. - Los campos opcionales llegan vacíos a menudo. Guarda con
!= blank— incluido el nombre del componente tras sus fallbacks (ver 22.6).
23.1 El esqueleto en el que encaja cada ejemplo
Una tarjeta por cada pack del producto actual, con título, badge y el ahorro tal como lo exprese el
pack (discount_value en basis points o en unidades menores). Cada tipo pinta después su
propio cuerpo dentro del case:
{%- liquid
assign bundles = product.metafields.combora.bundles.value
assign rate = cart.currency.rate | default: 1
-%}
{%- if bundles != blank -%}
{%- for bundle in bundles -%}
{%- liquid
assign type = bundle.bundle_type.value
assign dv = bundle.discount_value.value
assign cfg = bundle.config.value
-%}
<article class="cx__card">
<h3>{{ bundle.title.value | escape }}</h3>
{%- if bundle.badge_label.value != blank -%}
<span class="cx__badge">{{ bundle.badge_label.value | escape }}</span>
{%- endif -%}
{%- comment -%} El ahorro, tal como lo exprese este pack {%- endcomment -%}
{%- if dv.kind == 'percentage' -%}
<p>Ahorra {{ dv.bps | divided_by: 100 }}%</p>
{%- elsif dv.kind == 'fixed_amount' -%}
<p>Ahorra {{ dv.amount | times: rate | money }}</p>
{%- endif -%}
{%- case type -%}
{%- comment -%} un bloque por tipo — aquí van las secciones 23.2 a 23.7 {%- endcomment -%}
{%- endcase -%}
</article>
{%- endfor -%}
{%- endif -%}
23.2 Pack fijo
Lista los hijos con role == 'component' usando la cadena de fallbacks del nombre, muestra
el precio del pack cuando el pack usa modo precio (config.price, unidades menores), y enlaza
al producto padre comprable:
{%- when 'fixed' -%}
<ul>
{%- for c in bundle.components.value -%}
{%- if c.role.value == 'component' -%}
{%- liquid
assign name = c.label.value
if name == blank
assign name = c.variant.value.title
endif
if name == blank or name == 'Default Title'
assign name = c.variant.value.product.title
endif
-%}
{%- if name != blank -%}
<li>{{ c.quantity.value }}× {{ name | escape }}</li>
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</ul>
{%- if cfg.price -%}
<p class="cx__price">{{ cfg.price | times: rate | money }}</p>
{%- endif -%}
{%- if bundle.product.value != blank -%}
<a href="{{ bundle.product.value.url }}">Comprar este pack</a>
{%- endif -%}
Un pack fijo en modo precio lleva config.price y no discount_value; en modo
descuento es al revés — la línea de ahorro del esqueleto ya cubre el segundo caso.
En un producto de una sola variante, el título de la variante es el comodín de Shopify «Default Title»: la cadena de fallbacks lo salta y usa el título del producto (para eso está la condición extra).
23.3 Descuento por volumen
La escalera vive en tiers (ordenados por position), cada nivel con su propio
min_qty y discount_value:
{%- when 'volume' -%}
<table>
{%- for t in bundle.tiers.value -%}
{%- assign tv = t.discount_value.value -%}
<tr>
<td>Compra {{ t.min_qty.value }}+</td>
<td>
{%- if tv.kind == 'percentage' -%}
{{ tv.bps | divided_by: 100 }}% de descuento
{%- else -%}
{{ tv.amount | times: rate | money }} de descuento
{%- endif -%}
</td>
</tr>
{%- endfor -%}
</table>
23.4 Compra X, llévate Y
La regla son dos escalares en config; un porcentaje del 100% (bps == 10000)
significa que las unidades de recompensa salen gratis:
{%- when 'bogo' -%}
<p>Compra {{ cfg.buy_qty }}, llévate {{ cfg.get_qty }}
{%- if dv.kind == 'percentage' and dv.bps == 10000 %} gratis{% else %} con descuento{% endif -%}.</p>
23.5 Combina y ahorra y arma tu caja
Ambos son ofertas de "llega a una cantidad": el mix lee el min_items del metaobjeto, la
caja lee config.slots (y config.box_price cuando la caja cobra un precio
cerrado). El pool elegible está en config.eligible (ver 22.4):
{%- when 'mix_and_match' -%}
<p>Elige {{ bundle.min_items.value }} o más de la selección.</p>
{%- when 'build_a_box' -%}
<p>Llena una caja de {{ cfg.slots }}.
{%- if cfg.box_price %} Precio de la caja {{ cfg.box_price | times: rate | money }}.{% endif -%}</p>
23.6 Complementos (FBT)
Los componentes llevan roles: el anchor es el producto principal, los hijos
suggestion son los complementos:
{%- when 'fbt' -%}
<ul>
{%- for c in bundle.components.value -%}
{%- if c.role.value == 'suggestion' or c.role.value == 'anchor' -%}
<li>
{{ c.variant.value.product.title | default: c.label.value | escape }}
{%- if c.role.value == 'anchor' %} <em>(este producto)</em>{% endif -%}
</li>
{%- endif -%}
{%- endfor -%}
</ul>
23.7 Combo
Un combo anida subofertas. Agrupa sus hijos por position dividido entre 1000 (cada
suboferta ocupa un tramo de 1000) o recorre config.of[] — nunca agrupes por
role, que se repite entre subofertas:
{%- when 'combo' -%}
<ol>
{%- for sub in cfg.of -%}
<li>{{ sub.type | replace: '_', ' ' }}</li>
{%- endfor -%}
</ol>
23.8 Regalos de tienda entera, en cualquier página
Los regalos anunciados en todas las fichas de producto viven en un metafield de tienda, y el
Liquid de temas no resuelve una lista de metaobjetos a nivel tienda (22.1). Lee en su lugar el JSON del
index y resuelve cada pack por handle:
{%- assign index = shop.metafields.combora.index.value -%}
{%- if index != blank -%}
{%- for entry in index.bundles -%}
{%- if entry.all_pdp and entry.status == 'active' -%}
{%- assign gift = metaobjects['combora_bundle'][entry.handle] -%}
{%- if gift != blank -%}
<aside class="cx__gift">
<strong>{{ gift.title.value | escape }}</strong>
{%- assign gcfg = gift.config.value -%}
{%- if gcfg.threshold -%}
<span>Gasta {{ gcfg.threshold | times: rate | money }} para desbloquearlo.</span>
{%- endif -%}
</aside>
{%- endif -%}
{%- endif -%}
{%- endfor -%}
{%- endif -%}
23.9 El snippet completo
Todo lo anterior ensamblado en un fichero que funciona tal cual — el esqueleto, los seis cuerpos por
tipo, los regalos de tienda entera y un CSS mínimo para que sea legible de fábrica:
descarga combora-custom-bundle.liquid.
Guárdalo como snippets/combora-custom-bundle.liquid en tu tema y renderízalo desde la
plantilla de producto con {% render 'combora-custom-bundle', product: product %}. El GWP no
está en el case a propósito: un regalo se anuncia (23.8 o los bloques propios de la app) y
lo añade la app automáticamente — no hay nada que un widget de ficha de producto tenga que vender.
24Historial de esta edición
Cada flujo de este manual se probó en una tienda real. Aquí queda el rastro de cuándo se verificó y qué cambió después, para que sepas de qué fecha es lo que estás leyendo.
| Fecha | Qué se hizo |
|---|---|
| 15 de agosto de 2026 | Primera edición completa, verificada de punta a punta
sobre la tienda de desarrollo app-bundle-6pofnlbj, con compras de prueba reales
(pasarela Bogus). Se detectaron dos desviaciones (I-01: el pool que calificaba para el regalo
excluía de más; I-02: motivos de error del CSV sin traducir) y las dos quedaron
corregidas, con test de regresión. |
| 21 de agosto de 2026 | Revisión contra el código y contra la app en vivo. Se
añadió la sección 13 (Diseñar el widget); la visibilidad en catálogo
del pack fijo (5.1); las tres gráficas de Analítica;
el aviso de otro descuento automático activo en
Solución de problemas; el regalo de tienda entera en las fichas de
producto (9.3); y en el anexo, los campos test y
style, más powered_by_badge y los campos extra del índice. Se afinó el
copy del modo prueba y se corrigió la numeración del anexo. |
| 21 de agosto de 2026 (capturas) | Tras el shopify app deploy que
llevó el rediseño de widgets a la tienda, se rehicieron las capturas del escaparate sobre la tienda
real: la escalera de tramos del volumen, los separadores "+" de complementos, el
selector de combina y ahorra, la card del combo con sus chips de cantidad, la
barra del regalo (bloqueada y desbloqueada), los carritos de volumen, mix y BOGO, y las tres
del pack fijo (card, producto padre y carrito). Al rehacer esa última se corrigió un error de
fondo: el pie de figura del producto padre decía que su ficha muestra "su precio de pack", y lo que
pinta el tema es la suma de los componentes — el precio de pack lo aplica la Function al
llegar al carrito. |
| 24 de agosto de 2026 | Se rehicieron todas las capturas contra la tienda demo pública de Combora, montada para la ocasión con una promo publicada de cada tipo y nombres presentables, y se adaptó el texto a las cifras que muestran esas capturas. Las capturas de la interfaz existen ya en los 7 idiomas. Cada precio que se cita de aquí en adelante se midió contra un carrito real de esa tienda, no se calculó. El escaparate usa el tema Horizon de Shopify. |
| 10 de septiembre de 2026 | Se repreció a números redondos todo el catálogo de la tienda demo y cada tipo se movió a productos propios, para que cada ejemplo mida una sola oferta y no la arbitración entre varias. Después se volvieron a medir las cifras carrito a carrito; por eso los números difieren de las entradas de arriba: el pack fijo ($1,600.00 → $1,299.00), volumen con 2 y con 4 unidades ($2,000.00 → $1,800.00 y $4,000.00 → $3,200.00), BOGO con 3 ($900.00 → $600.00), mix con 3 ($1,050.00 → $840.00), la caja de 3 ($2,100.00 → $1,749.00), complementos ($800.00 → $600.00), el regalo por encima de $1,000 ($1,070.00 → $1,050.00) y el combo con 2 unidades ($1,040.00 → $850.00). Dos pies de figura describían comportamientos que ya no existen y se corrigieron: un combo no se muestra como card en la ficha de producto (cada suboferta se promociona con su propio bloque, y el combo se ve en el carrito), y la barra del regalo ahora nombra el regalo y lo que cuenta en cuatro estados, con un mensaje propio opcional por estado (sección 9.2). El umbral del regalo se mide sobre precio de lista. |
| 23 de agosto de 2026 | El manual pasó a ser multiidioma: ahora se genera a partir
de una shell común y un fichero de contenido por idioma, con selector de idioma en el panel izquierdo y
alternativas hreflang. El inglés es la versión canónica. Al traducir se detectó y corrigió
una contradicción en Solución de problemas: decía que el selector de casillas
solo aparece con variantes específicas, cuando 6.1 documenta correctamente que
aparece con cualquier alcance. |
Las capturas viven en
app/combora/public/manual/img/ del repositorio: las de la interfaz de la app bajo
img/<idioma>/, un juego por idioma, y las del escaparate y del admin de Shopify en la
raíz, porque esas siguen a tu tema y a tu admin, no al idioma de la app. Se rehacen desde la tienda demo;
en docs/manual/CAPTURAS.md está qué estado exige cada una.