Currency Code Best Practices for Software Development
Comprehensive best practices for handling currency codes in software applications. Covers validation, display, storage, conversion, and common mistakes to avoid.
Development
Detailed Explanation
Currency Code Best Practices
Here is a consolidated set of best practices for handling currencies correctly in software applications, drawn from real-world experience building financial systems.
1. Always Use ISO 4217 Codes
// GOOD
{ currency: "USD" }
{ currency: "JPY" }
{ currency: "EUR" }
// BAD
{ currency: "dollar" }
{ currency: "$" }
{ currency: "US Dollar" }
{ currency: "usd" } // Lowercase is acceptable in some APIs (Stripe)
// but standardize within your system
2. Never Assume Decimal Places
// GOOD: Look up decimal places per currency
const DECIMALS = {
USD: 2, EUR: 2, GBP: 2, JPY: 0, KWD: 3, BHD: 3
};
// BAD: Hardcoded assumption
const cents = amount * 100; // Breaks for JPY, KWD
3. Store Money as a Value Object
class Money {
constructor(
readonly amount: bigint, // Minor units
readonly currency: string, // ISO 4217
) {}
add(other: Money): Money {
if (this.currency !== other.currency) {
throw new Error("Cannot add different currencies");
}
return new Money(this.amount + other.amount, this.currency);
}
format(locale: string): string {
const decimals = getDecimalPlaces(this.currency);
const major = Number(this.amount) / Math.pow(10, decimals);
return new Intl.NumberFormat(locale, {
style: "currency",
currency: this.currency,
}).format(major);
}
}
4. Validate Currency Codes
const VALID_CURRENCIES = new Set([
"USD", "EUR", "GBP", "JPY", "CHF", "AUD", "CAD",
// ... full ISO 4217 list
]);
function isValidCurrency(code: string): boolean {
return VALID_CURRENCIES.has(code.toUpperCase());
}
5. Handle Currency Pairs Correctly
// Convention: BASE/QUOTE (or BASE/COUNTER)
// EUR/USD = 1.08 means 1 EUR costs 1.08 USD
// GOOD: Explicit about direction
{ from: "EUR", to: "USD", rate: 1.08 }
// BAD: Ambiguous
{ pair: "EUR-USD", rate: 1.08 } // Which direction?
6. Common Mistakes to Avoid
- Floating-point arithmetic for money (use integers or Decimal)
- String concatenation for formatting ("$" + amount)
- Assuming 2 decimal places for all currencies
- Ignoring locale for symbol placement and separators
- Not storing the currency alongside the amount
- Using deprecated codes (DEM, FRF instead of EUR)
- Mixing minor and major units in the same system
7. Testing Checklist
- JPY amounts (0 decimals) display and calculate correctly
- KWD amounts (3 decimals) display and calculate correctly
- Negative amounts format correctly in all supported locales
- Zero amounts display the correct currency symbol
- Currency code validation rejects invalid codes
- Rounding matches expected behavior for each currency
Use Case
This guide serves as a checklist for development teams building any application that handles money. Whether you are starting a new project or auditing an existing codebase, these best practices help prevent the most common and costly currency-related bugs.