ISO 8583 Parser
在线速查

ISO 4217 货币码与金额小数位

报文里的 DE49 放的是数字码不是字母码,而小数位决定了金额怎么读。下面还有个换算器。

共 74 个常用币种。0 位3 位小数的全部列出——它们是金额算错的高发区。
字母码数字码 DE49小数位名称
JPY3920日元
KRW4100韩元
VND7040越南盾
CLP1520智利比索
ISK3520冰岛克朗
PYG6000巴拉圭瓜拉尼
RWF6460卢旺达法郎
UGX8000乌干达先令
XAF9500中非法郎
XOF9520西非法郎
XPF9530太平洋法郎
BIF1080布隆迪法郎
DJF2620吉布提法郎
GNF3240几内亚法郎
KMF1740科摩罗法郎
VUV5480瓦努阿图瓦图
BHD0483巴林第纳尔
IQD3683伊拉克第纳尔
JOD4003约旦第纳尔
KWD4143科威特第纳尔
LYD4343利比亚第纳尔
OMR5123阿曼里亚尔
TND7883突尼斯第纳尔
USD8402美元
EUR9782欧元
CNY1562人民币
GBP8262英镑
HKD3442港元
MOP4462澳门元
TWD9012新台币
SGD7022新加坡元
AUD0362澳元
NZD5542新西兰元
CAD1242加元
CHF7562瑞士法郎
SEK7522瑞典克朗
NOK5782挪威克朗
DKK2082丹麦克朗
PLN9852波兰兹罗提
CZK2032捷克克朗
HUF3482匈牙利福林
RON9462罗马尼亚列伊
BGN9752保加利亚列弗
RUB6432俄罗斯卢布
UAH9802乌克兰格里夫纳
TRY9492土耳其里拉
ILS3762以色列新谢克尔
AED7842阿联酋迪拉姆
SAR6822沙特里亚尔
QAR6342卡塔尔里亚尔
EGP8182埃及镑
ZAR7102南非兰特
NGN5662尼日利亚奈拉
KES4042肯尼亚先令
INR3562印度卢比
PKR5862巴基斯坦卢比
BDT0502孟加拉塔卡
LKR1442斯里兰卡卢比
NPR5242尼泊尔卢比
THB7642泰铢
MYR4582马来西亚林吉特
IDR3602印尼盾
PHP6082菲律宾比索
KHR1162柬埔寨瑞尔
LAK4182老挝基普
MMK1042缅甸元
MNT4962蒙古图格里克
KZT3982哈萨克坚戈
BRL9862巴西雷亚尔
MXN4842墨西哥比索
ARS0322阿根廷比索
COP1702哥伦比亚比索
PEN6042秘鲁索尔
UYU8582乌拉圭比索
ALL0082阿尔巴尼亚列克
DZD0122阿尔及利亚第纳尔
BSD0442巴哈马元
AMD0512亚美尼亚德拉姆
BBD0522巴巴多斯元
BMD0602百慕大元
BTN0642不丹努尔特鲁姆
BOB0682玻利维亚诺
BWP0722博茨瓦纳普拉
BZD0842伯利兹元
SBD0902所罗门群岛元
CVE1322佛得角埃斯库多
KYD1362开曼群岛元
CRC1882哥斯达黎加科朗
CUP1922古巴比索
DOP2142多米尼加比索
ETB2302埃塞俄比亚比尔
FKP2382福克兰群岛镑
GMD2702冈比亚达拉西
GIP2922直布罗陀镑
GTQ3202危地马拉格查尔
GYD3282圭亚那元
HTG3322海地古德
HNL3402洪都拉斯伦皮拉
IRR3642伊朗里亚尔
JMD3882牙买加元
KGS4172吉尔吉斯斯坦索姆
LBP4222黎巴嫩镑
LSL4262莱索托洛蒂
LRD4302利比里亚元
MWK4542马拉维克瓦查
MVR4622马尔代夫拉菲亚
MUR4802毛里求斯卢比
MDL4982摩尔多瓦列伊
MAD5042摩洛哥迪拉姆
NAD5162纳米比亚元
AWG5332阿鲁巴弗罗林
NIO5582尼加拉瓜科多巴
PAB5902巴拿马巴波亚
PGK5982巴布亚新几内亚基那
SHP6542圣赫勒拿镑
SCR6902塞舌尔卢比
SOS7062索马里先令
SZL7482斯威士兰里兰吉尼
SYP7602叙利亚镑
TOP7762汤加潘加
TTD7802特立尼达和多巴哥元
MKD8072北马其顿代纳尔
TZS8342坦桑尼亚先令
UZS8602乌兹别克斯坦苏姆
WST8822萨摩亚塔拉
YER8862也门里亚尔
SLE9252塞拉利昂利昂
VES9282委内瑞拉玻利瓦尔
MRU9292毛里塔尼亚乌吉亚
STN9302圣多美和普林西比多布拉
BYN9332白俄罗斯卢布
TMT9342土库曼斯坦马纳特
GHS9362加纳塞地
RSD9412塞尔维亚第纳尔
MZN9432莫桑比克梅蒂卡尔
AZN9442阿塞拜疆马纳特
XCD9512东加勒比元
ZMW9672赞比亚克瓦查
SRD9682苏里南元
MGA9692马达加斯加阿里亚里
AFN9712阿富汗尼
TJS9722塔吉克斯坦索莫尼
AOA9732安哥拉宽扎
CDF9762刚果法郎
BAM9772波黑可兑换马克
GEL9812格鲁吉亚拉里
BND0962文莱元
FJD2422斐济元
KPW4082朝鲜元
SDG9382苏丹镑
实际金额:

两个最容易搞错的地方

第一,DE49 放的是数字码。报文里写的是 392 不是 JPY,是 840 不是 USD。做内部系统映射时把两者搞混,会导致币种识别错误,而这种错误往往要到对账才暴露。

第二,金额是最小货币单位的整数。报文里的 DE4 没有小数点,000000012345 是多少取决于币种:美元是 123.45,日元是 12345,科威特第纳尔是 12.345。

最常见的资金 bug:金额 × 100 写死。一笔 5,000 日元这么发出去,字段里是 500000,而日元零小数位——那就是 50 万日元,多了整整 100 倍,而且它会正常授权通过。反方向同样糟:科威特第纳尔除以 100,会少收 10 倍。两种错都是静默的,不报错、不触发校验,只有对账时才发现。

正确的做法

维护一张「币种 → 小数位」的表,所有换算都走这张表,不要让字面量 100 出现在任何金额附近。上面的换算器可以用来核对你的实现算得对不对。

不只是 DE4

DE5(结算金额)、DE6(持卡人入账金额)以及 EMV 的 9F02 标签都遵循同一规则。而且跨境交易里,这三个金额的币种可能各不相同——分别看 DE49、DE50、DE51,别默认它们一致。


真正出事的是小数位

ISO 8583 的金额域不带小数点。那个数字是「最小货币单位」的整数,而多少个最小单位等于一个单位 是由币种决定的,不是由报文决定的。默认到处都是两位小数,你会在两个方向上都出错。

日元的小数位是 0:一笔日元交易里的 000000001000 是 1000 日元,不是 10.00。 科威特第纳尔、巴林第纳尔、约旦第纳尔的小数位是 3:同样这串数字是 1.000 第纳尔。 一个写死的除以 100,会把一千日元的咖啡变成十日元,把一第纳尔的车费变成一千第纳尔 —— 而这两种错在日志里都不像错。

还有两个上面那张表显示不出来的坑。数字码和字母码是独立分配的,所以不能从一个推出另一个, 也不能按一个排序然后指望另一个跟着有序。以及 ISO 4217 里有卡组织压根不支持的码 —— 包括资金码和贵金属码 —— 所以「是合法的 ISO 币种码」和「能路由」不是一回事。 这套算术连带算例在金额与最小货币单位

公司网络打不开本站?本表和另外 13 个工具也提供可从本地磁盘直接运行的 HTML 文件,完全不连网络 —— 给那些访问不到本站的机器用。离线版,US$39 一次性买断。