Logo GH

Adaptadores de proveedores

Un adaptador de proveedor es una capa de integración aislada (anti-corruption layer, ACL) que traduce el contrato externo del proveedor (proveedor de juegos, pasarela de pagos, KYC/AML, puntuación de riesgo, notificaciones, etc.) al lenguaje interno del dominio y viceversa. Protege el dominio frente a API inestables, anomalías de red y cambios de esquemas y de políticas de seguridad.

Objetivos clave:

1. Desacoplamiento: ningún payload externo «en bruto» llega al núcleo.

2. Fiabilidad: gestione los fallos (timeouts, reintentos, DLQ, circuit breaker).

3. Consistencia: idempotencia, orden por clave, mensajería transaccional.

4. Operación: métricas, trazas, límites, aislamiento por tenant y residencia de datos.

1) Responsabilidades del adaptador

Contratos: descripción de los esquemas/endpoints externos; mapeo → comandos/eventos internos.
Transporte: REST/gRPC/WebSocket/SQS/Kafka/SFTP; pool de conexiones, backpressure.
Seguridad: mTLS, OAuth2, HMAC, claves/certificados por tenant/región, rotación de secretos.
Fiabilidad: timeouts, reintentos con jitter, circuit breaker, deduplicación.
Idempotencia: `Idempotency-Key`/`request_id`, almacenamiento de respuestas/estados.
Observabilidad: métricas de SLO, logs estructurados, trazas.
Versionado: soporte de varias versiones de esquemas/endpoints.
Operaciones: feature flags, despliegues canary, sandboxes, certificación.

2) Dónde se usan (ejemplos de contextos)

Game/RGS: inicio/cierre de ronda, apuestas/ganancias, tokens de sesión, estados del proveedor.
Payments/PSP: depósitos/retiros, webhooks de estado, contracargos, 3-D Secure.
KYC/AML: verificaciones, controles de sanciones/PEP, monitoreo de transacciones.
Risk/Fraud: puntuación, disparadores, recomendaciones de bloqueo.
Comms: e-mail/SMS/push, límites de envío, plantillas.

Cada tipo tiene su propia máquina de estados de eventos y su SLA; el adaptador debe normalizarlos.

3) Contrato y mapeo (interno ↔ externo)

Principios:
  • Introducimos un Published Language dentro del adaptador y nunca dejamos pasar los campos del proveedor hacia el dominio.
  • Todos los mensajes llevan `tenant_id`, `region`, `provider_id`, `operation_id`, `version_ts`.
  • Admitimos varias versiones de los esquemas externos mediante mapeadores.
yaml mapping:
provider: "AcmeRGS"
version: "v3"
inbound:
SpinResultV3 -> Round. Resulted
BonusWinV3  -> Bonus. Wagered outbound:
StartRound  -> POST /v3/sessions/{id}/start
Stake    -> POST /v3/spins compat:
accepts: ["v2","v3"]
emits:  ["v3"]

4) Idempotencia y orden

Deduplicación de solicitudes: `Idempotency-Key: <operation_id>` en las solicitudes; guardamos `(op_id → estado/respuesta final)` con TTL.
Deduplicación de webhooks: tabla `inbox(provider, event_id)` como clave primaria.
Orden por clave: serializamos las llamadas y el procesamiento por `aggregate_id` (por ejemplo, `round_id` o `psp_tx_id`).
Outbox/Inbox: mensajería transaccional en ambos extremos del flujo.

5) Fiabilidad: timeouts, reintentos, circuit breaker

Timeouts: cortos en el lado del cliente (orientados al p95), separados para connect/read.
Reintentos: solo en errores reintentables (5xx/timeout/429), backoff exponencial + full jitter, límite de intentos y plazo total.
Circuit Breaker: se abre cuando crecen los errores o la latencia; degradación controlada (por ejemplo, desactivar funciones secundarias del RGS o poner la operación en «esperando resultado»).
DLQ: mensajes «envenenados» con metadatos detallados y reprocesamiento seguro.

yaml reliability:
timeout_ms:
connect: 1000 read:  1500 retry:
max_attempts: 6 initial_backoff_ms: 200 max_backoff_ms: 8000 jitter: full retry_on: [TIMEOUT, 5xx, 429]
circuit_breaker:
failure_rate_threshold: 20%   # por ventana slow_call_threshold_ms: 1500 half_open_max_calls: 10

6) Límites de tasa, cuotas, concurrencia

Respete los límites del proveedor (RPS, ráfagas, concurrencia).
Implemente WFQ/DRR por tenant (equidad) para que un cliente «ruidoso» no consuma todo el presupuesto.
Respete las cabeceras `Retry-After`/`X-RateLimit-`.
Colas internas + backpressure en el productor.

7) Seguridad y cumplimiento

Transporte: mTLS, TLS 1.2+, conjuntos de cifrado actualizados, pinning de certificados cuando sea posible.
Autenticación: OAuth2 client-credentials/mTLS, HMAC (hash firmado del cuerpo + timestamp), claves de API.
Minimización de datos personales: solo los campos necesarios; enmascaramiento/redacción en logs y DLQ.
Secretos: KMS/HashiCorp Vault, rotación automática, aislamiento por tenant/región.
Cumplimiento: PCI DSS para los PSP, almacenamiento de tokens en lugar del PAN, GDPR/leyes locales de datos.

8) Multi-tenant y multirregión

Configuración de claves/endpoints por tenant/región.
Residencia de datos: las llamadas se hacen desde la región «de origen»; entre regiones, solo datos agregados.
Aislamiento: pools de conexiones y límites propios por tenant.

yaml tenants:
T1:
region: eu-central provider_keys:
acme_rgs: { client_id: "...", cert_ref: "vault://..." }
psp_foo: { hmac_key_ref: "kms://..." }
endpoints:
acme_rgs: "https://eu. api. acme-rgs. com"
psp_foo: "https://eu. api. psp-foo. com"
T2:
region: sa-east
...

9) Observabilidad: métricas, logs, trazas

Métricas:
  • Éxitos/errores por clase (2xx/4xx/5xx/timeout/429).
  • Latencia p50/p95/p99 por método.
  • Activaciones del límite de tasa, apertura/cierre del breaker, tasa de DLQ, éxito del reprocesamiento.
  • Logs estructurados: `tenant_id`, `provider_id`, `operation_id`, `endpoint`, `status`, `attempt`, `backoff_ms`.
  • Trazas: un `trace_id` único, spans «serialize → send → receive → map → publish», etiquetas `schema_version`, `region`.

10) Versionado y feature flags

Mantenga en paralelo v1/v2 del contrato externo; la migración se hace de forma canary o por tenants.
Toda nueva función del proveedor va detrás de un flag; los cambios se activan sin release.
Acuerdo de evolución: primero cambios aditivos, validación estricta de esquemas (JSON Schema/Proto).

11) Runbooks

1. Avalancha de 429/límites: activar el throttling global, respetar `Retry-After`, redistribuir las ventanas entre tenants.
2. Aumento de timeouts: reducir la concurrencia, aumentar los timeouts con cautela, abrir el breaker, activar la degradación de funciones.
3. Schema mismatch: congelar el reprocesamiento, activar un mapeador compatible, ejecutar backfill/reprocesamiento.
4. Webhooks inestables: pasar al modo pull/reconcile, aplicar la deduplicación del inbox.
5. Incidente del proveedor: cambiar al sandbox/centro de datos de respaldo (si existe), activar las operaciones «diferidas».

12) Pruebas

Pruebas de contrato: productor/consumidor contra fixtures fijados del proveedor.
Pruebas de caos: retrasos, pérdidas, mensajes fuera de orden, duplicados, respuestas parciales, cortes de conexión.
Rendimiento: estrés con picos de ráfagas; medición de p95/p99, comportamiento del breaker.
Idempotencia: repetir el mismo `operation_id` no genera efectos adicionales.
E2E en sandboxes: escenarios happy path/contracargo/disputas/cancelación/recálculo.

13) Opciones de implementación (deployment patterns)

Servicio adaptador independiente: + aislamiento, releases independientes; − un salto de red adicional.
Sidecar/plugin: + llamadas locales; − versiones más difíciles de gestionar.
Biblioteca: + fácil de integrar; − alto acoplamiento y versiones heterogéneas.

Recomendación: un servicio adaptador con una API clara y su propio ciclo de releases.

14) Ejemplo de API del adaptador (pseudocódigo)

http
POST /adapters/psp/authorize
Headers:
X-Tenant: T1
Idempotency-Key: op-uuid
Body:
{ "amount":"10. 00","currency":"EUR","method":"card","card_token":"tok_..." }

→ 202 Accepted
{
"operation_id":"op-uuid",
"status":"PENDING",
"as_of":"2025-10-31T12:00:00Z"
}
Webhook del proveedor → adaptador → núcleo:
  • Webhook con `provider_event_id` → `inbox` (clave primaria `(provider,event_id)`) → mapeo → evento de dominio `PaymentAuthorized`.

15) Errores típicos

Llevar el esquema externo «en bruto» al dominio → acoplamiento rígido y migraciones costosas.
Sin idempotencia ni inbox/outbox → efectos duplicados y estados fantasma.
Reintentos sin jitter ni límites → tormenta de solicitudes y bloqueo por límite de tasa.
Un único pool global sin equidad → un solo tenant «tumba» a todos.
Logs sin redacción de datos personales ni identificadores → imposible investigar incidentes y riesgo de cumplimiento.
Sin canaries ni flags → un release rompe a todos a la vez.
Ignorar `Retry-After` y los calendarios de mantenimiento del proveedor.

16) Checklist antes de producción

  • Mapeo de los esquemas externos → lenguaje interno; versiones y compatibilidad hacia atrás.
  • Idempotencia de solicitudes/webhooks (`operation_id`, `inbox`).
  • Timeouts, reintentos con full jitter, circuit breaker, DLQ y reprocesamiento seguro.
  • Límites de tasa y equidad por tenant; respeto de `Retry-After`.
  • mTLS/OAuth/HMAC, rotación de secretos, minimización de datos personales, auditoría de accesos.
  • Aislamiento regional y residencia de datos; configuración por tenant/región.
  • Métricas p95/p99, errores por clase, tasa de breaker/429/DLQ; trazas.
  • Sandboxes y pruebas de contrato; despliegue canary y feature flags.
  • Runbooks de incidentes y formación del equipo de guardia.
  • Documentación: SLA, límites, esquemas, procesos de evolución.

Conclusión

Los adaptadores de proveedores son el escudo y el traductor entre su dominio y el mundo exterior. Una ACL sólida, con idempotencia, control de errores y observabilidad, hace que las integraciones sean predecibles, reduce el coste de los cambios del proveedor y protege frente a los «fallos en cadena». Diseñe los adaptadores como componentes autónomos y gestionables, y el «mundo exterior» dejará de romper su arquitectura interna.

Contact

Póngase en contacto

Escríbanos ante cualquier duda o necesidad de soporte.¡Siempre estamos listos para ayudarle!

Telegram
@Gamble_GC
Iniciar integración

El Email es obligatorio. Telegram o WhatsApp — opcionales.

Su nombre opcional
Email opcional
Asunto opcional
Mensaje opcional
Telegram opcional
@
Si indica Telegram, también le responderemos allí además del Email.
WhatsApp opcional
Formato: +código de país y número (por ejemplo, +34XXXXXXXXX).

Al hacer clic en el botón, usted acepta el tratamiento de sus datos.