EZRate
Sign in

Difference Between IRR and Toman: A Developer’s Guide to Units and Formatting

The difference between IRR and Toman for developers: 1 Toman = 10 Rial, storing amounts, formatting Persian numbers, parsing input and avoiding 10× bugs.

Ersan Fazli
· Web Developer
Published 23 October 2026, 20:00 · 3 min read
Difference Between IRR and Toman
Key takeaways
  • The Rial (IRR) is Iran’s legal currency unit; the Toman equals 10 Rial and is what people use day to day. There is no ISO code for Toman.
  • Store integer amounts with an explicit unit column, convert once at the boundary and format only for display.
  • Persian digits, thousands separators and a possible redenomination are the other traps to design for.

Ask ten Iranian users how much something costs and all ten will answer in Toman. Look at their bank card receipt and it says Rial. That everyday ambiguity becomes a real bug the moment it enters a database. This guide explains the difference between IRR and Toman from a developer’s point of view and gives concrete patterns for storage, conversion, input and display.

★
Short answer
1 Toman = 10 Rial. IRR is the ISO 4217 code for the Rial; there is no ISO code for Toman (many systems use the informal “IRT”). Store integers with an explicit unit, convert once at your system boundary, and always print the unit next to the number. When using the EZRate API, request the unit you need with quote=IRT or quote=IRR instead of multiplying yourself.

Part of the Iranian Rial exchange rate API guide.

The basics

RialToman
CodeIRR (ISO 4217)None; “IRT” used informally
Value110 Rial
Where usedBank systems, cheques, official documents, card terminalsSpeech, shops, most price lists and websites
Minor unitsEffectively none in practiceNone

Inflation means everyday amounts run into millions of Toman, so integers are large but still fit easily in a 64-bit integer.

Storage: integer plus unit

sql
CREATE TABLE prices (
  id          bigserial PRIMARY KEY,
  amount      bigint      NOT NULL,          -- integer, no floats
  unit        varchar(4)  NOT NULL CHECK (unit IN ('IRR', 'IRT')),
  rate_source varchar(32) NOT NULL,          -- e.g. ezrate:tehran
  rate_at     timestamptz NOT NULL
);
  • Pick one internal unit (Rial is the safer choice for anything that touches banks) and convert at the edges.
  • Never use floating point for money. For non-integer values such as crypto, use numeric/Decimal.
  • Keep the rate and its timestamp next to any converted amount, so you can explain it later.

Conversion in one place

typescript
export type Unit = "IRR" | "IRT";

export function toRial(amount: bigint, unit: Unit): bigint {
  return unit === "IRR" ? amount : amount * 10n;
}

export function fromRial(rial: bigint, unit: Unit): bigint {
  if (unit === "IRR") return rial;
  if (rial % 10n !== 0n) throw new Error("Rial amount is not a whole number of Toman");
  return rial / 10n;
}

A single, tested function prevents the classic “multiplied by ten twice” bug that happens when two layers each assume the other did not convert.

Getting rates in the unit you need

bash
# Toman (default)
curl -H "X-API-Key: $EZRATE_KEY" "https://api.ezrate.me/v1/rates/usd"
# Rial
curl -H "X-API-Key: $EZRATE_KEY" "https://api.ezrate.me/v1/rates/usd?quote=IRR"
# convert an amount from Toman to Rial-free units, e.g. 2,000,000 Toman in USD
curl -H "X-API-Key: $EZRATE_KEY" "https://api.ezrate.me/v1/convert?from=irt&to=usd&amount=2000000&side=sell"

The response always includes quote in meta (and per rate), so you can assert the unit in code. See the JSON reference.

Formatting for display

javascript
const fa = new Intl.NumberFormat("fa-IR");     // ۱۲۳٬۴۵۶
const en = new Intl.NumberFormat("en-US");     // 123,456

function price(amount, unit, locale = "fa") {
  const n = (locale === "fa" ? fa : en).format(amount);
  const label = locale === "fa" ? (unit === "IRT" ? "تومان" : "ریال") : (unit === "IRT" ? "Toman" : "Rial");
  return `${n} ${label}`;
}
  • Persian locale uses Persian digits and the Arabic thousands separator (٬).
  • In right-to-left layouts, wrap numbers in an element with dir="ltr" or use unicode-bidi: isolate to stop the minus sign and separators from jumping.
  • Large amounts read better as “12.5 million Toman” in headings; keep the full number in tables.
Example UI showing the same amount formatted in Persian and English with unit labels
One amount, two locales, explicit unit

User input

  • Accept Persian, Arabic and Latin digits; normalise to Latin before parsing.
  • Strip separators (,, ٬, spaces) before parsing.
  • Show the unit inside the input (“Toman”) and a live preview in words.
  • Reject amounts that are not a whole number of Toman if you store Rial and accept Toman.
javascript
const digits = { "۰":"0","۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9",
                 "٠":"0","١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9" };
export const parseAmount = (s) =>
  BigInt(s.replace(/[۰-۹٠-٩]/g, d => digits[d]).replace(/[,\s٬]/g, ""));

Redenomination

Iran has had plans to introduce a new unit by removing zeros from the Rial. If and when such a change takes effect, there will be a transition period where old and new units coexist. Designing with an explicit unit column today makes that migration a data transformation instead of a rewrite. Track official central-bank announcements for timing.

US Dollar271,860Toman+0.70%
Database table with amount, unit, rate source and timestamp columns
Storing money with an explicit unit

Finally, write the unit into your API contracts and logs as well: a field called amount without a unit is a future bug, while amount_irr or an {amount, unit} object documents itself and lets reviewers spot mistakes immediately.

Related live rates: US dollar rate, 18K gold price, Emami coin price.

What is the difference between IRR and Toman?
IRR (Rial) is the official unit with an ISO code; one Toman equals ten Rial and is the unit people use day to day.
Is there an ISO code for Toman?
No. IRT is used informally by many systems, including the EZRate API.
Should I store amounts in Rial or Toman?
Either works if you store the unit explicitly; Rial is the safer internal unit when you integrate with banks.
How do I avoid 10× bugs?
Convert in one tested function, request the unit you need from the API and assert the unit in responses.
Ersan Fazli
I work in software development and programming, with a strong interest in building practical and efficient solutions. My focus is on developing new features, improving system performance, and solving technical challenges using modern technologies. I strive to create reliable, scalable, and high-quality software through continuous learning and the application of modern development practices.
All posts by author →

Comments (0)

Comments are shown after review. Sign-in is needed to send.

Related

API & Developers
Iran Gold Price API: Live 18K Gold per Gram, Mesghal, Ounce and Emami Coin Prices
API & Developers
USD to IRR API in Python and Django: Fetch, Cache and Display Live Rates
API & Developers
Currency API JSON Schema: EZRate Endpoints, Headers and Error Codes