Every amount you send to VNSwitch, and every amount VNSwitch returns, is an integer in the
currency’s minor unit (the smallest unit of that currency). This applies to payment amounts,
capture amounts, refunds and payouts alike. Dispute objects are the one exception in format,
not in meaning: their amount is a string holding the minor-unit integer (for example
"150000"), so parse it as an integer.
importjava.math.BigDecimal;importjava.util.Map;publicclassAmounts{// Decimal places per currency (add the currencies you accept).staticfinalMap<String,Integer>MINOR_DIGITS=Map.of("VND",0,"JPY",0,"KRW",0,"USD",2,"EUR",2,"SGD",2,"KWD",3,"BHD",3);// "10.50" + "USD" -> 1050. Throws if the value has too many decimal places.staticlongtoMinorUnits(Stringvalue,Stringcurrency){intdigits=MINOR_DIGITS.get(currency);returnnewBigDecimal(value).movePointRight(digits).longValueExact();}// 1050 + "USD" -> "10.50"staticStringformatMinorUnits(longamount,Stringcurrency){returnBigDecimal.valueOf(amount,MINOR_DIGITS.get(currency)).toPlainString();}publicstaticvoidmain(String[]args){System.out.println(toMinorUnits("150000","VND"));// 150000System.out.println(toMinorUnits("10.50","USD"));// 1050System.out.println(formatMinorUnits(1050,"USD"));// 10.50}}
The number of minor units in one major unit depends on the currency:
Currency
Decimal places
amount you send
Means
VND
0
150000
150,000 VND
USD
2
1050
10.50 USD
KWD
3
1500
1.500 KWD
VND has no minor unit. The amount is the number of dong: amount: 150000 with
currency: "VND" is 150,000 VND. Do not multiply VND amounts by 100.
A common bug is to treat every currency as having two decimal places. For VND that charges the customer 100 times too much: 15000000 is 15,000,000 VND, not 150,000 VND. Always look up the decimal places of the currency before you convert.
The amount field is an integer. A value with a fractional part, such as 150000.5, is not a
valid amount and the request is rejected (see
Errors).
The currency field takes a three-letter ISO 4217 code in uppercase, for example "VND" or
"USD". Which currencies you can actually charge depends on the payment providers enabled for
your account.
The examples in the code column convert between a decimal string (what a person types or what
your order system stores, for example "10.50") and the integer that VNSwitch expects, and
back again for display.
Never use floating-point numbers for money.10.50 * 100 in binary floating point can
give 1049.9999999999998. Work with integers, a decimal string, or an exact decimal type
(Decimal in Python, BigDecimal in Java).
Reject values with too many decimal places instead of rounding them silently. "10.505"
is not a valid USD amount, and "150000.5" is not a valid VND amount.
Store the integer and the currency together. An amount without its currency is
ambiguous: 150000 is 150,000 VND but 1,500.00 USD.
Keep amounts in minor units end to end. Convert only at the edges: when a person enters
an amount and when you show one.