Directorios por currency
El catálogo per currency es una variante del catálogo de contenido y price donde los precios mostrados, límites, bonificaciones, apuestas mínimas, jackpots y textos promocionales se adaptan a la moneda del jugador/tenant/región. El objetivo es dar los puntos de precio y reglas correctos sin copipastos de lógica y sin riesgos debido a las conversiones «sobre la marcha».
Efectos clave:- UX: pasos naturales de apuestas y precios «hermosos» (₺9. 99, R$5, €0. 20).
- Ingresos: límites exactos y aumentos sin margen de «comer» debido a los cursos.
- Cumplimiento: cumplimiento con las regulaciones locales (licencias, impuestos, age/geo).
1) Modelo de datos: compartimos «denominación» y «representación»
Precio base (denominación): moneda nacional única 'PLN '/' EUR '/' USD' para cálculos.
Display Price (vista): calculado a partir de la denominación + FX + redondeo + márgenes/descuentos (spread/fees).
Política: reglas de redondeo, pasos de apuesta, límites min/max, jackpots, sumas de bonificación y wager - personalizados por currency.
yaml price_model:
base_currency: "EUR"
items:
game_spin_min:
base: 0. 10 policy: "stake_min"
game_spin_step:
base: 0. 10 policy: "stake_step"
jackpot_seed:
base: 10000 policy: "jackpot_amount"
policies:
stake_min:
per_currency:
EUR: {round: "ceil_to_step", step: 0. 10}
TRY: {round: "ceil_to_step", step: 1. 00}
BRL: {round: "ceil_to_step", step: 0. 50}
stake_step:
per_currency:
EUR: {step: 0. 10}
USD: {step: 0. 10}
CLP: {step: 50}
jackpot_amount:
per_currency:
EUR: {round: "nearest_100"}
MXN: {round: "nearest_1000"}
2) Fuente de cursos (FX) y «frescura»
El servicio FX es un único punto de verdad para las conversiones:- Proveedor de cursos: principal y de respaldo; frecuencia de actualización (por ejemplo, cada minuto para volátiles, cada 15 min para estables).
- Staleness Bounded: SLA "cursos no mayores Δ t' (por ejemplo, p95 ≤ 5 min).
- Spread y comisiones: configuradas por tenant/region/currency.
- Ventanas libres: «congelar» los cursos para el partido/torneo/ventana promocional para que el precio no «salte».
- Auditoría: registro de versiones de FX con 'valid _ from/valid _ to' para reproducir cheques.
json
{
"as_of":"2025-10-31T12:00:00Z",
"base":"EUR",
"rates": { "TRY":34. 10, "BRL":5. 42, "MXN":19. 1, "UAH":43. 6, "USDT":1. 00 },
"spread_bps": { "TRY":120, "BRL":60 },
"fees_pct": { "default":0. 15 }
}
3) Redondeo y puntos de precio «hermosos»
Redondear después de FX y spreads:- Precios/paquetes: '99', '9. 99`, `4. 90 '(puntos psicológicos).
- Apuestas y pasos: «ceil_to_step» al paso de divisas (₺1, CLP $50).
- Bonos: redondear hacia abajo al paso del bono (R $1/ ₺5).
- Orden de operaciones: 'raw = base fx (1 + spread) (1 + fee)' → 'rounded = round_policy (raw)' → 'min/max clamp'.
Un ejemplo anti: el «redondeo bancario» para las apuestas puede dar pasos «feos» - use políticas explícitas.
4) Límites, min/max y jackpots
Min/Max per currency: tienen en cuenta las leyes locales y las restricciones RGS.
Botes: si el proveedor mantiene el bote en su moneda (EUR, por ejemplo), muestre el equivalente localizado (informer) o almacene los pools de divisas.
Pasos de moneda: CLP/JPY sin céntimos - todos los límites son enteros.
sql
CREATE TABLE currency_limits (
tenant_id text,
currency text,
feature text, -- spin_min, spin_max, deposit_min, payout_max, jackpot_min value numeric,
step numeric,
PRIMARY KEY (tenant_id, currency, feature)
);
5) Bonos y vales per currency
Denominación del bono: configurado por currency (no «recuento» de frente).
Wager: almacenar como multiplicador (x30) o como suma en moneda; evite la mezcla.
Cap de ganancia/cash out: también per currency.
Textos de marketing: localización de números y moneda en plantillas sin código duro.
yaml bonus:
welcome_pack:
EUR: {amount: 100, wager_x: 35, cap: 500}
BRL: {amount: 500, wager_x: 40, cap: 2500}
TRY: {amount: 2500, wager_x: 40, cap: 12500}
6) Restricciones de proveedores (RGS/PSP)
RGS: algunos juegos no están disponibles para monedas 'crypto '/locales; parte de los proveedores requieren mínimos fijos (por ejemplo, 0 €. 20).
PSP: los métodos de pago dependen de la moneda (PIX ↔ BRL, PayID ↔ AUD, Papara ↔ TRY); los límites de depósito/retiro también son diferentes.
Regla: el catálogo/escaparate filtra los juegos y métodos de pago por moneda y jurisdicción antes de la exhibición.
7) Contorno arquitectónico
Currency Policy Store (CP): tablas de reglas por currency (pasos, límites, puntos de precio, redondeos).
Servicio FX: curso en caché, versiones y frescura SLA.
Codificador de catálogo: fabrica los Modelos de Lectura por currency (proyecciones).
API de capa de lectura: tira de proyecciones terminadas; sin conversiones on-the-fly en la vía caliente de IU.
Outbox → Proyecciones: cambios en FX/políticas → eventos 'CurrencyPolicyUpdated/FXUpdated' → actualizaciones incrementales de escaparates.
read_catalog_{tenant}_{region}_{currency}
El envío por moneda acelera la refresh y la recolección de métricas.
8) Proyecciones por currency (ejemplo)
sql
CREATE TABLE read_catalog_currency (
tenant_id text,
region text,
currency text,
game_id text,
price_min numeric, -- displayed min-rate price_step numeric,
jackpot numeric,
bonus_badge text,
as_of timestamptz,
PRIMARY KEY (tenant_id, region, currency, game_id)
);
Actualizaciones - 'UPSERT' idempotentes de eventos de directorio + eventos FX/políticas.
9) Formato y localizaciones
Símbolo/código: '₺/TRY', 'R $/BRL', '€', 'USDT' (para cripto - sin peniques o con 2 caracteres, según la política de UX).
Agrupación y separador decimal: dependen de 'locale' (ru_RU, tr_TR, pt_BR).
RTL/Arabe Locals: comprobación separada de la corrección del signo de moneda.
10) Almacenamiento en caché y rendimiento
Las respuestas de catálogo por currency almacenan en caché 30-120 s; El indicador FX 'as _ of' da en la respuesta.
Discapacidad: eventos 'FXUpdated '/' PolicyUpdated '/' GameUpserted' → limpieza de claves de caché de destino.
Paginación con cursores para que el orden de las tarjetas no «salte» en los pequeños apdates del price.
11) Observabilidad y SLO
Métricas:- `catalog_p95_ms` по валютам, `fx_freshness_ms` (p50/p95/p99), `policy_refresh_latency_ms`.
- La proporción de precios «feos» (no se encuentra en el escalón), la proporción de transacciones rechazadas debido a los límites.
- Discrepancia «escaparate vs cálculo» en check out (donde se produce el adeudo real).
- FX es más antiguo que SLA, aumento de errores de redondeo, aumento de fallos PSP en los límites.
- Discrepancia entre el mínimo de RGS y el mínimo de escaparate.
12) Cumplimiento, impuestos y residencia
Per currency ≠ per country: sigue la combinación 'currency + geo + license'.
Reglas fiscales/fee - en la política monetaria y en el cheque.
Residencia: datos y cálculos para las monedas locales - en la región correspondiente.
13) Pruebas
Property-based: invariant «después de convertir y redondear el precio se encuentra en el paso»; «min ≤ value ≤ max».
Golden-cases: conjunto de monedas de referencia/precios para la regresión.
Chaos FX: cursos de «salto», windows freeze, cambio de proveedor FX.
E2E: La liquidación del importe en el escaparate y el importe total adeudado; tolerance ≤ 0. 01 unidades de moneda (o 1 paso).
14) Errores típicos
Volver a calcular sobre la marcha en la API de lectura → UX inestable y p99 alto.
Ignorar los pasos de moneda (CLP/JPY) → «medio centavo» y los fallos RGS/PSP.
Redondear «por hábito» (bankers rounding) en lugar de reglas claras por política.
No registre la versión FX en el cheque → no es posible resolver las disputas.
Las denominaciones de bonificación única a través de FX → números «extraños» para los mercados locales.
Esconder comisiones en FX sin transparencia es un riesgo de reclamaciones y multas.
15) Recetas rápidas
Apuestas en TRY/BRL: paso ₺1/R $0. 50, min-apuesta redondear para arriba al paso, «hermosos» price-points para los paquetes.
Crypto (USDT/USDC): paso $0. 10, redondeo al paso más cercano, ausencia de comisiones en la exhibición (pero visible en el cheque).
Alta volatilidad FX: freeze por match/promo; alertas cuando se desvía> X% del precio base.
Multi-tenant: diferentes sprades/pasos en las marcas; fairness en los cálculos de proyecciones per tenant.
16) Ejemplo de configuración (fuente única de la verdad)
yaml catalog_currency:
base_currency: EUR fx_sla_ms: 300000 # 5 minutes rules:
- currency: "TRY"
stake_step: 1. 00 stake_min: 5. 00 display_round: "ceil_to_step"
psychological_points: [9, 19, 29, 49, 99]
psp_methods: ["Mefete","Papara","Crypto"]
- currency: "BRL"
stake_step: 0. 50 stake_min: 1. 00 display_round: "ceil_to_step"
psychological_points: [4. 90, 9. 90, 19. 90, 49. 90]
psp_methods: ["PIX","Boleto","Cards"]
- currency: "CLP"
stake_step: 50 stake_min: 200 display_round: "ceil_to_step"
psp_methods: ["WebPay","Cards"]
jackpot:
display_policy:
EUR: "nearest_100"
MXN: "nearest_1000"
bonuses:
welcome:
EUR: {amount: 100, wager_x: 35}
BRL: {amount: 500, wager_x: 40}
TRY: {amount: 2500, wager_x: 40}
17) Lista de verificación antes de la venta
- Moneda base única y versión FX en cada cheque/evento.
- Las políticas de redondeo/pasos/límites se establecen por currency y están cubiertas por pruebas.
- Las proyecciones del directorio per currency están listas; la vía caliente no hace conversiones.
- Los botes y bonificaciones se muestran/gotean correctamente por currency.
- Los métodos PSP se filtran por divisas; los límites coinciden con el escaparate.
- SLA frescura FX y alertas personalizadas; freeze windows para eventos volátiles.
- Localización de números y símbolos de moneda; plantillas promocionales sin código duro.
- Auditoría de cambios de políticas/FX; reproducibilidad del cheque.
- Multi-tenant/región: aislamiento de datos, spreads y límites diferentes.
- Incidentals playbooks: Salto de FX, incumplimiento del mínimo RGS, fallo de los límites PSP.
Conclusión
Los catálogos per currency son una disciplina de ingeniería, no «multiplicar por curso». Divide la denominación y la representación, centraliza FX y las políticas de redondeo, materializa las proyecciones por currency y mide la frescura. Entonces, el escaparate será rápido, predecible y honesto, y el negocio estará protegido de pérdidas latentes de margen y sorpresas regulatorias en los mercados locales.