ISO 4217 Currency Codes: The Complete Developer Guide
If you've ever built a payment system, integrated an exchange rate API, or displayed prices in multiple currencies, you've encountered ISO 4217 currency codes — whether you knew it or not. These three-letter codes like USD, EUR, JPY, and GBP are the universal language of money in software development. Understanding how they work, where they come from, and how to use them correctly is essential for any developer building financial applications.
This guide covers everything you need to know: the structure of currency codes, a reference list of the world's most-used currencies, how to handle minor units and special codes, and how to put them to work with a Finexly API documentation integration that fetches live exchange rates.
What Is ISO 4217?
ISO 4217 is an international standard published by the International Organization for Standardization (ISO) that defines codes for representing world currencies. First introduced in 1978, it is now used universally in banking systems, financial software, e-commerce platforms, payment processors, and currency exchange APIs.
The standard serves three key purposes:
- Eliminate ambiguity — "dollar" could mean the US dollar, Canadian dollar, Australian dollar, or dozens of others.
USD,CAD,AUDare unambiguous. - Enable computerized processing — Both alphabetic codes and numeric codes allow systems with different character set support to handle currency data reliably.
- Support international interoperability — Any compliant system — whether a bank in Tokyo or a startup in Berlin — can exchange financial data without custom mappings.
The standard is maintained by SIX Group on behalf of ISO and the Swiss Association for Standardization, and the list is updated periodically as new currencies are introduced or old ones are retired.
Understanding the Code Structure
Alphabetic Codes (Alpha-3)
Every ISO 4217 alphabetic code is exactly three uppercase ASCII letters. The structure is deliberate:
- First two letters — Derived from the ISO 3166-1 alpha-2 country code (e.g.,
USfor the United States,JPfor Japan,GBfor Great Britain) - Third letter — Usually the first letter of the currency name (e.g.,
Dfor Dollar,Yfor Yen,Pfor Pound)
So USD = United States (US) + Dollar (D). JPY = Japan (JP) + Yen (Y). GBP = Great Britain (GB) + Pound (P).
There are exceptions — particularly for the Euro (EUR), which predates many of the countries that use it — but this pattern holds for the vast majority of national currencies.
Numeric Codes
Each currency also has a three-digit numeric code (e.g., 840 for USD, 978 for EUR, 826 for GBP). These numeric codes are especially useful in systems that don't handle Latin characters, and in EDI (Electronic Data Interchange) systems where bandwidth is constrained.
Where possible, the numeric currency code matches the ISO 3166-1 numeric country code for the issuing nation.
Minor Units (Decimal Places)
ISO 4217 also specifies the number of decimal places (minor units) for each currency. Most currencies use 2 decimal places (e.g., $1.99), but there are important exceptions:
| Minor Units | Example Currencies |
|---|---|
| 0 | Japanese Yen (JPY), Korean Won (KRW), Chilean Peso (CLP) |
| 2 | US Dollar (USD), Euro (EUR), British Pound (GBP) |
| 3 | Kuwaiti Dinar (KWD), Bahraini Dinar (BHD), Omani Rial (OMR) |
¥1999 as ¥19.99, you've introduced a 99x pricing error. Always look up the correct minor unit count for any currency your application supports.Major World Currencies Reference Table
Here are the most commonly used ISO 4217 currency codes, organized by region:
Americas
| Code | Currency | Country | Numeric | Decimals |
|---|---|---|---|---|
| USD | US Dollar | United States | 840 | 2 |
| CAD | Canadian Dollar | Canada | 124 | 2 |
| MXN | Mexican Peso | Mexico | 484 | 2 |
| BRL | Brazilian Real | Brazil | 986 | 2 |
| ARS | Argentine Peso | Argentina | 032 | 2 |
| CLP | Chilean Peso | Chile | 152 | 0 |
| COP | Colombian Peso | Colombia | 170 | 2 |
| PEN | Peruvian Sol | Peru | 604 | 2 |
Europe
| Code | Currency | Country/Region | Numeric | Decimals |
|---|---|---|---|---|
| EUR | Euro | Eurozone | 978 | 2 |
| GBP | British Pound Sterling | United Kingdom | 826 | 2 |
| CHF | Swiss Franc | Switzerland | 756 | 2 |
| NOK | Norwegian Krone | Norway | 578 | 2 |
| SEK | Swedish Krona | Sweden | 752 | 2 |
| DKK | Danish Krone | Denmark | 208 | 2 |
| PLN | Polish Zloty | Poland | 985 | 2 |
| CZK | Czech Koruna | Czech Republic | 203 | 2 |
| HUF | Hungarian Forint | Hungary | 348 | 2 |
| RON | Romanian Leu | Romania | 946 | 2 |
| RUB | Russian Ruble | Russia | 643 | 2 |
| TRY | Turkish Lira | Turkey | 949 | 2 |
Asia-Pacific
| Code | Currency | Country | Numeric | Decimals |
|---|---|---|---|---|
| JPY | Japanese Yen | Japan | 392 | 0 |
| CNY | Chinese Yuan Renminbi | China | 156 | 2 |
| HKD | Hong Kong Dollar | Hong Kong | 344 | 2 |
| SGD | Singapore Dollar | Singapore | 702 | 2 |
| AUD | Australian Dollar | Australia | 036 | 2 |
| NZD | New Zealand Dollar | New Zealand | 554 | 2 |
| KRW | South Korean Won | South Korea | 410 | 0 |
| INR | Indian Rupee | India | 356 | 2 |
| IDR | Indonesian Rupiah | Indonesia | 360 | 2 |
| THB | Thai Baht | Thailand | 764 | 2 |
| MYR | Malaysian Ringgit | Malaysia | 458 | 2 |
| PHP | Philippine Peso | Philippines | 608 | 2 |
| TWD | New Taiwan Dollar | Taiwan | 901 | 2 |
| VND | Vietnamese Dong | Vietnam | 704 | 0 |
Middle East & Africa
| Code | Currency | Country | Numeric | Decimals |
|---|---|---|---|---|
| AED | UAE Dirham | United Arab Emirates | 784 | 2 |
| SAR | Saudi Riyal | Saudi Arabia | 682 | 2 |
| ILS | Israeli New Shekel | Israel | 376 | 2 |
| EGP | Egyptian Pound | Egypt | 818 | 2 |
| ZAR | South African Rand | South Africa | 710 | 2 |
| NGN | Nigerian Naira | Nigeria | 566 | 2 |
| KES | Kenyan Shilling | Kenya | 404 | 2 |
| KWD | Kuwaiti Dinar | Kuwait | 414 | 3 |
| BHD | Bahraini Dinar | Bahrain | 048 | 3 |
| OMR | Omani Rial | Oman | 512 | 3 |
| QAR | Qatari Riyal | Qatar | 634 | 2 |
Special and Non-Standard Codes
ISO 4217 includes several special codes that don't correspond to traditional national currencies. These start with X (for "extra") and are important to know when building global financial applications.
Precious Metals
| Code | Description |
|---|---|
| XAU | Gold (troy ounce) |
| XAG | Silver (troy ounce) |
| XPT | Platinum (troy ounce) |
| XPD | Palladium (troy ounce) |
Testing and Special Purposes
| Code | Description |
|---|---|
| XTS | Code reserved for testing purposes |
| XXX | No currency / transaction involves no currency |
Supranational and Collective Codes
| Code | Description |
|---|---|
| XDR | Special Drawing Rights (International Monetary Fund) |
| XCD | East Caribbean Dollar (shared by 8 island nations) |
Important: Bitcoin and other cryptocurrencies are not part of ISO 4217, although various informal codes (BTC,ETH) are widely used. Some payment processors and APIs useXBTfor Bitcoin (following theXprefix convention), but this is not an official ISO designation.
Using Currency Codes in Your Application
Fetching Live Exchange Rates with Finexly
The Finexly API supports all 170+ ISO 4217 currency codes. Here's how to fetch live exchange rates using the standard three-letter codes:
cURL
curl "https://finexly.com/api/latest?base=USD&symbols=EUR,GBP,JPY,CAD,AUD" \
-H "Authorization: Bearer YOUR_API_KEY"Response:
{
"base": "USD",
"date": "2026-04-04",
"rates": {
"EUR": 0.9234,
"GBP": 0.7891,
"JPY": 149.85,
"CAD": 1.3612,
"AUD": 1.5473
}
}JavaScript (fetch)
const BASE_CURRENCY = 'USD';
const TARGET_CURRENCIES = ['EUR', 'GBP', 'JPY', 'CNY', 'AUD'];
async function getExchangeRates() {
const symbols = TARGET_CURRENCIES.join(',');
const url = `https://finexly.com/api/latest?base=${BASE_CURRENCY}&symbols=${symbols}`;
const response = await fetch(url, {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});
const data = await response.json();
return data.rates;
}
getExchangeRates().then(rates => {
console.log(`1 USD = ${rates.EUR} EUR`);
console.log(`1 USD = ${rates.JPY} JPY`);
});Python (requests)
import requests
API_KEY = "YOUR_API_KEY"
BASE = "USD"
TARGETS = ["EUR", "GBP", "JPY", "CNY", "BRL"]
response = requests.get(
"https://finexly.com/api/latest",
params={"base": BASE, "symbols": ",".join(TARGETS)},
headers={"Authorization": f"Bearer {API_KEY}"}
)
data = response.json()
for code, rate in data["rates"].items():
print(f"1 {BASE} = {rate} {code}")PHP
<?php
$apiKey = 'YOUR_API_KEY';
$base = 'USD';
$symbols = implode(',', ['EUR', 'GBP', 'JPY', 'CNY', 'AUD']);
$url = "https://finexly.com/api/latest?base={$base}&symbols={$symbols}";
$context = stream_context_create([
'http' => [
'header' => "Authorization: Bearer {$apiKey}\r\n"
]
]);
$response = file_get_contents($url, false, $context);
$data = json_decode($response, true);
foreach ($data['rates'] as $code => $rate) {
echo "1 {$base} = {$rate} {$code}\n";
}
?>Converting Between Currencies
To convert an amount from one currency to another, you need the exchange rate between them. You can fetch live rates from our currency converter tool or through the API:
def convert_currency(amount: float, from_code: str, to_code: str, rates: dict) -> float:
"""
Convert amount from one ISO 4217 currency to another.
rates: dict of exchange rates relative to a base currency (e.g., USD)
"""
if from_code == "USD":
# Direct conversion from base currency
return amount * rates[to_code]
elif to_code == "USD":
# Convert back to base currency
return amount / rates[from_code]
else:
# Cross-rate conversion
usd_amount = amount / rates[from_code]
return usd_amount * rates[to_code]
# Example usage
rates = {"EUR": 0.9234, "GBP": 0.7891, "JPY": 149.85}
eur_amount = convert_currency(100, "USD", "EUR", rates)
print(f"$100 = €{eur_amount:.2f}") # $100 = €92.34Formatting Currency Values by Locale
Getting the number formatting right is just as important as the currency code itself. Different countries use different decimal separators, grouping separators, and symbol placement conventions.
JavaScript — Intl.NumberFormat
The Intl.NumberFormat API is the gold standard for locale-aware currency formatting in JavaScript:
function formatCurrency(amount, currencyCode, locale = 'en-US') {
return new Intl.NumberFormat(locale, {
style: 'currency',
currency: currencyCode,
minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(amount);
}
// Examples with different locales
console.log(formatCurrency(1234.56, 'USD', 'en-US')); // $1,234.56
console.log(formatCurrency(1234.56, 'EUR', 'de-DE')); // 1.234,56 €
console.log(formatCurrency(1234.56, 'GBP', 'en-GB')); // £1,234.56
console.log(formatCurrency(1234.56, 'JPY', 'ja-JP')); // ¥1,235 (no decimals!)
console.log(formatCurrency(1234.56, 'INR', 'en-IN')); // ₹1,234.56
// Handling zero-decimal currencies correctly
console.log(formatCurrency(1500, 'JPY', 'ja-JP')); // ¥1,500 ✓
// Never: ¥15.00 ✗ — that would be a 100x pricing error!Key insight: Intl.NumberFormat automatically applies the correct number of decimal places for each currency code when you don't override minimumFractionDigits — so JPY will render as a whole number and KWD as three decimal places.
Python — babel library
from babel.numbers import format_currency
# Babel handles locale-specific formatting
print(format_currency(1234.56, 'USD', locale='en_US')) # $1,234.56
print(format_currency(1234.56, 'EUR', locale='de_DE')) # 1.234,56 €
print(format_currency(1234.56, 'JPY', locale='ja_JP')) # ¥1,235
print(format_currency(1234.56, 'INR', locale='en_IN')) # ₹1,234.56
print(format_currency(12.345, 'KWD', locale='ar_KW')) # 12.345 KWD (3 decimal places)Install with: pip install babel
Common Developer Mistakes with Currency Codes
Mistake 1: Storing Currency as a Floating Point Number
# ❌ WRONG — floating point errors will cause headaches
price = 19.99
tax = 0.20
total = price * (1 + tax) # 23.988000000000003
# ✅ CORRECT — use integer minor units
price_cents = 1999 # $19.99 stored as cents
tax_rate = Decimal('0.20')
total_cents = int(price_cents * (1 + tax_rate)) # 2399 = $23.99Mistake 2: Assuming All Currencies Have 2 Decimal Places
// ❌ WRONG
function formatPrice(amount, currency) {
return `${amount.toFixed(2)} ${currency}`; // Always 2 decimals
}
formatPrice(1500, 'JPY') // "1500.00 JPY" — WRONG, JPY has 0 decimals
// ✅ CORRECT — use Intl.NumberFormat which knows decimal counts
function formatPrice(amount, currency, locale) {
return new Intl.NumberFormat(locale, { style: 'currency', currency }).format(amount);
}Mistake 3: Hardcoding Currency Symbols
# ❌ WRONG — not all dollars use "$", not all euros use "€" in all contexts
SYMBOLS = {'USD': '$', 'EUR': '€', 'GBP': '£'}
formatted = f"{SYMBOLS[currency]}{amount:.2f}"
# ✅ CORRECT — let your localization library handle it
from babel.numbers import format_currency
formatted = format_currency(amount, currency, locale=user_locale)Mistake 4: Confusing CNY and CNH
China has two currency codes in practice:
- CNY — Chinese Yuan Renminbi, used onshore (mainland China)
- CNH — Chinese Yuan traded offshore (Hong Kong, international markets)
CNH is not an official ISO 4217 code, but it is widely used in financial APIs and trading platforms. The exchange rates between CNY and CNH can differ slightly due to capital controls. For most application developers, CNY is the correct code to use.
Building a Currency Selector Component
Here's a practical example of building a currency selector in JavaScript that uses the Finexly API documentation to display all 170+ supported currencies. This is especially useful when building multi-currency e-commerce sites:
async function buildCurrencySelector(elementId, apiKey) {
// Fetch supported currencies from Finexly
const response = await fetch('https://finexly.com/api/currencies', {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const { currencies } = await response.json();
const select = document.getElementById(elementId);
// Build options with flag emoji, code, and name
currencies.forEach(({ code, name }) => {
const option = document.createElement('option');
option.value = code;
option.textContent = `${code} — ${name}`;
select.appendChild(option);
});
}
// Usage
buildCurrencySelector('currency-dropdown', 'YOUR_API_KEY');Check out the full list of supported currencies and other Finexly API documentation to see all the endpoints available for currency conversion and historical rates.
Historical Rates and Discontinued Currencies
ISO 4217 maintains codes for historical currencies that are no longer in use. These are sometimes needed when working with historical financial data:
| Code | Currency | Notes |
|---|---|---|
| DEM | German Deutsche Mark | Replaced by EUR in 2002 |
| FRF | French Franc | Replaced by EUR in 2002 |
| ITL | Italian Lira | Replaced by EUR in 2002 |
| GRD | Greek Drachma | Replaced by EUR in 2002 |
| YUM | Yugoslav Dinar | Yugoslavia dissolved |
| DDM | East German Mark | German reunification |
Frequently Asked Questions
What is the difference between a currency code and a currency symbol?
A currency code is a standardized three-letter identifier (e.g., USD) defined by ISO 4217, while a currency symbol is a typographic shorthand (e.g., $, €, £). Symbols vary by locale — for example, $ can mean CAD, USD, AUD, or many other dollars depending on context. Currency codes are always unambiguous.
How many ISO 4217 currency codes are there? As of 2026, there are around 180 active currency codes. The exact number changes as new currencies are introduced (e.g., new nations forming or currency reforms) and old ones are retired. Finexly supports 170+ of these for real-time exchange rate queries.
Can I use currency codes with the Finexly free plan? Yes — the pricing page shows our free plan includes access to all supported ISO 4217 currency codes with up to 1,000 API requests per month. You can query any combination of base and target currencies within that limit. If you need more capacity, see our API comparison page to evaluate plan options.
Why does JPY (Japanese Yen) have no decimal places? The Yen was decimalized differently from most currencies. While it technically has a sub-unit called the "sen" (1/100 of a Yen), sen are no longer used in practice, making JPY effectively a zero-decimal currency. This is why 500 Yen is written as ¥500 — not ¥5.00.
What currency code should I use for the Euro in all Eurozone countries?
Always use EUR — it is the same currency code regardless of whether the transaction is in Germany, France, Spain, Italy, or any other Eurozone nation. The Euro is a supranational currency with a single ISO code for all member states.
Next Steps
Now that you understand ISO 4217 currency codes, you have the foundation to build reliable, internationally compatible financial applications. The key takeaways:
- Always use three-letter ISO 4217 codes when storing or transmitting currency information
- Look up the correct minor unit count before formatting any currency value
- Use
Intl.NumberFormat(JavaScript) orbabel(Python) for locale-aware display - Never store monetary amounts as floating point — use integers in minor units
Ready to add live exchange rates to your project? Get your free Finexly API key — no credit card required. Start with 1,000 free requests per month and access real-time rates for all 170+ ISO 4217 currencies.
Need to work with historical rates? Check out our historical exchange rates API guide. Want to understand how to choose between REST and WebSocket for your API integration? Or learn about multi-currency SaaS billing?
Upgrade as you grow when your needs increase.
Explore More
Vlado Grigirov
Senior Currency Markets Analyst & Financial Strategist
Vlado Grigirov is a senior currency markets analyst and financial strategist with over 14 years of experience in foreign exchange markets, cross-border finance, and currency risk management. He has wo...
View full profile →