Skip to main content

Currency Management

Canonical Rules

  • Currency codes must be ISO-4217, 3 letters, uppercase.
  • Site.currency is the canonical fallback source.
  • Default fallback is EUR when currency is absent or invalid.
  • Product.currency is required for catalog, widget, and search rendering.
  • FX conversion is intentionally out of scope. Values are never auto-converted between currencies.
  • Mixed-currency monetary data must not be merged into one scalar total.

Data Model

  • Site.currency (required, default EUR)
  • Product.currency (required, backfilled from site currency where missing)
  • Legacy defaults that were USD were normalized to EUR in v2 rollout.

Fallback Order

Use this order for runtime and forwarding decisions:

  1. Event-level currency (if valid)
  2. Order-level currency (if valid)
  3. Site-level currency (Site.currency)
  4. EUR

API Contract Notes

  • POST /api/v1/sites supports currency.
  • PUT /api/v1/sites/:id supports currency.
  • PUT /api/v1/admin/sites/:id supports currency.
  • Product responses include mandatory currency.
  • Category conversion analytics return revenueByCurrency[] (no mixed single total).

Analytics Rules

  • When multiple currencies exist in a window, responses expose per-currency rows.
  • UI must format each amount with the row currency.
  • Dashboards should show Mixed for aggregate cards when a single-currency total is not valid.

Integration Forwarding Rules

  • GA4 / Meta / Google Ads currency resolution uses the fallback order above.
  • Provider payloads should not default to USD unless explicitly set by event/order/site data.

UI Rendering Rules

  • Never render fixed symbols ($, , ) without a currency code context.
  • Use shared currency formatter utilities.
  • Do not concatenate symbol + numeric strings manually.

Guardrail

  • Run pnpm currency:check to catch hardcoded fallback currency and symbol regressions in runtime code.