GH GambleHub

Multi-currency catalogs

(Section: Operations and Management)

1) Task and scope

A multi-currency catalog is a single source of truth about prices/fees/taxes for different currencies, regions and channels. It provides:
  • correct price mart (UX, trust),
  • reproducibility of calculations (audits, returns),
  • economic predictability (margin/taxes),
  • compliance (taxation, sanctions, currency restrictions).

2) Data model (reference)

Entities:
  • Product/SKU: `{sku_id, title, attributes, region_policies[]}`
  • PriceList: `{pricelist_id, base_currency, effective_from, effective_to, version}`
  • PriceItem: `{sku_id, base_price, base_currency, tax_class, pricing_model, promo_refs[]}`
  • FXRate: `{pair: EUR→USD, rate, source, method, precision, effective_from, version}`
  • TaxRule: `{region, tax_mode: VAT/GST included|excluded, rate(s), threshold, rounding}`
  • DisplayRule: `{region, currency_whitelist[], minor_units, rounding_mode, charm_pricing}`
  • Override: `{sku_id|category|tenant|campaign, currency, price_or_markup, priority}`
  • BasketPolicy: `{bundle_rules, promo_stack_mode, free_shipping_thresholds, rounding_scope}`
  • AuditReceipt: `{hash, signature, pricelist_version, fx_version, computed_totals}`
Key accuracy fields:
  • `minor_units` (ISO 4217; e.g. JPY = 0, USD/EUR = 2, KWD = 3; for crypto - up to 8)
  • 'rounding _ mode ':' HALF _ UP '(retail),' BANKERS '(finance),' FLOOR '/' CEIL '(taxes/regulators)

3) FX sources and policy

Sources: course providers (commercial/central banks), own TWAP/median.
Update policy: frequency (1-15 min for volatile, 1 time/day for stable), publication delay.
Markups: 'rate (1 + fx_markup_bps)' to the client side; transparent per-channel/region rules.
Guaranteed quotation window (rate lock): 5-30 minutes with 'fx _ version' in the order.
Anti-jump: cap changes per tick, circuit-breakers, fallback on the latest valid quote.
Versioning: each course publication has a'version', 'effective _ from'; Keep history for returns/disputes.

4) Pricing strategies

Base + FX: store the base price in the "core" (for example, EUR), convert on the showcase.
Per-currency sheets: pre-calculated prices for key currencies (best UX, predictability).
Mixed: top 10 currencies - pre-calculation, "long tail" - on-the-fly.
Charm-pricing: `X. 99/95/90 'by region, monitor the accumulation of rounding errors.
Fees: payment fee, cross-border fee, network fee (crypto) - in the directory or at the "Checkout Pricing" stage.

5) Taxes and "inclusion"

VAT/GST included/excluded: EU - more often than VAT-inclusive; B2B can be VAT-free.
Layers of taxes: federal/state/local; for online games - specific fees.
Threshold rates: tax varies from turnover/category/region (threshold).
Tax rounding: per-item vs per-basket; rounding modes and calculation order must be deterministic.
Yur. reporting: keep the'tax _ rule _ version' in the check/receipt.

6) Rounding and accuracy

Round at the last step of the show; keep "high accuracy" in calculations (up to 8-9 characters).
For crypto, use decimal libraries (without binary floating point).
Basket anti-drift: "bankers rounding" for amounts, but UX-rounding for display; fix'rounding _ scope '.
Sum rule: the sum of line-by-line rounding must be the same as total - use penny distribution.

7) Catalogs, promos and bundles

Promo-правила: `if region=A and currency in [EUR,USD] then discount=10% cap=50`.
Order of application: (1) base price → (2) discounts → (3) taxes → (4) fees → (5) rounding.
Bundle distribution: proportional to the position tab before the discount; wrapper for returns.
Threshold promo: free shipping/bonus when total≥X in cart currency; Keep the base currency equivalent, but fix the FX version.

8) Integration with payments and compliance

Currency availability: Not every currency is available to every player/region/payment provider.
Guaranteed FX: authorization prefix by fixed 'fx _ version'; during expiration - request confirmation of the new price.
CUS/sanctions: block lists of currencies/banks/tokens, restrictions on conversion.
Returns/chargeback: recalculation according to the historical 'fx _ version' of the order; return fee - by directory on the date of the transaction.

9) API Architecture and Contract

Reading directory:
  • `GET /catalog/prices? sku=…¤cy=…®ion=…&pricelist=…`
  • Ответ: `{unit_price, currency, fx_version, pricelist_version, tax_breakdown[], fees[], display_price, rounding_mode}`
Basket valuation (pricer):
  • `POST /pricing/quote { items[], region, currency, buyer_type }`
  • Ответ: `{items_priced[], subtotal, discounts, taxes[], fees[], total, fx_version, lock_ttl, signature}`
Confirmation (checkout):
  • 'POST/pricing/commit {quote_id, signature} '→ receipt with hash and signatures.
Webhooks:
  • `PriceListUpdated`, `FXRatePublished`, `TaxRuleChanged`, `PromoChanged` — с `version/effective_from`.

10) Caching and performance

Edge cache: key 'pricelist: region: currency: sku: version'; The TTL for stable currencies is higher.
Warmup: Warming up the top categories by campaign launch.
SWR (stale-while-revalidate): for storefronts; checkout - fresh only.
Partial invalidation: disability by 'sku', 'category', 'pricelist _ version' tags.
SLO: p95 ≤ 120ms for display, p95 ≤ 250ms for quote, ≥99. 95% availability.

11) Observability and audit

Trace: 'trace _ id', 'pricelist _ version', 'fx _ version', 'tax _ rule _ version' in all events.
Immutability: WORM-journals of publications of price lists/courses; Merkle-slices, release signatures (DSSE).
Receipts: check/receipt with full layout and payload hash; store for 7-10 years (by regulator).
Dashboards: vitrina↔checkout discrepancy, up/down rounding frequency, FX errors, course lock time (lock TTL), ROI promo.

12) Display localization

Currency format: character/code (₴, €, $, AED), character position, delimiters, space.
Local rules: "₴ 1,234,56" vs "$1,234. 56”.
Psychology: magic price tags ('.99') are not always appropriate in fintech/games; test the per-region.

Legal signatures: "Price includes VAT," "Network commission is charged separately."

13) Special cases

Currencies without fractional part: JPY/ISK - minor_units=0.
Three-character minor units: KWD/BHD = 3.
Crypto: BTC/ETH/USDT - up to 8 characters, network fee separately; stablecoins ≠ "1:1 heading" with cross border.
Double price: "catalog currency" ≠ "write-off currency" (merchant bank rate). Document the spread.
Sports/games: maximum winnings limits in catalog currency - keep equivalents by 'fx _ version' round.

14) SLO/SLI and success metrics

Correctness: the proportion of orders where total_checkout = total_quote (± 1 minor unit for distribution rules) ≥ 99. 99%.
FX stability: the share of operations in the rate lock window ≥ 99%.
Economy: margin/unit vs plan; deviations due to FX/rounding (bps).
UX: speed quote p95, share of dumps on price conversion, NPS storefronts.
Audit: 100% of checks with saved '_ version' and signature.

15) Incident playbooks

"The price on the showcase ≠ in the basket":

1. freeze cash disabled, 2) forced refresh price list, 3) compare 'pricelist _ version '/' fx _ version', 4) policy compensation.

"FX jump destroys margins":

1. enable increased markup/discount cap, 2) reduce lock TTL, 3) switch to fallback source.

"Tax does not converge":

1. check 'tax _ rule _ version', 2) validation of rounding_scope, 3) hotfix rules and reprice of baskets.

"Promo gives a negative price":

1. security rules (min_price), 2) disable stacking, 3) recalculation and audit.

16) Safety and compliance

Policy-as-code: control of changes in price lists/FX/taxes through PR + release signatures.
Roles/accesses: 4-eye principle on price publications/FX.
Logs/receipts: signed publishing events and checkout.
Regional restrictions: prohibition of individual currencies/tokens; geo-politicians.

17) Experiments and optimization

A/B: charm-pricing, pre-calculated prices vs on-the-fly, display format.
Dynamic markup: dependence on pair volatility/time of day.
Cohort analysis: returns/chargeback by currency, rounding sensitivity.
Cash strategies: SWR/TTL impact on conversion and accuracy.

18) Implementation checklist

  • Define the base currency and policy per-currency of the sheets.
  • Configure FX collection/publishing with versioning, markups, and lock TTL.
  • Formalize TaxRule and calculation/rounding order (per-item or per-basket).
  • Implement directory API/quote/commit + signed receipts.
  • Enable edge cache and granular disability; SWR for storefronts.
  • Create dashboards (vitrina↔checkout, FX errors, taxes, bps margin).
  • Enter roles/signatures on price/rate publications, WORM journals.
  • Prepare playbooks: Price miss, FX spike, tax discrepancies.
  • Conduct "GameDay Catalog": disable FX source, promo burst, tax change.
  • Regularly revamp minor_units/otobrazheniye by region.

19) FAQ

Do I need to store prices in each currency?
Not necessarily. Combine pre-calculation for top currencies and conversion for tail - this is how UX and costs are balanced.

Why does total "not beat" after rounding?

Due to differences per-item vs per-basket. Fix one approach and use "penny distribution."

How to make a refund in a month?
According to the historical 'pricelist _ version', 'fx _ version' and 'tax _ rule _ version' stored in the receipt.

What about crypto?
Use decimal accuracy, network fee separately, do not promise 1:1 to fiat; fix the course and the action window.

Summary: A multicurrency catalog is a combination of precision math, strict policies, and smart caching. Version everything (prices/rates/taxes), fix the quotation window, determine the order of calculations and rounding, sign check artifacts and keep dashboards visible. So you get an honest showcase, reproducible settlements and a managed economy in all currencies and regions.

Contact

Get in Touch

Reach out with any questions or support needs.We are always ready to help!

Telegram
@Gamble_GC
Start Integration

Email is required. Telegram or WhatsApp — optional.

Your Name optional
Email optional
Subject optional
Message optional
Telegram optional
@
If you include Telegram — we will reply there as well, in addition to Email.
WhatsApp optional
Format: +country code and number (e.g., +380XXXXXXXXX).

By clicking this button, you agree to data processing.