Informe de soporte — 22/09/2026

Sistema Beneficios (DINI/DINO · Tipre) — revisión de 3 situaciones reportadas en .soporte/20260922. El traffic.log (release 20260921) fue clave para diagnosticar el tema 1.

Resumen

#TemaMóduloDiagnósticoEstado
1Beneficio para factura A/B no aplica (SIN_BENEFICIOS · FACTURA_NO_COINCIDE)BeneficiosCenterEl gateway no envía el tipo de factura (no existe en el momento del QR)Corregido + E2E · v1.4.0
2Fechas del emulador con +3h en autorizadorintencionfecha/trxfechaGatewayQREl emulador emitía UTC (Z); al persistir se re-parseaba como localCorregido + E2E
3trx.total sin el descuento aplicadoRouterQREl descuento YA está persistido en txrx.rx (JSON in/out)Observación

Tema 1 — Beneficio para factura A/B no aplica Corregido · release v1.4.0

La transacción se resuelve como SIN_BENEFICIOS y, al abrir el detalle, muestra MOTIVO: FACTURA_NO_COINCIDE.

Causa raíz. En el momento del pago por QR la factura todavía no existe (se define después, en el paso fiscal/POS). Por eso GatewayQR envía el bloque invoice en null de forma fija:

// GatewayQR — BeneficiosCenterClient.java:278-284
// Buyer invoice data is not available on the gateway yet (known limitation)
invoice.put("type", JSONObject.NULL);
invoice.put("taxIdKind", JSONObject.NULL);
invoice.put("taxId", JSONObject.NULL);
invoice.put("extraCustomerTypeId", JSONObject.NULL);

Y BeneficiosCenter descarta el beneficio cuando la factura viene nula y el beneficio está restringido por tipo de factura:

// BeneficiosCenter — BenefitResolver.java:123-126
if (!beneficio.tiposFactura().isEmpty()
        && (request.invoiceType() == null || !beneficio.tiposFactura().contains(request.invoiceType()))) {
    return MotivoDescarte.FACTURA_NO_COINCIDE;   // null SIEMPRE descarta
}

Prueba en el traffic. Dos transacciones consecutivas, misma sucursal y POS, el mismo invoice nulo — la única diferencia es la restricción de factura del beneficio:

requestIdinvoice.typeResultado
1206791nullFACTURA_NO_COINCIDEbenefits: []
1206792null✓ aplicó benefit 1 (DINI_NEGOCIOS, 10%)

La 1206792 solo pudo pasar el filtro con type=null porque se le quitó la restricción de factura al beneficio. Conclusión: cualquier beneficio restringido por tipo de factura nunca aplicará por el canal QR. Lo mismo vale para extraCustomerTypeId (códigos extra).


Solución — filtro de factura neutralizado en el resolver. Se quitó el descarte FACTURA_NO_COINCIDE ([BenefitResolver.java:123](backend/src/main/java/com/tipre/beneficioscenter/resolucion/BenefitResolver.java)). Un beneficio con restricción de factura ya no se descarta nunca. El campo tiposFactura y su tabla quedan dormidos (no se borran): para reactivar el check el día que el gateway pueda enviar la factura, se restaura el bloque. Sin migración de esquema. Release v1.4.0.

Verificación E2E OK — beneficio con restricción factura=[B,C] sembrada, pegándole directo al /resolver:

invoice.typeAntesAhora
"A"FACTURA_NO_COINCIDE✓ aplica
"B"✓ aplica✓ aplica
nullFACTURA_NO_COINCIDE✓ aplica

Y el money-path completo por GatewayQR (factura null) con el beneficio restringido: importe_final 9000, importe_recdesc -1000, pm 999. 44 tests del resolver en verde.

Tema 2 — Fechas del emulador con +3h Corregido · release v20260922

Los campos autorizadorintencionfecha y trxfecha de transacciones originadas por el emulador se guardaban 3 horas adelantadas (ej. 15:26:52 por un evento de las 12:26). Con el autorizador real (Tecso) las fechas salían bien.

Causa raíz. El emulador seteaba la fecha con getDatenow().toString(). getDatenow() devuelve un Instant, y Instant.toString() siempre serializa en UTC con Z (ej. 14:49Z por un evento de las 11:49 en Córdoba). Al persistir, getDatenowFromString() hace substring(0,23)corta la Z — y re-parsea esos dígitos UTC como si fueran hora local → +3h. Tecso nunca falló porque envía wall-clock local.

Fix. El emulador ahora emite wall-clock local (mismo formato que Tecso). No se tocó getDatenow() (lo usa el camino real).

MyCurrentDateTime.java — nuevo método:

public String getDatenowString() {
    return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS")
              .format(Calendar.getInstance().getTime());   // local, sin 'Z'
}

TrxResource.java (líneas ~1263 y ~1391): getDatenow().toString()getDatenowString() en los dos bloques del emulador.


Verificación E2E OK — BeneficiosCenter (:8080) + GatewayQR con el war corregido (:8082, emulador ON), pago QR real por 10.000:

Campo persistido (trx 10145)ValorAntes del fix
trxfecha16:10:51(siempre OK)
autorizadorintencionfecha16:10:52 ✓19:10 (+3)
autorizadortrxfecha16:10:52 ✓19:10 (+3)

Emulador emitió "intention_datetime":"2026-09-22T16:10:52.120" (local, sin Z). Hora real del evento: 16:10. Money-path OK de paso: importe_final 9000, importe_recdesc -1000, pm 999, APROBADA.

Tema 3 — trx.total sin descuento (RouterQR) Observación documentada

El dato del descuento NO se pierde. RouterQR ya persiste el payload JSON in/out de cada llamada a autorizador en la tabla txrx:

txrx.txrequest JSON (varchar 100000) txrx.rxresponse JSON — contiene importe_final e importe_recdesc del body de la DINI claveSe guarda vía txrxRepository.saveAndFlush() (TxRxService.java:46), disparado por AutorizadorService por cada trx.

El único punto "incómodo" es que trx.total muestra el bruto (se llena desde importe, no desde importe_final). Para conciliar y unir las trx, el neto/descuento se obtiene del JSON ya guardado:

SELECT trxid,
       JSON_VALUE(rx,'$.importe_final')   AS importe_final,
       JSON_VALUE(rx,'$.importe_recdesc') AS importe_recdesc
FROM   txrx
WHERE  tipoaut = 'DINI' AND trxid = @trxid;

Conclusión. Es un tema de ergonomía de reporte, no de datos faltantes. Se deja como observación: el dato está disponible en txrx.rx. Si a futuro se quiere el descuento como columna directa en trx (sin parsear JSON), sería agregar importe_final/importe_recdesc a la entidad — no se hizo en esta ronda.

Entregables del día

Config Ambos releases: solo el artefacto (war/jar) — sin claves nuevas ni migración de esquema. Deploy = reemplazar y reiniciar.
Informe generado el 22/09/2026 · Sistema Beneficios · Tipre. Adjuntos de origen: Captura de pantalla 2026-09-22 115447.png, BeneficiosCenter_SinBeneficios_Motivo_FacturaNoCoincide.zip (RouterQR + GatewayQR + BeneficiosCenter logs, con traffic.log).