Каталоги 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', щоб відтворювати чеки.
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 і вимірюйте свіжість. Тоді вітрина буде швидкою, передбачуваною і чесною, а бізнес - захищений від прихованих втрат маржі і регуляторних сюрпризів на локальних ринках.