Pago por $200, BeneficiosCenter resuelve $-10, el autorizador cobra $190 — pero el POS no aplica el descuento. En toda la cadena (GWQR, RouterQR, POS) el campo importe_recdesc llega en null, y el POS lee ese campo para imputar el descuento.
importe_final = 190 (el descuento SÍ se cobró) importe_recdesc = null ← el POS necesita este campo y viene vacío
Tecso respetó el contrato. El spec que le pasamos a Tecso (sección 2, "Lo que devuelve el Autorizador") define que el descuento aplicado viaja anidado en benefits_data:
{ "status":"approved", "payment_method_id":990, "amount":190.00,
"benefits_data": {
"benefits_card": {...}, "original_amount":200.00,
"discounted_amount": 10 ← acá, dentro de benefits_data
} }
Pero GatewayQR leía discounted_amount del nivel superior del webhook (donde Tecso NO lo manda). Entonces nunca armaba importe_recdesc ni se lo pasaba al POS, y notificaba a BeneficiosCenter con descuentoAplicado:null. El importe_final (190) sí salía bien porque ese viene del amount top-level.
¿Por qué no se detectó antes? El emulador interno de GatewayQR emitía discounted_amount en el top level (no como Tecso), así que el E2E contra el emulador pasaba y tapaba el bug durante semanas. El doble de prueba no reflejaba el contrato real.
En resumen: no es un problema de Tecso ni de BeneficiosCenter — es que GatewayQR nunca implementó del todo el contrato que nosotros mismos definimos.
AutorizadorRespuesta que lee benefits_data.discounted_amount (Tecso) con fallback al top level. Aplicado en los 4 puntos que lo usaban: webhook de pago, notificación a BeneficiosCenter, webhook de anulación y consulta/poll.benefits_data anidado + status_details como objeto), para que el E2E ejercite el mismo camino que producción y no vuelva a tapar un bug así.traffic.log el hop origen=GatewayQR destino=POS (respuesta al POS), que antes no se logueaba — justo el que hubiera mostrado el importe_recdesc de inmediato (lo pidieron en el ticket).36 tests unitarios en verde (incluye test directo del helper con shape real de Tecso + fallback, y regresión del webhook). Se corrió además un code-review del diff: sin bugs de correctitud; solo se cerraron huecos de cobertura. E2E completo: BeneficiosCenter + GatewayQR con el emulador ya emitiendo el shape de Tecso, pago QR por $200 con beneficio 10%:
| Campo | Antes (reclamo) | Ahora |
|---|---|---|
Respuesta al POS · importe_recdesc | null | -20.00 ✓ |
importe_final | 180.00 | 180.00 |
Notificación a BeneficiosCenter · descuentoAplicado | null | 20 ✓ |
DB GatewayQR · trx.importe_recdesc | null | -20.00 ✓ |
El importe_recdesc (negativo, como espera el POS para imputar el descuento) ahora llega end-to-end.
Nota: la corrección es en el autorizador real (Tecso). El circuito con emulador ya venía "ok" justamente porque el emulador no replicaba el contrato; con esta versión el emulador también lo replica.