它是一份关于银行卡交易报文的国际标准。它描述的不是网络、不是接口、也不是产品,而是「字节该怎么排」——好让两个从没打过交道的系统,对同一条支付请求的含义达成一致。这也是一份 1987 年的标准至今还承载着全世界大部分卡交易的原因:格式活得比所有建在它上面的技术都长。
它有 1987、1993、2003 三个版本,你最可能遇到的还是 1987 版。版本之间的差别在于有哪些域、某些域多宽,所以版本不是无关紧要的细节:同样的字节在两个版本下可以解出不同结果。MTI 的第一位就告诉你这是哪一版。
几乎没人跑纯粹的 ISO 8583。Visa、Mastercard、各国本地转接机构都有自己的一套:域号相同,但私有域各填各的、各自还有额外的码值,有时字符编码也不一样。标准给的是信封,卡组织的规范才告诉你信里写了什么。两者说法不一致时,以你手上那份接口规范为准。
从左往右分三段读。
每一位各管一件事:
| 位置 | 含义 | 取值举例 |
|---|---|---|
第 1 位 | 版本 | 0 = 1987、1 = 1993、2 = 2003 |
第 2 位 | 报文类别 | 1 授权、2 金融、4 冲正、8 网络管理 |
第 3 位 | 报文功能 | 0 请求、1 响应、2 通知、3 通知响应 |
第 4 位 | 报文来源 | 0 收单方、2 发卡行、1/3 同上但是重发 |
所以 0100 是 1987 版、收单方发出的授权请求,0110 是它的响应。0400 是冲正请求,0800 是签到、心跳这类网络管理报文。把四位分开读,比背一张 MTI 清单快得多。
位图是 64 个二进制位,通常写成 16 个十六进制字符。第 n 位是 1,就表示第 n 个数据域出现了,按域号从小到大排列;没出现的域就是真的不在报文里,不补位、不留占位符。这就是这个格式的诀窍:不需要额外的结构说明也能很紧凑,因为位图本身就是结构说明。
第 1 位是特殊的:它不表示 DE1,而表示后面还跟着第二个位图,把范围扩到 DE128。第 1 位是 0 的话,报文到 DE64 就结束,位图也只有 16 个十六进制字符。
位图相关的问题大多出自两个地方:从 0 开始数位,以及忘了位图可能是 8 个原始字节而不是 16 个十六进制字符。两种情况都会让后面的域整体错开一位。
每个域要么是定长,要么自己带长度前缀:
| 类型 | 前缀 | 怎么读 |
|---|---|---|
FIX | 没有 | 取正好声明的那么多个字符。DE4 永远是 12 位。 |
LLVAR | 2 位 | 先读两位当长度,再取那么多个字符。那两位不属于值本身。 |
LLLVAR | 3 位 | 同理,长度占三位。用在可能超过 99 个字符的域上,比如 DE55。 |
声明的长度算的是值的字符数,而不总是字节数:Hex/BCD 下两个数字压进一个字节,而二进制域的长度按字节还是按位算,取决于具体规范。解析器出现「一个域一个域地往后错」时,先查长度的单位。
下面是一条完整的授权请求,用的是测试卡号和占位终端号,不含任何真实持卡人数据。
010072200000008080001641111111111111110000000000000010000821143000123456TERM0001702
从左往右拆开:
| 字节 | 域 | 读出来是什么 |
|---|---|---|
0100 | MTI | 1987 版、授权、请求、来自收单方 |
7220000000808000 | 位图 | 第 2、3、4、7、11、41、49 位是 1——这七个域按此顺序跟在后面。第 1 位是 0,所以没有第二个位图。 |
16 4111111111111111 | DE2 卡号 | LLVAR:16 是长度,后面 16 位才是卡号 |
000000 | DE3 处理码 | 消费,付方和收方账户都未指定 |
000000001000 | DE4 金额 | 1000 个最小货币单位。结合 DE49 = 702(新加坡元,两位小数)就是 10.00 新元 |
0821143000 | DE7 传输时间 | 8 月 21 日 14:30:00 GMT。域里不带年份。 |
123456 | DE11 系统跟踪号 | 收单方当天用的流水号 |
TERM0001 | DE41 终端号 | 只在这个商户内部唯一,不是全局唯一 |
702 | DE49 币种 | 新加坡元的 ISO 4217 数字码 |
注意:DE49 没读之前,DE4 是没有含义的。先币种、后金额这个顺序,是金额差出一百倍最常见的来源。
上面这条报文可以直接粘进首页的解析器,看它逐域拆开。
一共有 128 个数据域,但实际工作中的问题几乎都集中在这十来个上:
| 域 | 名称 | 为什么总被问到 |
|---|---|---|
DE2 | 卡号 | 前 6–8 位决定路由给哪家发卡行;日志里一律掩码。 |
DE3 | 处理码 | 是消费还是取现,决定计价、额度和利息。 |
DE4 | 交易金额 | 最小货币单位、无小数点。不看 DE49 就没有含义。 |
DE11 | 系统跟踪号 | 只在当天、只在该收单方范围内唯一,会回绕重用。 |
DE22 | 输入方式 | 卡是怎么读进来的,牵涉责任划分。 |
DE37 | 检索参考号 | 整个交易生命周期不变,对账时实际可用的关联键。 |
DE39 | 响应码 | 00 是成功,其余都是原因。 |
DE41/DE42 | 终端号 / 商户号 | 交易发生在哪,也是持卡人发起争议时针对的对象。 |
DE49 | 币种 | 决定 DE4 的小数位。要先读它。 |
DE55 | 芯片数据 | TLV 格式的芯片数据——芯片交易被拒的原因就在这里面。 |
域字典里有全部 128 个域的长度、格式和说明。
ISO 8583 的工作大部分不是解析报文,而是查某个值是什么意思。值得存下来的几张表:
有四个地方,标准到此为止、接下来得看别人的文档。每一个都让人花过一整周。
在用,而且全世界绝大部分卡授权流量都走它。ISO 20022 在账户间转账和实时支付上增长很快,一些卡组织也在迁移,但卡这条线上跑的还是 8583,未来若干年也还会是。两者是并存关系,不是谁取代了谁。
8583 是按位置排布的紧凑字节,是为 1980 年代的线路设计的;20022 是 XML 或 JSON,数据模型丰富得多。8583 用少得多的字节表达少一些的信息,这正是它能在对时延敏感的卡组织网络上活下来的原因。它们是两种格式做部分重叠的事,不是同一个东西的两个版本。
基础结构——MTI、位图、域号、长度——不需要,这部分公开资料很充分,本站也讲了。但你的报文里真正出现的那些私有域和额外码值,得拿到你所在卡组织或处理机构的规范。那部分不公开,也推不出来。
基本上都是长度单位或者编码问题:二进制域的长度按字节给、却当成字符读;Hex/BCD 的域被当成 ASCII 读;或者位图发的是 8 个原始字节、却按 16 个十六进制字符读。找到最后一个解对的域,查它的长度规则。