GH GambleHub

Каталоги per currency

Каталог per currency — это вариант каталога контента и прайсинга, где отображаемые цены, лимиты, бонусы, минимальные ставки, джекпоты и тексты промо адаптированы к валюте игрока/тенанта/региона. Цель — дать правильные прайс-поинты и правила без копипаста логики и без рисков из-за конвертаций «на лету».

Ключевые эффекты:
  • UX: естественные шаги ставок и «красивые» цены (₺9.99, R$5, €0.20).
  • Доход: точные лимиты и бусты без «проедания» маржи из-за курсов.
  • Комплаенс: соответствие локальным правилам (лицензии, налоги, age/geo).

1) Модель данных: разделяем «номинал» и «представление»

Base Price (номинал): единая внутренняя валюта `PLN`/`EUR`/`USD` для расчетов.
Display Price (представление): вычисляется из номинала + FX + округление + наценки/скидки (spread/fees).
Policy: правила округления, шаги ставок, мин/макс лимиты, джекпоты, бонусные суммы и wager — настраиваются per 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) Источник курсов (FX) и «свежесть»

FX-сервис — единая точка правды для конвертаций:
  • Поставщик курсов: основной и резервный; частота обновления (например, каждую минуту для волатильных, каждые 15 мин для стабильных).
  • Bounded staleness: SLA «курсы не старше Δt» (например, p95 ≤ 5 мин).
  • Спред и комиссии: конфигурируются per tenant/region/currency.
  • Freeze windows: «заморозить» курсы на матч/турнир/промо-окна, чтобы прайс не «прыгал».
  • Аудит: лог версий FX с `valid_from/valid_to`, чтобы воспроизводить чеки.
Пример выдачи FX:
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) Округление и «красивые» прайс-поинты

Округление делайте после FX и спредов:
  • Цены/пакеты: `99`, `9.99`, `4.90` (психологические точки).
  • Ставки и шаги: «ceil_to_step» к валютному шагу (₺1, CLP$50).
  • Бонусы: округление вниз к шагу ваучера (R$1 / ₺5).
  • Порядок операций: `raw = base fx (1+spread) (1+fee)` → `rounded = round_policy(raw)` → `min/max clamp`.

Анти-пример: «банковское округление» для ставок может дать «некрасивые» шаги — используйте явные политики.

4) Лимиты, мин/макс и джекпоты

Min/Max per currency: учитывают локальные законы и RGS-ограничения.
Джекпоты: если провайдер держит джекпот в своей валюте (например, EUR), показывайте либо локализованный эквивалент (информер), либо храните пер-валютные пулы.
Шаги валюты: CLP/JPY без копеек — все лимиты целочисленные.

Пример таблицы лимитов:
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) Бонусы и ваучеры per currency

Номинал бонуса: конфигурируется per currency (не «пересчет» в лоб).
Wager: храните как множитель (x30) или как сумму в валюте; избегайте смешения.
Кэп выигрыша/кэш-аут: тоже per currency.
Маркетинг-тексты: локализация чисел и валюта в шаблонах без хардкода.

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) Ограничения провайдеров (RGS/PSP)

RGS: некоторые игры недоступны для валют `crypto`/локальных; часть провайдеров требует фиксированные минимумы (например, €0.20).
PSP: методы оплаты зависят от валюты (PIX ↔ BRL, PayID ↔ AUD, Papara ↔ TRY); лимиты депозита/вывода — тоже разные.
Правило: каталог/витрина фильтруют игры и способы оплаты по валюте и юрисдикции до показа.

7) Архитектурный контур

Currency Policy Store (CP): таблицы правил per currency (шаги, лимиты, прайс-поинты, округления).
FX-сервис: кэш курсов, версии и SLA свежести.
Каталог-билдер: производит Read Models per currency (проекции).
API слоя чтения: вытягивает готовые проекции; никаких on-the-fly конвертаций в горячем пути UI.
Outbox → Проекции: изменения FX/политик → события `CurrencyPolicyUpdated/FXUpdated` → инкрементальные апдейты витрин.

Схема разделов проекций:

read_catalog_{tenant}_{region}_{currency}

Партиционирование по валюте ускоряет refresh и сбор метрик.

8) Проекции per currency (пример)

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)
);

Обновления — идемпотентные `UPSERT`ы из событий каталога + событий FX/политик.

9) Форматирование и локали

Символ/код: `₺/TRY`, `R$/BRL`, `€`, `USDT` (для крипто — без копеек или с 2 знаками, согласно UX-политике).
Группировка и десятичный разделитель: зависят от `locale` (ru_RU, tr_TR, pt_BR).
RTL/арабские локали: отдельная проверка на корректность знака валюты.

10) Кэширование и производительность

Каталожные ответы per currency кэшируйте 30–120 с; FX-индикатор `as_of` отдавайте в ответе.
Инвалидация: события `FXUpdated`/`PolicyUpdated`/`GameUpserted` → целевая очистка ключей кэша.
Пагинация курсорами, чтобы порядок карточек не «прыгал» при мелких апдейтах прайса.

11) Наблюдаемость и SLO

Метрики:
  • `catalog_p95_ms` по валютам, `fx_freshness_ms` (p50/p95/p99), `policy_refresh_latency_ms`.
  • Доля «некрасивых» цен (не лежат на шаге), доля отклоненных транзакций из-за лимитов.
  • Расхождение «витрина vs расчет» на чек-ауте (где происходит реальный дебет).
Алерты:
  • FX старше SLA, рост ошибок округления, всплеск отказов PSP по лимитам.
  • Несоответствие RGS-минимума и витринного минимума.

12) Комплаенс, налоги и residency

Per currency ≠ per country: следите за комбинацией `currency + geo + license`.
Налоговые правила/fee — в политике валюты и в чеке.
Residency: данные и расчеты для локальных валют — в соответствующем регионе.

13) Тестирование

Property-based: инвариант «после конвертации и округления цена лежит на шаге»; «min ≤ value ≤ max».
Golden-cases: набор эталонных валют/прайсов для регрессии.
Chaos FX: «прыгающие» курсы, freeze windows, переключение провайдера FX.
E2E: матчимость суммы на витрине и итоговой списанной суммы; толеранс ≤ 0.01 единицы валюты (или 1 шаг).

14) Типичные ошибки

Пересчитывать на лету в API чтения → нестабильный UX и высокий p99.
Игнорировать шаги валют (CLP/JPY) → «полкопейки» и отказы RGS/PSP.
Округлять «по привычке» (bankers rounding) вместо четких правил per policy.
Не фиксировать FX-версию в чеке → невозможно разбирать споры.
Единые бонусные номиналы через FX → «странные» числа для локальных рынков.
Прятать комиссии в FX без прозрачности — риск претензий и штрафов.

15) Быстрые рецепты

Ставки в TRY/BRL: шаг ₺1 / R$0.50, мин-ставка округлять вверх к шагу, «красивые» прайс-поинты для пакетов.
Crypto (USDT/USDC): шаг $0.10, округление к ближайшему шагу, отсутствие комиссий в показе (но видимые в чеке).
High-volatility FX: freeze на матч/промо; алерты при отклонении > X% от базового прайса.
Мульти-тенант: разные спрэды/шаги у брендов; fairness в расчетах проекций per tenant.

16) Пример конфигурации (единый источник правды)

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) Чек-лист перед продом

  • Единая базовая валюта и версия FX в каждом чеке/событии.
  • Политики округления/шагов/лимитов заданы per currency и покрыты тестами.
  • Проекции каталога per currency готовы; горячий путь не делает конвертаций.
  • Джекпоты и бонусы корректно отображаются/капятся per currency.
  • PSP-методы фильтруются по валютам; лимиты совпадают с витриной.
  • SLA свежести FX и алерты настроены; freeze windows для волатильных событий.
  • Локализация чисел и символов валют; шаблоны промо без хардкода.
  • Аудит изменений политик/FX; воспроизводимость чека.
  • Мульти-тенант/регион: изоляция данных, различающиеся спрэды и лимиты.
  • Плейбуки инцидентов: FX-скачок, несоответствие RGS-минимума, сбой PSP-лимитов.

Заключение

Каталоги per currency — это инженерная дисциплина, а не «умножить на курс». Разделите номинал и представление, централизуйте FX и политики округления, материализуйте проекции per currency и измеряйте свежесть. Тогда витрина будет быстрой, предсказуемой и честной, а бизнес — защищен от скрытых потерь маржи и регуляторных сюрпризов на локальных рынках.

Contact

Свяжитесь с нами

Обращайтесь по любым вопросам или за поддержкой.Мы всегда готовы помочь!

Начать интеграцию

Email — обязателен. Telegram или WhatsApp — по желанию.

Ваше имя необязательно
Email необязательно
Тема необязательно
Сообщение необязательно
Telegram необязательно
@
Если укажете Telegram — мы ответим и там, в дополнение к Email.
WhatsApp необязательно
Формат: +код страны и номер (например, +380XXXXXXXXX).

Нажимая кнопку, вы соглашаетесь на обработку данных.