Skip to Content
FeaturesCurrency

Currency

Hoikka uses EUR as the base currency with built-in support for multi-currency expansion.

Key Concepts

  • Base currency: EUR (all prices stored in EUR cents)
  • Minor units: Prices stored as integers (2999 = 29.99)
  • Exchange rate: Locked at order creation time
  • Locale-aware formatting: Proper symbols and decimal separators

Price Storage

All prices are stored in cents (minor units) to avoid floating-point errors:

// Product variant price variant.price = 2999; // 29.99 EUR // Order totals order.subtotal = 5998; // 59.98 EUR order.total = 6498; // 64.98 EUR

Formatting Prices

Use the shared formatPrice helper for consistent display:

import { formatPrice } from "$lib/utils"; // Format with currency symbol formatPrice(2999); // "29,99 €" (default EUR) formatPrice(2999, "EUR"); // "29,99 €" formatPrice(2999, "USD"); // "$29.99" formatPrice(2999, "GBP"); // "£29.99" formatPrice(2999, "SEK"); // "29,99 kr"

Available Functions

import { formatPrice, formatPriceNumber, convertPrice, getCurrencySymbol, BASE_CURRENCY } from "$lib/utils"; // Format with currency symbol formatPrice(2999, "EUR"); // "29,99 €" // Format number only (no symbol) formatPriceNumber(2999, "EUR"); // "29,99" // Convert from base currency convertPrice(2999, 1.08); // 3239 (EUR to USD at 1.08 rate) // Get currency symbol getCurrencySymbol("EUR"); // "€" getCurrencySymbol("USD"); // "$" // Base currency constant BASE_CURRENCY; // "EUR"

Supported Currencies

CodeSymbolLocaleExample
EURfi-FI29,99 €
USD$en-US$29.99
GBP£en-GB£29.99
SEKkrsv-SE29,99 kr
NOKkrnb-NO29,99 kr
DKKkrda-DK29,99 kr

Order Currency Fields

Orders store currency information for historical accuracy:

order = { currencyCode: "EUR", // ISO 4217 currency code exchangeRate: "1.000000", // Rate from EUR at order time subtotal: 5998, // Always in order's currency total: 6498 };

Why Store Exchange Rate?

When an order is placed, the exchange rate is locked:

Order placed: 2024-01-15, rate EUR→USD = 1.08 Order total: 64.98 EUR = $70.18 USD Later (2024-02-01): rate changes to 1.12 Order still shows: $70.18 (original rate preserved)

Database Schema

-- Orders table CREATE TABLE orders ( -- ... currency_code VARCHAR(3) DEFAULT 'EUR' NOT NULL, exchange_rate NUMERIC(10, 6) DEFAULT '1' NOT NULL, -- ... );

Usage in Components

Svelte Components

<script> import { formatPrice } from "$lib/utils"; </script> <!-- Product price --> <span>{formatPrice(variant.price)}</span> <!-- Order total with specific currency --> <span>{formatPrice(order.total, order.currencyCode)}</span>

Server-Side

import { formatPrice, convertPrice } from "$lib/utils"; // Calculate price in target currency const eurPrice = 2999; const exchangeRate = 1.08; const usdPrice = convertPrice(eurPrice, exchangeRate); // 3239

Best Practices

  1. Always use formatPrice() - never format manually with .toFixed(2)
  2. Store in cents - avoid floating-point math
  3. Lock exchange rate - store rate at order creation
  4. Use ISO 4217 codes - 3-letter currency codes (EUR, USD, GBP)
  5. Base currency is EUR - all product prices are in EUR
Last updated on