Malaysian money, handled the way the rules say. Cash rounding to 5 sen per
Bank Negara, SST by category, and amounts in words for cheques and
invoices. Everything is Decimal; floats are refused at the door.
$ ringgit round 12.33
RM12.33 -> RM12.35 (rounding +RM0.02)
$ ringgit words 1234.50
Ringgit Malaysia: Seribu Dua Ratus Tiga Puluh Empat Dan Lima Puluh Sen Sahaja
$ ringgit sst 33.33 fnb
net RM33.33
sst RM2.00
gross RM35.33
cash RM35.35
pip install ringgit
No dependencies. Python 3.10+.
Three things go wrong in almost every Malaysian invoicing codebase:
- Money in floats.
0.1 + 0.2is not0.3, and a total that is off by a sen fails reconciliation.ringgittakesstr,intorDecimaland raisesTypeErroron a float instead of rounding it quietly. - The 5-sen rule done wrong. Since 1 April 2008 the total of a cash bill is rounded to the nearest 5 sen: 1 and 2 sen down, 3 and 4 up to 5, 6 and 7 down to 5, 8 and 9 up to 10. It applies to the cash total only, not to each line and not to card or transfer payments. People round every item, or round electronic payments, or use a generic "round to nearest 0.05" that behaves differently at the edges.
- "The SST rate." There is not one. Service tax is 8% standard and 6% for food and beverage, telecommunications, parking, logistics and, since 1 January 2026, industrial rental. Sales tax is 5% or 10% by tariff line, with exempt goods at 0%. A single constant is the wrong answer.
from ringgit import RM, round_cash, sst, to_words
total = RM("10.10") + RM("0.20") + "0.03" # RM10.33
total.cash() # RM10.35 — what the customer hands over
str(total) # 'RM10.33'
round_cash("12.38") # Decimal('12.40')
sst("100", "service") # Decimal('8.00')
sst("100", "fnb") # Decimal('6.00')
sst("100", Decimal("0.07")) # an explicit rate, when you must
to_words("1500") # 'Ringgit Malaysia: Seribu Lima Ratus Sahaja'
to_words("1500", "en") # 'Ringgit Malaysia One Thousand Five Hundred Only'The words follow cheque convention: Ringgit Malaysia: ... Sahaja, with se- before puluh, belas, ratus and ribu (sepuluh, sebelas, seratus, seribu) and satu before juta and bilion.
- Rounding: Bank Negara Malaysia, Rounding Mechanism, effective 1 April 2008.
- SST: Royal Malaysian Customs Department, MySST. Rates as of 1 January 2026.
47 tests, including the full sen-ending table for the rounding rule and the awkward Malay numerals (sebelas, seratus satu, satu juta).
MIT.