Back to Arky

Price Formatting

Utilities for currency-safe minor-unit conversion and formatting

Arky stores monetary amounts as integer minor units. The scale depends on the currency: for example, USD has two minor-unit digits while JPY has none. Always carry the currency code with the amount instead of assuming that every value is cents.

Importing

import {
	convertToMajor,
	convertToMinor,
	formatMinor,
	getCurrencyMinorUnits,
	getCurrencyName,
	getCurrencySymbol,
	SUPPORTED_STORE_CURRENCIES,
} from "arky-sdk/utils";

Format Minor Units

Pass both the integer amount and its ISO currency code:

formatMinor(1999, "USD"); // "$19.99"
formatMinor(1999, "EUR"); // "€19.99"
formatMinor(1999, "JPY"); // "¥1,999"

formatMinor applies the supported currency’s minor-unit scale before using Intl.NumberFormat.

Convert Between Major And Minor Units

Conversions also require the currency:

convertToMajor(1999, "USD"); // 19.99
convertToMajor(1999, "JPY"); // 1999

convertToMinor(19.99, "USD"); // 1999
convertToMinor(1999, "JPY"); // 1999

Do not divide or multiply by 100 directly; that is wrong for zero-decimal currencies.

Currency Metadata

getCurrencyMinorUnits("USD"); // 2
getCurrencyMinorUnits("JPY"); // 0

getCurrencySymbol("USD"); // "$"
getCurrencyName("USD"); // "US Dollar"

console.log(SUPPORTED_STORE_CURRENCIES);

Display An API Amount

API payment and price objects already carry their currency:

function PaymentTotal({
	payment,
}: {
	payment: { total: number; currency: string };
}) {
	return <span>{formatMinor(payment.total, payment.currency)}</span>;
}
Tip

Store and transmit integer minor-unit amounts together with their currency. Convert only at input and display boundaries.

Warning

Currency-aware conversion rejects unsupported currency codes instead of guessing a decimal scale.