GH GambleHub

Cambio de moneda en la interfaz

1) Principios

1. Primero el significado, luego IU. Separe la moneda de la cuenta (verdad contable) de la divisa de visualización (conveniencia) y la divisa de transacción (conversión real de dinero).
2. Cero ambigüedad. Muestra el código + símbolo en caso de riesgo de confusión ('US $', 'CA $', 'MXN', 'R $'). Para ₴/₸/₼: agregue siempre el código en los detalles.
3. Honestidad de cursos. Visto: fuente del curso, momento de la última actualización, si las comisiones/sprad están incluidas.
4. Estabilidad de entrada. El cambio de moneda no debe «saltar» los valores de entrada sin consentimiento explícito (especialmente en las formas de apuestas/depósitos).
5. Localización de formatos. Separadores, espacios, signo de moneda - según la ubicación del usuario; precisión - por moneda.


2) Modelos de conmutación

Visualización (display-only): todos los cálculos permanecen en la moneda de la cuenta, IU muestra el equivalente en la moneda seleccionada. Utilice para directorio, perfil, análisis.
Híbrido: mostrar en la moneda seleccionada + confirmar la transacción en la moneda de la cuenta (mostramos ambas).
Operativa: el usuario cambia la divisa de la transacción (depósito/retiro/apuesta). Se necesitan cursos explícitos, comisiones, tiempo de fijación.

Regla: el valor predeterminado es display-only, y la conversión «dura» sólo se incluye en los flujos correspondientes (caja registradora, retiro, transferencia de fondos).


3) Controles y colocación

Interruptor de moneda en la tapa/en el panel de perfil (icono «₴/€/$» o código de moneda).
Selector: búsqueda por código/nombre/símbolo; Monedas favoritas/frecuentes - arriba.
Dentro de los formularios (depósito/apuesta): selector compacto a la derecha del campo de suma, junto a la pista «≈ equivalente en XXX».
Patrón móvil: hoja de bottom con lista y entrada para filtrar.

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) Formato y precisión

Unidades menores: almacena las cantidades en unidades mínimas enteras (centavos, centavos, satoshi).

Decimales por moneda:
  • 0: JPY, KRW, CLP
  • 2: USD, EUR, UAH, TRY
  • 3 +: algunas monedas ZAR (2), KWD (3), crypto (4-8)
  • Criptomonedas: muestra hasta 8 caracteres (precisión dinámica, pero con un límite inferior para la legibilidad).
  • Los números de tabla son: 'font-variant-numeric: tabular-nums' para alinear las columnas.
Intl-snippet:
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) Cursos y actualizaciones

Fuente: Registre el proveedor del curso (Price/Bank/FX-API).
Caché: actualice los cursos con una frecuencia razonable (por ejemplo, cada 60-300 segundos) + actualizaciones incrementales bajo demanda.
Tiempo de confirmación: muestra 'Actualizado N min hacia atrás' y tiempo de confirmación al formalizar la operación.
Sprad/Commission: muestra una línea explícita: "Tasa 1 USD = 36.60 UAH (Sprade 1 incluido. 5%)».
Redondeos: bancario o normal: seleccione uno y fije en la política.


6) Texto y explicaciones UX

Equivalente: «≈ 52,10 €» - junto a la cantidad, el color silenciado, se actualiza en tiempo real.
Cláusulas legales: «El curso real y la comisión se fijarán en el paso de confirmación».
Códigos largos: utilice tooltips/línea secundaria: «US $ - dólar estadounidense».
Conversión en la cesta: no cambie el «total» sin explicación; muestre la línea de recuento.


7) Accesibilidad (A11y)

'role =' listbox/option '' en el selector de divisas.
Compatibilidad con teclado: flechas, Enter, Type-ahead por código/nombre.
Lectura para SR: «Moneda de visualización: UAH - Grivna ucraniana».
El color ≠ el único medio de significado (siempre hay código/texto).
RTL: números/códigos en 'dir = «ltr»' dentro de las cadenas árabes.


8) Performance y almacenamiento en caché

Cursos - en memoria + localStorage con TTL (por ejemplo, 5 min).
Actualizaciones de batch: vuelva a calcular los equivalentes en paquetes (requestAnimationFrame, debouns 100-200 ms).
No active el render de lista adicional cuando haya fluctuaciones en el tipo <umbral (por ejemplo, 0,1%).


9) Especificidad de iGaming

La moneda de la cuenta es la información básica (depósitos, balance, historial).
Moneda de la apuesta: normalmente = moneda de la cuenta; si se especifica otro, muestre el bloque doble: «Cargado X XXX en USD (≈ Y YYY en UAH)».
Fijación al calcular: las ganancias se convierten al tipo de cambio en el momento del cálculo, no las apuestas - esto se debe ver en los detalles del cupón/historial.
Depósito/retiro: tasa y comisión PSP/banco - una línea separada; ETA por el método.
Límites del juego responsable: definidos en la moneda de la cuenta; si UI está en otra moneda - muestre ambos valores.
Torneos y premios: la moneda del fondo de premios se fija; cuando se muestra, el equivalente es indicativo, marcado.


10) Antipattern

Cambio de valor «mágico» en el campo de entrada al cambiar de moneda - sin consentimiento explícito.
Uso de un solo carácter «$» sin código de país.
La comisión oculta está al día (no hay línea sobre el sprad).
Agitar local y moneda (formatea por 'en-US' para 'UAH').
Precisión rígida «2 signos» para JPY/KRW o «8 signos» para todas las criptomonedas.
El recuento de transacciones históricas es «retroactivo» al tipo de cambio actual - sin la marca de «recuento».


11) Tokens del sistema de diseño (ejemplo)

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

Interruptor de moneda (Nat, contexto + 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>;
}

Doble visualización (conversión operativa)

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) Métricas

latencia FX: tiempo desde cambiar de moneda hasta actualizar todos los campos (objetivo ≤ 150 ms).
Tasa de corrección: porcentaje de llamadas a un sapport por «cantidades incorrectas» (<0,2%).
Display vs account mismatch: eventos en los que el usuario confunde monedas (reducimos con sugerencias).
CTR consejos del curso: clics en «Más información sobre el curso/comisión».
Abandón de la caja registradora en la conversión: porcentaje de fallos asociados a un cambio «repentino» en la cantidad.


14) Lista de comprobación de QA

Significado y transparencia

  • La moneda de la cuenta y/o la transacción son visibles en todas partes.
  • Para $, se muestra el código de país (US $, CA $, etc.).
  • Hay una línea sobre el curso, la fecha de actualización y el sprad/comisión.

Formato y precisión

  • Decimales por moneda (JPY = 0, KWD = 3, crypto = hasta 8).
  • El número local/moneda corresponde al idioma de IU.
  • Las operaciones históricas no se recalculan «al tipo de cambio actual» sin marcar.

Comportamiento

  • El cambio de moneda no cambia la entrada sin confirmación.
  • El equivalente «≈» se actualiza sin problemas y rápidamente.
  • El selector de monedas de teclado está disponible, funciona Type-ahead.

iGaming-especificidad

  • En el cupón: el cargo/ganancia y su moneda están firmados, se indica el tipo de fijación.
  • En la caja registradora: las comisiones PSP/banco se ven por separado.
  • En los límites: se muestran ambas magnitudes (cuenta y visualización).

RTL/A11y

  • Los códigos/sumas se leen correctamente en RTL ('dir =' ltr '' para números).
  • Los indicadores de contraste y enfoque corresponden a AA.

15) Documentación en el sistema de diseño

Componentes: 'CurrencySwitch', 'Money', 'FxNote', 'DualAmount'.
Política de precisión/redondeo y una sola función de formato.
Las reglas son: «cuando display-only», «cuando hard-nat», «cómo mostrar el sprad».
Referencia de monedas: código, símbolo, descargas, colisiones regionales de caracteres.
Galería Do/Don 't: «$ sin código», entrada automática, comisiones ocultas.


Resumen breve

Cambiar de moneda no es solo un selector de «₴/€/$». Se trata de un modelo claro de dinero (la moneda de la cuenta vs muestra vs operación), un tipo de cambio honesto con la comisión, el formato correcto por el local y el comportamiento cuidadoso de los campos de entrada. Fije las reglas en el sistema de diseño, automatice el formato y el almacenamiento en caché de los cursos, y los usuarios trabajarán con confianza con las cantidades sin dudar de los números y sin perder dinero en los sprades «invisibles».

Contact

Póngase en contacto

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

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.