Saltar a contenido

Configurar el lado GatewayQR

Esta página documenta, del lado del GatewayQR (repositorio separado, com.tipre.gatewayqr), la configuración que lo conecta con BeneficiosCenter. Complementa Configuración, que solo cubre las claves del lado de BeneficiosCenter. Fuente: src/main/resources/config/application-*.yml y BeneficiosCenterClient.java del repositorio del GatewayQR.

Propiedades app.beneficioscenter.*

app:
  beneficioscenter:
    enabled: true
    base-url: http://beneficioscenter:8080
    api-key: CHANGE_ME
    connect-timeout-ms: 300
    read-timeout-ms: 800
    result-connect-timeout-ms: 300
    result-read-timeout-ms: 800
Clave Tipo / default Significado
app.beneficioscenter.enabled boolean, default false Interruptor general. En false, el gateway nunca llama a BeneficiosCenter: seguir cobrando sin beneficios, no un error.
app.beneficioscenter.base-url string Host y puerto donde escucha BeneficiosCenter (por ejemplo http://beneficioscenter:8080).
app.beneficioscenter.api-key string Debe ser exactamente el mismo valor que bc.gateway.api-key del lado de BeneficiosCenter (ver Configuración) — viaja como header X-Api-Key en ambas llamadas. Un valor que no coincide responde 401 en BeneficiosCenter; el cliente lo trata igual que cualquier otra falla (ver Comportamiento fail-safe).
app.beneficioscenter.connect-timeout-ms / .read-timeout-ms int, default 300 / 800 Timeouts de la llamada a /resolver (la ruta caliente, síncrona).
app.beneficioscenter.result-connect-timeout-ms / .result-read-timeout-ms int, default 300 / 800 Timeouts de la llamada a /resultado (fire-and-forget, en un pool aparte).

Los defaults de arriba son los que trae BeneficiosCenterClient si la clave falta del todo; en la práctica cada ambiente (application-dev.yml, application-prod.yml) los declara explícitamente, con su propio base-url y api-key.

Las dos llamadas

Llamada Endpoint (BeneficiosCenter) Cuándo Modo
Resolución POST /api/v1/beneficios/resolver Antes de armar la intención de pago — ver Contrato con el autorizador. Síncrona, bloqueante hasta connect-timeout-ms/read-timeout-ms: el gateway espera la respuesta para saber qué benefits_methods_data adjuntar.
Resultado POST /api/v1/beneficios/resultado Después de que el autorizador ya aprobó o rechazó — ver Pipeline de resultado de pago. Fire-and-forget: se encola en un pool propio (2–4 hilos daemon, cola de 50) y se descarta si el pool está saturado; nunca corre en el hilo que atiende el webhook de pago.

Comportamiento fail-safe: nunca frena un cobro

BeneficiosCenterClient está escrito para que ningún problema de comunicación con BeneficiosCenter afecte un cobro:

  • obtenerBenefits (la llamada a /resolver) atrapa RestClientException y cualquier Exception inesperada, y en ambos casos devuelve una lista vacía — el pago sigue sin beneficios, nunca se corta.
  • notificarResultado (la llamada a /resultado) nunca lanza ni bloquea al llamador: si el enabled es false, no hace nada; si falla el envío, se loguea en WARN y se descarta.
  • Con app.beneficioscenter.enabled: false, ninguna de las dos llamadas ocurre.

Esto es lo mismo que documenta Despliegue del lado de BeneficiosCenter: si BeneficiosCenter está lento o caído, "el gateway sigue operando sin beneficios" — la garantía es simétrica en ambos repositorios.

SEC-01 — el webhook de aprobación de pago es un control aparte

No confundir con app.beneficioscenter.api-key

server.apikey.tecso es una propiedad del GatewayQR, sin relación con BeneficiosCenter: protege el webhook que el autorizador DINI/TECSO llama para avisar que un pago fue aprobado o rechazado (postWebHook/postWebHookAnulacion en TrxResource), no la integración con BeneficiosCenter. Se documenta acá porque es un requisito de despliegue del mismo proceso GatewayQR, y porque una corrida E2E de BeneficiosCenter (ver E2E con GatewayQR) ejercitó este control al mismo tiempo que el pipeline de resultado.

Verificado en TrxResource.java: si server.apikey.tecso no está configurada (ausente o de 3 caracteres o menos) en el ambiente, el webhook responde 401 sin procesar nada — fail-closed, nunca se salteaba la validación por falta de configuración. Con la clave configurada, compara el header APIKEY recibido contra el valor esperado con MessageDigest.isEqual (comparación en tiempo constante). En producción, server.apikey.tecso debe estar siempre configurada.

Dónde sigue