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 EURFormatting 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
| Code | Symbol | Locale | Example |
|---|---|---|---|
| EUR | € | fi-FI | 29,99 € |
| USD | $ | en-US | $29.99 |
| GBP | £ | en-GB | £29.99 |
| SEK | kr | sv-SE | 29,99 kr |
| NOK | kr | nb-NO | 29,99 kr |
| DKK | kr | da-DK | 29,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); // 3239Best Practices
- Always use
formatPrice()- never format manually with.toFixed(2) - Store in cents - avoid floating-point math
- Lock exchange rate - store rate at order creation
- Use ISO 4217 codes - 3-letter currency codes (EUR, USD, GBP)
- Base currency is EUR - all product prices are in EUR
Last updated on