Saltar a contenido

ADR-004 — Spike: cómo viajan los beneficios en la intención Prisma

Status: accepted (spike de discovery, 2026-09-03). Sin código — solo hechos que alimentan el SPEC.

Contexto

El riesgo R-02 (RISKS.md) dejaba abierto en qué campo de la intención Prisma viajan los beneficios hacia el autorizador DINI. Un spike sobre la documentación del gateway y minutas de integración resolvió la duda con evidencia documental.

Hechos encontrados

Alternativa 1 — dentro de payment_methods_data: una entrada por payment_method_id (990 y 991) con el descuento expresado como monto total ya descontado en installments[].total_amount. No viaja porcentaje. Pierde información y mezcla planes de pago con beneficios. Descartada.

Alternativa 2 — benefits_methods_data (elegida): un elemento por tipo de cuenta, con porcentaje y tope:

"benefits_methods_data": [
  { "establishment_id": "12345678",
    "benefits_card": { "code": "990", "description": "DINI Negocios" },
    "discount": { "percentage": 5.00, "maximum_discount_amount": 250.00 } },
  { "establishment_id": "12345678",
    "benefits_card": { "code": "991", "description": "DINI Gift Card" },
    "discount": { "percentage": 3.00, "maximum_discount_amount": 500.00 } }
]

DINI mapea sus tipos de cuenta a benefits_card.code = payment_method_id. Viajan porcentaje y tope, uno por tipo de cuenta.

Alternativa 3 — respuesta del autorizador benefits_data: objeto que vuelve en la respuesta solo si intervino una tarjeta de beneficios (benefits_card[], original_amount, discounted_amount). Es independiente de BeneficiosCenter — lo produce el autorizador.

Decisión (hechos que congelan el SPEC)

  1. El GatewayQR mapea la respuesta de BeneficiosCenter a benefits_methods_data (Alternativa 2). El mapeo es directo y sin pérdida:
BeneficiosCenter benefits[] Prisma benefits_methods_data[]
paymentMethodId benefits_card.code
description benefits_card.description
percentage discount.percentage
maxDiscountAmount discount.maximum_discount_amount
(config del gateway) establishment_id
  1. maximum_discount_amount aparece siempre en los ejemplos Prisma. Cuando BeneficiosCenter devuelve maxDiscountAmount: null, el gateway debe resolver qué enviar (omitir el campo o enviar el monto del ticket). Queda registrado como R-03 para cerrar con DINI; no cambia nuestro contrato.
  2. La restricción "un solo porcentaje por tipo de cliente" de BeneficiosCenter coincide con la forma de benefits_methods_data: una entrada por benefits_card.code.
  3. benefits_data en la respuesta del autorizador es independiente de BeneficiosCenter y sigue siendo del gateway y el POS.

Extensión Tipre, no estándar Prisma

discountAmount (→ discount.amount) y type (→ discount.type) del contrato de BeneficiosCenter no son campos del estándar Prisma v27: viajan como extensión propuesta por Tipre para evitar que el autorizador recompute y redondee distinto. Ver Contrato con el autorizador para el detalle completo, confirmado contra docs/Beneficios-contrato-autorizador.pdf.

Consecuencias

  • R-02 pasa de "abierto" a "resuelto por evidencia documental"; falta solo la confirmación formal de DINI de que su autorizador acepta benefits_methods_data con códigos 990/991.
  • El contrato de la API (SPEC §4) no cambia.

Verificación

  • Test de contrato en el simulador del gateway: cada benefits[] de BeneficiosCenter se traduce a un elemento benefits_methods_data con los cuatro campos anteriores (AC-28).