GH GambleHub

Перемикання валют в інтерфейсі

1) Принципи

1. Спочатку сенс, потім UI. Відокремлюйте валюту аккаунта (бухгалтерська істина) від валюти відображення (зручність) і валюти операції (фактична конвертація грошей).
2. Нульова двозначність. Показуйте код + символ при ризику плутанини ('US $','CA $','MXN','R $'). Для ₴/₸/₼ - завжди додавайте код в деталях.
3. Чесність курсів. Видно: джерело курсу, момент останнього оновлення, чи включені комісії/спред.
4. Стабільність введення. Перемикання валюти не повинно «стрибати» значення введення без явної згоди (особливо у формах ставок/депозитів).
5. Локалізація форматів. Роздільники, прогалини, знак валюти - по локалі користувача; точність - по валюті.


2) Моделі перемикання

Відображення (display-only): всі розрахунки залишаються у валюті облікового запису, UI показує еквівалент в обраній валюті. Використовуйте для каталогу, профілю, аналітики.
Гібрид (soft convert): відображення в обраній валюті + підтвердження операції у валюті облікового запису (показуємо обидві).
Операційна (hard convert): користувач змінює валюту операції (депозит/вивід/ставка). Потрібні явні курси, комісії, час фіксації.

Правило: за замовчуванням - display-only, а «жорстку» конверсію включайте тільки у відповідних потоках (каса, виведення, переказ коштів).


3) Контролі та розміщення

Перемикач валюти в шапці/на панелі профілю (іконка «₴/€/$» або код валюти).
Селектор: пошук за кодом/назвою/символом; обрані/часті валюти - зверху.
Всередині форм (депозит/ставка): компактний селектор праворуч від поля суми, поруч підказка «≈ еквівалент в XXX».
Мобільний патерн: bottom sheet зі списком і введенням для фільтрації.

html
<button aria-haspopup="listbox" aria-expanded="false" class="currency-switch">UAH</button>
<ul role="listbox" class="currency-menu" hidden>
<li role="option" aria-selected="true">UAH — ₴</li>
<li role="option">USD — US$</li>
<li role="option">EUR — €</li>
<li role="option">TRY — ₺</li>
</ul>

4) Форматування і точність

Мінорні одиниці: зберігайте суми в цілих мінімальних одиницях (копійки, центи, сатоші).

Десяткові розряди по валюті:
  • 0: JPY, KRW, CLP
  • 2: USD, EUR, UAH, TRY
  • 3+: деякі валюти ZAR (2), KWD (3), крипто (4-8)
  • Криптовалюти: показуйте до 8 знаків (динамічна точність, але з нижньою межею для читабельності).
  • Табличні цифри: `font-variant-numeric: tabular-nums;'для вирівнювання колонок.
Intl-сніпет:
js const fmt = (amountMinor, currency, locale) => {
const fraction = { JPY:0, KRW:0, KWD:3 }[currency]?? 2;
return new Intl.NumberFormat(locale, { style:'currency', currency, minimumFractionDigits:fraction, maximumFractionDigits:fraction })
.format(amountMinor / 10fraction);
};
fmt(200000, 'UAH', 'uk-UA'); // 2 000,00 ₴

5) Курси та оновлення

Джерело: фіксуйте провайдера курсу (внутрішній прайсинг/банк/FX-API).
Кеш: оновлюйте курси з розумною частотою (наприклад, кожні 60-300 сек) + інкрементальні оновлення на вимогу.
Час фіксації: відображайте «оновлено N хв назад» і час фіксації при оформленні операції.
Спред/комісія: показуйте явний рядок: "Курс 1 USD = 36,60 UAH (включений спред 1. 5%)».
Округлення: банківське або звичайне - виберіть одне і зафіксуйте в політиці.


6) UX тексту і пояснень

Еквівалент: «≈ 52,10 €» - поруч із сумою, приглушеним кольором, оновлюється в реальному часі.
Юридичні застереження: «Фактичний курс і комісія будуть зафіксовані на кроці підтвердження».
Довгі коди: використовуйте tooltips/вторинний рядок: «US $ - долар США».
Конверсія в кошику: не змінюйте «разом» без пояснення; показуйте рядок перерахунку.


7) Доступність (A11y)

'role = «listbox/option»'у селектора валют.
Підтримка клавіатури: стрілки, Enter, Type-ahead за кодом/назвою.
Читання для SR: "Валюта відображення: UAH - українська гривня".
Колір ≠ єдиний носій сенсу (завжди є код/текст).
RTL: числа/коди в'dir = «ltr»'всередині арабських рядків.


8) Перформанс і кешування

Курси - в пам'яті + localStorage з TTL (наприклад, 5 хв).
Батч-оновлення: перераховуйте еквіваленти пачками (requestAnimationFrame, дебаунс 100-200 мс).
Не тригеріть зайвий ререндер списку при коливаннях курсу <порогу (наприклад, 0,1%).


9) Специфіка iGaming

Валюта аккаунта - базова звітність (депозити, баланс, історія).
Валюта ставки: зазвичай = валюті акаунта; якщо задана інша - покажіть подвійний блок: «Списано X XXX в USD (≈ Y YYY в UAH)».
Фіксація при розрахунку: виграші конвертуються за курсом на момент розрахунку, а не ставки - це повинно бути видно в деталях купона/історії.
Депозит/висновок: курс і комісія PSP/банку - окремим рядком; ETA за методом.
Ліміти відповідальної гри: визначаються у валюті акаунта; якщо UI в іншій валюті - показуйте обидва значення.
Турніри та призи: валюта призового фонду фіксується; при відображенні еквівалент - орієнтовний, з позначкою.


10) Антипатерни

«Магічна» зміна значення в полі введення при перемиканні валюти - без явної згоди.
Використання одного символу «$» без коду країни.
Прихована комісія в курсі (немає рядка про спред).
Перемішування локалі і валюти (форматуєте по'en-US'для'UAH').
Жорстка точність «2 знака» для JPY/KRW або «8 знаків» для всіх криптовалют.
Перерахунок історичних транзакцій «заднім числом» за поточним курсом - без позначки «перерахунок».


11) Токени дизайн-системи (приклад)

json
{
"currency": {
"default": "UAH",
"displayList": ["UAH","USD","EUR","TRY","PLN","BRL","MXN"],
"fractions": { "JPY":0, "KRW":0, "KWD":3, "BTC":8 },
"showCodeWithSymbol": ["USD","CAD","AUD","NZD"],
"approxPrefix": "≈ "
},
"format": {
"tabularNums": true,
"grouping": "locale",
"negative": "−"
},
"fx": {
"ttlSec": 300,
"changeThresholdPct": 0.1,
"showSpread": true
}
}

12) Сніппети

Перемикач валюти (React, контекст + Intl)

tsx import { createContext, useContext, useState, useMemo } from 'react';

type Cur = 'UAH'    'USD'    'EUR'    'TRY';
const CurrencyCtx = createContext<{cur:Cur,set:(c:Cur)=>void, rate:(from:Cur,to:Cur)=>number}>({cur:'UAH',set:()=>{},rate:()=>1});

export function CurrencyProvider({children}:{children:React.ReactNode}){
const [cur, set] = useState<Cur>('UAH');
// fx: получить из кэша/апи; здесь — заглушка const table = { UAH:{USD:0.027,EUR:0.025,TRY:0.89,UAH:1}, USD:{UAH:36.6,EUR:0.93,TRY:33.0,USD:1}, EUR:{UAH:39.2,USD:1.07,TRY:35.4,EUR:1}, TRY:{UAH:1.12,USD:0.030,EUR:0.028,TRY:1} };
const rate = (from:Cur,to:Cur)=> table[from][to];
const value = useMemo(()=>({cur, set, rate}),[cur]);
return <CurrencyCtx.Provider value={value}>{children}</CurrencyCtx.Provider>;
}

export function useCurrency(){ return useContext(CurrencyCtx); }

export function Money({minor, iso}:{minor:number, iso:Cur}){
const { cur, rate } = useCurrency();
const fraction = { JPY:0, KRW:0, KWD:3 }[cur as any]?? 2;
const v = (minor/10fraction) rate(iso, cur);
return <span style={{fontVariantNumeric:'tabular-nums'}}>{new Intl.NumberFormat(undefined,{style:'currency',currency:cur, minimumFractionDigits:fraction, maximumFractionDigits:fraction}).format(v)}</span>;
}

Подвійне відображення (операційна конверсія)

html
<div class="amount">
<label>Сумма депозита</label>
<div class="row">
<input type="number" inputmode="decimal" aria-describedby="fxnote">
<select aria-label="Валюта операции">
<option>USD</option><option>EUR</option><option>UAH</option>
</select>
</div>
<small id="fxnote">≈ 2 000,00 ₴ · Курс будет зафиксирован на следующем шаге</small>
</div>

13) Метрики

FX latency: час від перемикання валюти до оновлення всіх полів (мета ≤ 150 мс).
Correctness rate: частка звернень у саппорт за «невірними сумами» (<0,2%).
Display vs account mismatch: події, де користувач плутає валюти (знижуємо підказками).
CTR підказки курсу: кліки по «Детальніше про курс/комісії».
Абандон каси при конверсії: частка відмов, пов'язана з «раптовою» зміною суми.


14) QA-чек-лист

Сенс і прозорість

  • Скрізь видно валюту акаунта та/або операції.
  • Для $ показаний код країни (US $, CA $ і т.п.).
  • Є рядок про курс, дату оновлення і спред/комісію.

Формат і точність

Десяткові розряди по валюті (JPY = 0, KWD = 3, crypto = до 8).

  • Локаль числа/валюти відповідає мові UI.
  • Історичні операції не перераховані «за поточним курсом» без позначки.

Поведінка

  • Перемикання валюти не змінює введення без підтвердження.
  • Еквівалент «≈» оновлюється плавно і швидко.
  • Селектор валют клавіатурно-доступний, працює Type-ahead.

iGaming-специфіка

  • У купоні: списання/виграш та їх валюта підписані, курс фіксації вказаний.
  • У касі: комісії PSP/банку видно окремо.
  • У лімітах: показуються обидві величини (акаунтна і відображувана).

RTL/A11y

  • Коди/суми читаються коректно в RTL ('dir = «ltr»'для чисел).
  • Контраст і фокус-індикатори відповідають AA.

15) Документація в дизайн-системі

Компоненти: `CurrencySwitch`, `Money`, `FxNote`, `DualAmount`.
Політика точності/округлень і єдина функція форматування.
Правила: «коли display-only», «коли hard-convert», «як показувати спред».
Довідник валют: код, символ, розряди, регіональні колізії символів.
Галерея Do/Don't: «$ без коду», автоприжок введення, приховані комісії.


Коротке резюме

Перемикання валют - це не просто селектор «₴/€/$». Це ясна модель грошей (акаунтна валюта vs відображення vs операція), чесний курс з комісією, коректне форматування по локалі і дбайливу поведінку полів введення. Зафіксуйте правила в дизайн-системі, автоматизуйте форматування і кешування курсів - і користувачі будуть впевнено працювати з сумами, не сумніваючись в цифрах і не втрачаючи гроші на «невидимих» спредах.

Contact

Зв’яжіться з нами

Звертайтеся з будь-яких питань або за підтримкою.Ми завжди готові допомогти!

Розпочати інтеграцію

Email — обов’язковий. Telegram або WhatsApp — за бажанням.

Ваше ім’я необов’язково
Email необов’язково
Тема необов’язково
Повідомлення необов’язково
Telegram необов’язково
@
Якщо ви вкажете Telegram — ми відповімо й там, додатково до Email.
WhatsApp необов’язково
Формат: +код країни та номер (наприклад, +380XXXXXXXXX).

Натискаючи кнопку, ви погоджуєтесь на обробку даних.