Guía: Lectura desde GET · ← Aplicación
rule_effects — referencia completa
:::info Campo en la respuesta GET
En GET /points y GET /points/{id}, este bloque viene en **rule_effects** (string JSON). Valida rule_group para bundle (no variantes legacy como rule_grouped en samples antiguos).
:::
Define qué beneficio otorga la campaña (puntos fijos, ratio, porcentaje sobre líneas/total, etc.) y cómo se reparte entre el ticket y las líneas.
Pregunta que responde: «Si la campaña ganó, ¿cuántos puntos/saldo otorga y sobre qué base del carrito o del evento?»
Índice
- Matriz de efectos y distribuciones por
when - Valor monetario de
value(puntos y wallet) - Campos comunes en GET
limits(límite del efecto, no de victoria)- Distribuciones permitidas por tipo de efecto
- Restricciones de distribución por
when - Reglas de acumulación por efecto
percentagedirect_valueratiostrikethroughcombo_priceformula(efecto promocional externo)- Mecánica bundle (
rule_group) - Configuración vs respuesta de ticket
- Activación y caducidad (metadatos GET)
- Errores frecuentes —
rule_effects
Matriz de efectos y distribuciones por when
when | Efectos permitidos | Distribuciones | rule_group / limits |
|---|---|---|---|
after_create_activity (carrito) | percentage, ratio, direct_value, strikethrough, combo_price, formula | Las tres (total, individual_items, individual_items_pro_rata) con restricciones por tipo — ver tabla abajo | Sí en percentage, direct_value, combo_price |
| Slug de trigger | Solo direct_value | Solo total | No (rule_group: false) |
after_create_custom_entity | percentage, ratio, direct_value | Solo total | No |
manual | Solo direct_value | Solo total | No |
Restricciones de distribución por tipo de efecto (solo carrito; en trigger, custom event y manual aplica solo la fila de la matriz):
| Efecto | total | individual_items | individual_items_pro_rata |
|---|---|---|---|
percentage | ✓ | ✓ | ✓ |
direct_value | ✓ | ✓ | ✓ |
ratio | ✓ | ✓ | ✓ |
strikethrough | — | ✓ (única) | — |
combo_price | ✓ | — | ✓ |
formula | — | ✓ (única) | — |
Para trigger, evento personalizado y manual: distribución siempre total, sin bundle (rule_group: false). Los límites de efecto (limits) y la mecánica bundle solo aplican en carrito.
Valor monetario de value (puntos y wallet)
:::warning Lectura obligatoria para integraciones
En campañas de puntos/wallet, el campo value de rule_effects se persiste siempre en valor monetario en base de datos, independientemente de accrual_mode (points o money). No interpretes value como «número de puntos» salvo que hayas convertido desde moneda.
:::
Requisitos asociados a cada campaña:
| Requisito | Para qué sirve |
|---|---|
currency en la campaña | Moneda en la que está expresado el value monetario. |
score_exchange de esa moneda (configuración de Company) | Cuántas unidades monetarias equivalen a 1 punto (tipo de cambio puntos ↔ dinero). Cada moneda suele tener un único score_exchange. |
Conversión a puntos (cuando accrual_mode es points o cuando necesitas mostrar unidades al customer):
puntos_otorgados = value_monetario / score_exchange
Ejemplo: regla «1 punto cada 10 €» con punto que vale 0,01 €:
| Concepto de negocio | Valor en GET / BD (rule_effects.value) |
|---|---|
| 1 punto = 0,01 € | 0.01 (moneda de la campaña, p. ej. EUR) |
| Ratio «cada 10 € → 1 punto» | En ratio, unit: 10 y value: 0.01 (no value: 1 en puntos) |
Si la integración muestra puntos al customer, divide (o aplica la fórmula acordada con la API) usando el score_exchange vigente para currency. Con accrual_mode: money, el saldo en wallet suele alinearse 1:1 con el importe monetario acumulado; aun así, en configuración el value del efecto sigue guardándose en moneda.
En scores[] del ticket, el motor devuelve el otorgamiento ya calculado; al depurar discrepancias, parte siempre del value monetario del GET y del score_exchange, no de un conteo literal de puntos en rule_effects.
Aquí **rule_group** (agrupación bundle en el efecto) sí importa para integraciones — a diferencia de bundle / grouped en rule_conditions, que son internos y se ignoran.
Campos comunes en GET
| Campo | Rol |
|---|---|
key / type | Identifican el efecto; suelen coincidir (percentage, direct_value, …) |
value | Magnitud principal: en puntos/wallet, importe monetario (direct_value, base del ratio) o porcentaje (percentage). Ver valor monetario. No aplica en strikethrough ni en formula |
unit | Solo **ratio**: unidad monetaria de referencia (p. ej. cada 10 €) |
distribution | Cómo se reparte el efecto (ver tabla por tipo más abajo) |
limits | Veces máximas que el efecto puede aplicar en la misma transacción |
rule_group | true = agrupación / bundle (solo percentage, direct_value, combo_price). Requiere cantidades en condiciones + aplicación — ver Mecánica bundle |
formula | Solo efecto **formula**: expresión fija de cálculo |
strikethrough_data | Solo **strikethrough**: mapa clave producto → precio promocional. La clave puede ser **product_id** o **product_code** según use la compañía (debe coincidir con el identificador de línea en el ticket) |
limits (límite del efecto, no de victoria)
limits en rule_effects acota cuántas veces puede aplicarse el efecto en la misma transacción (mismo ticket). No es el tope de victoria de la campaña (once, presupuesto, etc.) ni un límite de unidades en rule_conditions.
| Valor | Interpretación |
|---|---|
0 | Sin límite: el efecto puede aplicarse todas las veces que correspondan según condiciones y aplicación |
> 0 | Como máximo esa cantidad de aplicaciones del efecto en el ticket |
Qué cuenta como «una aplicación» depende de distribution y de rule_group:
| Configuración | Qué cuenta como 1 aplicación | Qué limita limits: N |
|---|---|---|
distribution: individual_items y rule_group null / false | Una unidad (línea interna de cantidad 1; ver expansión abajo) | Máximo de unidades bonificadas en el ticket |
rule_group: true (bundle / 2x1 / combo) | Un grupo armado según quantity en rule_conditions + rule_application | Máximo de grupos que reciben el beneficio (p. ej. cuántos 2x1) |
Una unidad = una línea en el motor (aunque el ticket traiga quantity > 1)
Para el cálculo de efectos, Loyal Guru trata cada unidad como una línea independiente. Si la integración envía una sola línea con quantity: 10, el motor la descompone internamente en 10 líneas de cantidad 1, ejecuta condiciones, rule_application, efectos y limits sobre ese modelo unitario y, al terminar, reagrupa el resultado en las mismas líneas que llegaron en el ticket (mismo número de líneas y cantidades que envió el retailer).
Implicaciones para integraciones:
- Con
distribution: individual_items,limitscuenta unidades (líneas internas de qty 1), no necesariamente filas del JSON delines[].limits: 10con una línea agregada de qty 15 → como mucho 10 unidades con descuento en esa línea (las 5 restantes de esa línea, al precio pleno para ese efecto). - En
POST /activities,effects[]puede mostrar el otorgamiento consolidado por línea original; la lógica interna siguió el modelo unitario. - Condiciones de victoria y aplicación también se evalúan sobre unidades expandidas cuando el motor lo requiere; la expansión es transparente para quien solo lee el GET de campaña, pero importa al interpretar
limitsy al depurar tickets con líneas multi-cantidad.
Ejemplo: % por producto con tope de unidades (sin bundle)
Objetivo: 5 % sobre determinados productos, como máximo en 10 unidades del ticket.
| Campo | Valor | Por qué |
|---|---|---|
type | percentage | Descuento porcentual |
value | 5 | 5 % |
distribution | individual_items | El % se calcula por unidad (línea interna de qty 1) |
rule_group | null o false | Sin agrupación: cada aplicación = una unidad |
limits | 10 | Como mucho 10 unidades reciben el 5 % en esa compra |
rule_application debe acotar los productos (p. ej. product_id o product_categories en las líneas). Si el ticket trae una línea con quantity: 15 del producto elegible, el motor la trata como 15 unidades; con limits: 10 solo 10 llevan el 5 % (en la respuesta suele verse reflejado en esa misma línea agregada). Si hay varias líneas en lines[], el tope de 10 se reparte entre unidades de todas ellas según prioridad/apilamiento.
{
"type": "percentage",
"value": 5,
"distribution": "individual_items",
"rule_group": null,
"limits": 10
}
Ejemplo: 2x1 con tope de grupos (con rule_group)
Objetivo: mecánica 2x1 pero solo dos 2x1 por ticket (dos grupos bonificados).
| Campo | Valor | Por qué |
|---|---|---|
rule_group | true | Cada aplicación = un grupo (par 2+1), no una línea suelta |
limits | 2 | Como mucho 2 grupos con beneficio en la transacción |
Condiciones de victoria (rule_conditions) definen el tamaño del grupo (p. ej. quantity ≥ 2); rule_application cuántas unidades del grupo llevan dto. (p. ej. ≥ 1). Detalle completo: Mecánica bundle (rule_group) — ahí el mismo ticket con 8 unidades y limits: 2 solo bonifica 2 de 4 grupos posibles.
No confundir con límites de victoria (
once,num_per_day, presupuesto, etc.) en la configuración general de la campaña.
Distribuciones permitidas por tipo de efecto
| Efecto | total | individual_items | individual_items_pro_rata |
|---|---|---|---|
percentage | ✓ | ✓ | ✓ |
direct_value | ✓ | ✓ | ✓ |
ratio | ✓ | ✓ | ✓ |
strikethrough | — | ✓ (única) | — |
combo_price | ✓ | — | ✓ |
formula | — | ✓ (única) | — |
Restricciones de distribución por when
when | Distribuciones permitidas |
|---|---|
| Carrito | Según tipo de efecto (tabla anterior) |
| Trigger, evento personalizado, manual | Solo total |
| Distribución | Comportamiento breve |
|---|---|
total | Un solo otorgamiento sobre el conjunto calificado / total de la transacción |
individual_items | El efecto se evalúa por unidad (cada unidad como línea interna de qty 1; ver expansión unitaria) |
individual_items_pro_rata | El beneficio se reparte proporcionalmente entre las líneas calificadas |
Reglas de acumulación por efecto
| Efecto | Modo en carrito |
|---|---|
strikethrough | Siempre Highest Discount |
combo_price | Siempre Highest Discount |
percentage, ratio, direct_value, formula | Stackable o Highest Discount (configurable) |
Detalle: Acumulación.
percentage
:::info Disponibilidad
Solo evento carrito (after_create_activity). En trigger, evento personalizado y manual no está disponible — ver matriz por when.
:::
Otorgamiento porcentual sobre líneas o total calificado (saldo en moneda según el % sobre la base; ver valor monetario).
{
"key": "percentage",
"type": "percentage",
"value": 20,
"limits": 0,
"formula": null,
"rule_group": null,
"distribution": "individual_items"
}
| Campo | Lectura |
|---|---|
value: 20 | 20 % de descuento |
distribution: individual_items | El % se aplica en cada línea que cumpla aplicación |
limits: 0 | Sin tope de unidades bonificadas; con limits: 10, como mucho 10 unidades — ver ejemplo % con tope |
rule_group: null | Sin agrupación (p. ej. % simple en categoría). Con true, activa grupos según quantity en condiciones y aplicación |
Integración: si el otorgamiento no aparece en las líneas esperadas del ticket, revisar **rule_application** además del % — en carrito, la aplicación suele ser obligatoria para % por línea (Detalles operativos §5).
direct_value
:::info Disponibilidad
Carrito: sí. Trigger, evento personalizado, manual: solo este tipo, con distribution: total.
:::
Importe fijo de otorgamiento, expresado en moneda de la campaña en value (ver valor monetario).
{
"key": "direct_value",
"type": "direct_value",
"value": 5,
"limits": 0,
"formula": null,
"rule_group": null,
"distribution": "individual_items"
}
| Campo | Lectura |
|---|---|
value: 5 | 5 € (u otra moneda) de saldo monetario según currency; en modo puntos, convertir a unidades con score_exchange |
distribution: individual_items | 5 € por línea calificada; con total, un único bloque de 5 € sobre el conjunto |
rule_group | Igual que en percentage: true para bundles que reparten un importe fijo en grupo |
Caso frecuente: €5 de dto. en cesta → direct_value, distribution: total, condición total_cart >= X.
ratio
:::info Disponibilidad Carrito y evento personalizado. No en trigger ni manual. :::
Otorgamiento proporcional al gasto: por cada unit (importe en moneda de la campaña) gastado en base calificada, se otorga value en moneda (no en puntos enteros), repartido según distribution.
{
"key": "ratio",
"type": "ratio",
"unit": 10,
"value": 0.01,
"limits": 2,
"formula": null,
"distribution": "individual_items_pro_rata"
}
| Campo | Lectura del ejemplo |
|---|---|
unit: 10, value: 0.01 | Cada 10 € calificados → 0,01 € de saldo (= 1 punto si score_exchange es 0,01) |
distribution: individual_items_pro_rata | Ese beneficio se prorratea entre las líneas que participan |
limits: 2 | Como máximo 2 aplicaciones del ratio en la misma transacción (p. ej. hasta 20 € de base → 2 × 1 de beneficio si la regla lo permite) |
valueyunitenratioestán en moneda. Conaccrual_mode: points, traduce el resultado a puntos conscore_exchangeantes de mostrarlo al customer.
strikethrough
:::info Disponibilidad Solo carrito. Otorga saldo equivalente a la diferencia precio ticket − precio promocional (misma mecánica que descuento tachado, expresada como acumulación). :::
Sustituye el precio de la línea en el ticket por el precio promocional definido en strikethrough_data. El saldo otorgado equivale a la diferencia entre el precio enviado en el ticket y el precio promocional del efecto.
{
"key": "strikethrough",
"type": "strikethrough",
"limits": 0,
"formula": null,
"distribution": "individual_items",
"strikethrough_data": {
"233212": 1,
"343434": 9
}
}
| Campo | Lectura |
|---|---|
strikethrough_data | Mapa { "clave_producto": precio_promocional }. La clave es el **product_id** o el **product_code** que use la compañía en catálogo/ticket — debe ser el mismo tipo de identificador que envía la integración en la línea |
Sin value | La magnitud del dto. sale del cálculo por línea (precio ticket − precio promo) |
distribution | Siempre individual_items (una evaluación por línea / producto) |
limits | Misma semántica (0 = sin tope de aplicaciones del efecto) |
Claves del mapa: en una misma campaña, las entradas suelen ser homogéneas (todas por ID numérico o todas por código). Si la compañía opera por SKU, espera claves tipo "12000041"; si opera por ID interno, claves tipo "233212".
Ejemplo numérico (por product_id): strikethrough_data["233212"]: 1, línea en ticket con ese producto y precio 3 → precio efectivo 1, descuento 2 (3 − 1).
Ejemplo (por product_code): strikethrough_data["CC-33CL-LATA"]: 0.99 — la línea del ticket debe traer el mismo product_code para que matchee.
Integración: si no aplica, comprobar tipo de clave (ID vs código) alineado con el ticket, que la clave exista en el mapa y el precio de línea enviado. Acumulación: siempre Highest Discount.
combo_price
:::info Disponibilidad Solo carrito. Otorga saldo según precio fijo del bundle (mecánica compartida con descuentos combo). :::
Precio fijo del bundle para un grupo de productos que cumplen condiciones / aplicación.
{
"key": "combo_price",
"type": "combo_price",
"value": 10.9,
"limits": 0,
"formula": null,
"rule_group": true,
"distribution": "individual_items_pro_rata"
}
| Campo | Lectura |
|---|---|
value: 10.9 | Precio total del combo (10,9 €) |
rule_group: true | El motor agrupa líneas que cumplen la mecánica bundle antes de fijar el precio combo |
distribution: individual_items_pro_rata | El ahorro del combo se reparte entre líneas del grupo. Alternativa: total (un solo bloque sobre el conjunto) |
limits: 0 | Sin tope de veces que puede aplicar el combo en el ticket |
Restricción: no usar individual_items en combo_price — solo total o individual_items_pro_rata. Acumulación: siempre Highest Discount.
formula (efecto promocional externo)
:::info Disponibilidad
Solo carrito. Saldo por línea según promoPrice (u atributo acordado) enviado por integración externa.
:::
Otorgamiento calculado por línea a partir de un atributo enviado por un sistema externo (precio promo precalculado).
{
"key": "formula",
"type": "formula",
"limits": 0,
"formula": "lines.total - lines.attributes.promoPrice",
"distribution": "individual_items"
}
| Campo | Lectura |
|---|---|
formula | Fija en configuración: lines.total - lines.attributes.promoPrice |
Sin value | El importe sale del cálculo por línea |
distribution | Siempre individual_items |
rule_group | No usa agrupación (formula no admite bundle) |
Flujo de integración: el integrador debe enviar promoPrice (u homólogo acordado) en atributos de línea del ticket. Si falta en una línea, esa línea no recibe dto. por esta campaña. Si el resultado ≤ 0, no aplica descuento en esa línea.
Mecánica bundle (rule_group)
En Owner App, Bundle / grupo (rule_group: true) indica al motor que forme grupos de líneas y aplique el efecto por grupo, no línea a línea de forma independiente.
Dónde aplica
rule_effects.rule_group | Tipos de efecto compatibles |
|---|---|
true | percentage, direct_value, combo_price |
false / null | Cualquier efecto sin agrupación |
| No disponible | ratio, strikethrough, formula |
Los tres bloques que definen el bundle
| Bloque | Pregunta que responde | Qué validar en integración |
|---|---|---|
**rule_conditions** | ¿Cuántas unidades hacen falta para formar un grupo? | Misma cláusula de producto/categoría + subcondición quantity (ej. gte 2 → grupos de 2) |
**rule_application** | ¿Sobre cuántas unidades del grupo cae el efecto? | Misma familia de producto/categoría + subcondición quantity (ej. gte 1 → 1 unidad con beneficio por grupo) |
**rule_effects** | ¿Qué beneficio y cuántas veces? | rule_group: true, value / type, distribution, **limits** |
Los flags bundle y grouped en el JSON de condiciones/aplicación son internos (ignorar valor). Lo operativo son las **quantity** anidadas y **rule_group** en el efecto.
Ejemplo completo: 2x1 del producto 2222 (100 % en 1 de cada 2)
Victoria — armar grupos de 2 unidades (rule_conditions):
{
"conditions": {
"and": [
{
"key": "cart_product_id",
"field": "product_code",
"bundle": 1,
"values": ["2222"],
"grouped": true,
"operator": "in",
"conditions": [
{ "field": "quantity", "value": 2, "operator": "gte" }
],
"array_field": "lines"
}
]
}
}
Aplicación — el dto. va sobre 1 unidad por grupo (rule_application):
{
"conditions": {
"and": [
{
"key": "cart_product_id",
"field": "product_code",
"bundle": 1,
"values": ["2222"],
"grouped": true,
"operator": "in",
"conditions": [
{ "field": "quantity", "value": 1, "operator": "gte" }
],
"array_field": "lines"
}
]
}
}
Efecto — 100 % en esa unidad, con agrupación activa (rule_effects):
{
"key": "percentage",
"type": "percentage",
"value": 100,
"limits": 1,
"formula": null,
"rule_group": true,
"distribution": "individual_items_pro_rata"
}
Interpretación del 2x1
| Paso | Lectura |
|---|---|
Condiciones quantity: 2 | Cada grupo válido = 2 unidades del producto 2222 en el ticket |
Aplicación quantity: 1 | Dentro de cada grupo, el 100 % aplica sobre 1 unidad (la “gratis” o bonificada del 2x1) |
rule_group: true | El motor agrupa antes de calcular; sin esto, el % se interpretaría línea a línea sin mecánica 2x1 |
distribution: individual_items_pro_rata | Reparto del otorgamiento de la unidad bonificada entre líneas del grupo (habitual en 2x1) |
Ticket con 8 unidades 2222 | 8 ÷ 2 = 4 grupos → hasta 4 aplicaciones del efecto (4 unidades bonificadas si no hay tope) |
limits del efecto con bundles
Con rule_group: true, cada aplicación del efecto es un grupo (no una línea suelta). Por eso limits: 2 en un 2x1 significa «como mucho dos 2x1 en el ticket», no «dos unidades en total». Ver también ejemplo 2x1 con tope de grupos.
limits | En el ejemplo 2x1 |
|---|---|
0 | Sin tope: todos los grupos posibles en el ticket reciben beneficio (8 uds. → 4 grupos → 4 bonificaciones) |
1 | Solo 1 grupo recibe el efecto en la transacción (1 producto “gratis”, aunque haya más grupos posibles) |
2 | Máximo 2 grupos (dos 2x1); con 8 uds. en ticket solo se bonifican 2 de los 4 grupos posibles |
**limits** cuenta aplicaciones del efecto por transacción (grupos bonificados conrule_group, o líneas conindividual_itemssin grupo), no unidades totales en el carrito.
Resumen visual
Ticket: 8 × producto 2222
│
rule_conditions (qty ≥ 2) → 4 grupos de 2
│
rule_application (qty ≥ 1) → 1 unidad con dto. por grupo
│
rule_effects (100%, rule_group) + limits
│
limits: 0 → 4 bonificaciones (4 grupos)
limits: 2 → 2 bonificaciones (solo 2 de 4 grupos)
Variantes habituales
| Mecánica | Condiciones (grupo) | Aplicación (beneficio) | Efecto típico |
|---|---|---|---|
| 2x1 mismo producto | quantity gte 2 en producto | quantity gte 1 en mismo producto | percentage: 100 + rule_group: true |
| 3x2 en categoría | quantity gte 3 en categoría | quantity gte 1 en categoría | percentage: 100 + rule_group: true |
| Bundle A + B + C productos por €10 | quantity gte 1 en A + quantity gte 1 en B + quantity gte 1 en C | filtro de líneas del bundle | combo_price + rule_group: true |
| € fijo por grupo | quantity gte N | quantity gte 1 | direct_value + rule_group: true |
Errores frecuentes — bundle
| Síntoma | Causa habitual |
|---|---|
| 2x1 no funciona | rule_group: false o falta subcondición quantity en condiciones o aplicación |
| Bonifica de más | limits: 0 con muchos grupos en ticket; subir limits para capar grupos bonificados |
| Bonifica de menos | limits bajo (ej. 1) con muchas unidades; o condiciones exigen más unidades que las del ticket |
| Producto distinto en aplicación | values / field en aplicación no coinciden con condiciones de victoria |
Confundir flags bundle/grouped | No activan la mecánica solos; hace falta **rule_group: true** y las **quantity** correctas |
Configuración vs respuesta de ticket
| Contexto | Campo | Qué contiene |
|---|---|---|
| Campaña en GET | rule_effects (a menudo string JSON) | Configuración: type, value, distribution, limits, … |
| Ticket / compra evaluada | scores[] (principal) | Puntos/saldo ya calculados por campaña o línea |
| Ticket (descuentos) | effects[] | Descuentos monetarios en la misma actividad |
Campos típicos en scores[] del ticket:
| Campo en ticket | Relación con config |
|---|---|
rule_id / campaign_id | ID de la campaña de puntos |
points / amount | Puntos o saldo otorgados (según contrato API) |
line | Línea del ticket si la distribución es por ítem |
status / fechas | Puede reflejar activación/caducidad según integración |
Ejemplo (ratio en carrito):
{
"scores": [{
"rule_id": 201,
"line": 1,
"points": 150,
"currency": "POINTS"
}]
}
Integración: comparar rule_effects del GET con scores[] en POST /activities (o equivalente). Si scores[] está vacío, revisar when, elegibilidad (rule_conditions, audiencia), rule_application, flag apply_points en la compañía y metadatos de activación/caducidad — no cupón ni TPV.
Activación y caducidad (metadatos GET)
Además de rule_effects, en GET /points suelen venir campos de ciclo de vida del saldo otorgado:
| Campo | Uso |
|---|---|
activation_period_type + activation_delay | Cuándo pasan de pendientes a disponibles |
expiration_period_type + availability_duration | Cuándo caducan |
currency | Moneda de puntos o wallet |
Estos campos explican diferencias entre configuración en GET y saldo visible en app/wallet del customer.
Errores frecuentes — rule_effects
| Confusión | Cómo resolverlo |
|---|---|
limits: 0 «desactiva límites» | Correcto: sin tope de aplicaciones del efecto en la transacción |
Una línea con quantity: 20 y limits: 10 | El motor expande a 20 unidades; solo 10 reciben el efecto; la respuesta puede seguir siendo una línea con el otorgamiento agregado — ver expansión unitaria |
limits vs límites de victoria | rule_effects.limits = repeticiones del efecto; once / num_* = cuántas veces puede ganar la campaña el cliente |
| Bundle / 2x1 | Trío: quantity en rule_conditions (tamaño grupo) + quantity en rule_application (uds. con dto.) + rule_group: true + limits |
strikethrough «no descontó lo esperado» | Clave del mapa (product_id vs product_code) debe coincidir con el identificador de la línea en el ticket; dto. = precio ticket − precio promo |
combo_price con individual_items | Inválido en producto; usar total o individual_items_pro_rata |
formula sin promoPrice en línea | Integración incompleta; dto. 0 en esa línea |
| % o ratio sin aplicación en carrito | Revisar rule_application — suele ser obligatoria para % por línea |
| Mismo % en config y distinto en ticket | Revisar acumulación entre campañas y scores[] |
Volver: Lectura desde GET · Checklist