最初,金融系统只有IBM这些大公司来提供设备,象各种主机与终端等,后来有很多大大小小的公司进入,怎样设计一个报文协议,解决各公司金融系统之间的报文交换,暂且称该协议叫做ISO8583协议。例如‘回头客会员管理系统’POS机上应用的就是8583报文。
金融行业涉及到的数据内容是比较少的,如交易类型、帐号、帐户类型、密码、交易金额、交易手续费、日期时间、商户代码、2磁3磁数据、交易序列号等,都总结起来不过100个左右的数据。我们可以简单的设计ISO8583,定义128个字段,将所有金融数据字段按照顺序排列,分别对应128个字段。每个数据类型占固定的长度,要发送一个报文时,就将128个字段按照顺序连起来,然后将整串数据包发送出去。
任何金融软件收到ISO8583包后,直接按照我们定义的规范解包即可,因为整个报文的128个字段都预先定义好了。比如第1个字段是“交易类型”,长度为4位,第2个字段位是“帐号”,为19位等等。接收方就可以先取4位,再取接着的19位,依次类推,直到整个数据包128个字段都解完为止。
不过我们有几个问题要思考下:
1、 我怎么知道每个字段的数据类型呢,是数字还是字符?
2、 每个传送的报文都把128个字段都传过去,有时候我可能只需要其中5个字段。
3、 如果我某些字段的长度不固定,属于变长怎么办。
第一个问题。我在定义ISO8583时除了定义每个字段表示什么,还规定其内容是数字或是字符等类型。可能出现的类型有以下几种:字母、数字、特殊字符、年月日等时间、二进制数据。比如“商户类型”字段定义其长度是15,类型为字母。如果“商户类型”同时包括数字和字母呢?那我们就定义一个字段可以同时属于多个类型。
第二个问题。其本质就是如果我只传128个字段的5个字段,接收方怎么知道我传了哪几个字段。我在报文前面加上个包头,用16个字节,即128个bit来表示128个字段中的某个字段是否存在。每个bit如果是1就表示对应的字段在本次报文中存在,如果是0就是不存在。比如,我要发送5个字段,分别属于128个字段中的第2、3、6、8、9字段,我就可以将128bit的报文头填成011001011000000000………0。
我们把这16个字节称为bit map,即位图,用来表示某个位是否存在。考虑到很多时候报文不需要128个字段,可以将报文头由128bit减到64bit,把ISO8583的128个字段中最常见的都放到前64个字段中,只有在需要的时候才把剩下的64bit放到报文里面?
我把64bit报文头的第一位bit用来代表特殊含义,如果该bit为1,则表示64bit后面跟了剩下的64bit报文头;如果第一位bit为0,则表示64bit后面直接是数据字段内容。因为报文头第二个64bit属于有时候有,所以我们叫它Extended bit map扩展位图,报文头最开始的64bit我们叫它Primary bit map主位图。我们直接把扩展位图固定放到128个字段的第一个字段,而主位图每个数据包都有,就强制性放在所有128个字段的前面。
第三个问题。比如第2个字段是“帐号”,是不定长的,可能有的银行帐号是19位,有的是17位等,在字段的开头加上“帐号”的长度。比如帐号是0123456789,一共10位,我们变成100123456789,接收方收到该字段后,它知道ISO8583规定第2个字段“帐号”是变长的,会先取前面2位出来,然后根据长度获取帐号。在规范里面定义某个字段的属性是“LLVAR”,其中LL表示长度,VAR表示数据,两个LL表示两位长,最大是99,三位就是“LLLVAR”,最大是999。
另外考虑到有些人有特殊的要求,我们将128个字段中的部分定义为自定义字段,算是一种扩展。
typedef struct ISO8583
{
int bit_flag; /*域数据类型0 -- string, 1 -- int, 2 -- binary*/
char *data_name; /*域名*/
int length; /*数据域长度*/
int length_in_byte;/*实际长度(如果是变长)*/
int variable_flag; /*是否变长标志0:否 2:2位变长, 3:3位变长*/
int datatyp; /*0 -- string, 1 -- int, 2 -- binary*/
char *data; /*存放具体值*/
int attribute; /*保留*/
} ISO8583;
ISO8583 Tbl8583[128] =
{
/* FLD 1 */ {0,"BIT MAP,EXTENDED ", 8, 0, 0, 2, NULL,0},
/* FLD 2 */ {0,"PRIMARY ACCOUNT NUMBER ", 22, 0, 2, 0, NULL,0},
/* FLD 3 */ {0,"PROCESSING CODE ", 6, 0, 0, 0, NULL,0},
/* FLD 4 */ {0,"AMOUNT, TRANSACTION ", 12, 0, 0, 1, NULL,0},
/* FLD 5 */ {0,"NO USE ", 12, 0, 0, 0, NULL,0},
/* FLD 6 */ {0,"NO USE ", 12, 0, 0, 0, NULL,0},
/* FLD 7 */ {0,"TRANSACTION DATE AND TIME ", 10, 0, 0, 0, NULL,0},
/* FLD 8 */ {0,"NO USE ", 8, 0, 0, 0, NULL,0},
/* FLD 9 */ {0,"NO USE ", 8, 0, 0, 0, NULL,0},
/* FLD 10 */ {0,"NO USE ", 8, 0, 0, 0, NULL,0},
/* FLD 11 */ {0,"SYSTEM TRACE AUDIT NUMBER ", 6, 0, 0, 1, NULL,0},
/* FLD 12 */ {0,"TIME, LOCAL TRANSACTION ", 6, 0, 0, 0, NULL,0},
/* FLD 13 */ {0,"DATE, LOCAL TRANSACTION ", 4, 0, 0, 0, NULL,0},
/* FLD 14 */ {0,"DATE, EXPIRATION ", 4, 0, 0, 0, NULL,0},
/* FLD 15 */ {0,"DATE, SETTLEMENT ", 4, 0, 0, 0, NULL,0},
/* FLD 16 */ {0,"NO USE ", 4, 0, 0, 0, NULL,0},
/* FLD 17 */ {0,"DATE, CAPTURE ", 4, 0, 0, 0, NULL,0},
/* FLD 18 */ {0,"MERCHANT'S TYPE ", 4, 0, 0, 0, NULL,0},
//省略部分参考规范文档。
/* FLD 123 */ {0,"NEW PIN DATA ", 8, 0, 3, 2, NULL,0},
/* FLD 124 */ {0,"NO USE ",999, 0, 3, 0, NULL,0},
/* FLD 125 */ {0,"NO USE ",999, 0, 3, 0, NULL,0},
/* FLD 126 */ {0,"NO USE ",999, 0, 3, 0, NULL,0},
/* FLD 127 */ {0,"NO USE ",999, 0, 3, 0, NULL,0},
/* FLD 128 */ {0,"MESSAGE AUTHENTICATION CODE FIELD ", 8, 0, 0, 2, NULL,0}
};
如第二域:域名为主帐号,
数据类型为string
长度为22(最长长度不得超过此数)
是个2位变长域
在打包时需在数据域前加上数据的实际长度,如‘19数据值’(即19为长度)
如第三域:域名为处理码,
数据类型为string
长度为6
是个定长域 必须填满6位。
1,信息类型(message type)定义
位图位置:-
格式:定长
类型:N4
描述:
数据包的第一部分,定义数据包的类型。
数据类型由数据包的发起者设定,应遵循以下要求:
数据包开始部分必须是信息类型;
对不支持的信息类型能给出拒绝应答。
0100授权交易
0110授权交易答复
0200金融交易
0210金融交易答复
0240查询交易
0250查询交易答复
0400冲正交易
0410冲正交易答复
0800管理交易
0810管理交易答复
2,位图(Bit Map) - 基本位图和扩展位图
位图位置:1
格式:定长
类型:B16
描述:
如将位图的第一位设为'1',表示使用扩展位图,否则表示只使用基本位图。
如使用某数据域,应在位图中将相应的位设位'1',如使用41域,需将位图的41位设为'1'。
选用条件:如使用65到128域,需设位图域为'1'
3,Bit02主帐号(Primary Account Number )
位图位置:02
格式:变长,LLVAR
类型:N..22
描述:
唯一的确认一个用户交易的基本帐号。
由于银行电子服务系统涉及多个应用系统,而帐号长度最多为22位,故将原标准的19长度改为22位。
Bit03 处理代码 (Processing Code )
位图位置:03
格式:定长
类型:N6
描述:用于描述交易对客户帐户造成何种影响的代码。
处理代码和信息码一起可唯一定义一种交易的类型。
处理代码由以下三部分组成:
位置描述
1-2交易动作码
3-4付出帐户类型,用于借记类,如查询、代收费、转场交易。
5-6收入帐户类型,用于代收费、转帐等。
其中:
ff : 付出帐户
tt: 收入帐户
* 视主机而定
5,Bit04 交易金额 (Amount, Transaction)
位图位置:04
格式:定长
类型:N12
描述:帐户人要求交易的交易金额,不含任何处理和交易费用。
金额的表示和货币代码有关,应能表示相应货币的最小单位。参ISO4217有关货币代码定义。
如“000000000100”用于表示美元,表示1.00元;如用于表示意大利货币,则表示100里拉。
对于查询等交易,应设交易金额为“000000000000”。
6,Bit07交易日期和时间Transmission Date and Time
位图位置:07
格式:定长,MMDDhhmmss
类型:N10
描述:本地交易日期和时间
7,Bit11系统跟踪号(Systems Trace Audit Number)
位图位置:11
格式:定长
类型:N6
描述:终端交易的跟踪号码。
交易发起终端填写,和“交易日期、时间”、信息类型等合在一起可唯一定义某一个终端的唯一一笔交易。即是说,在同一天,对一终端,同一类交易的系统跟踪号应保证不同。系统跟踪号在交易过程中不能修改。使用此域来匹配请求和通知类交易的返回。
应用系统使用此域来检查收到的授权、金融、自动冲正、结算、管理和网管等类交易的应答包是否是其请求包的应答。
系统跟踪号不用于匹配自动冲正交易,也不用于在预授权消费时匹配前面的预授权交易。参90域。
对于银行电子服务系统,其系统跟踪号是交易流水号。
8,Bit12本地交易时间(Time ,Local Transaction)
位图位置:12
格式:定长,hhmmss
类型:N6
描述:交易在终端上发生的时间。
本地交易时间在交易处理过程中不能改变。在自动冲正,存贮转发时,本地交易时间不能改变。
9,Bit13本地交易日期(Date ,Local Transaction)
位图位置:13
格式:定长,MMDD
类型:N4
描述:交易在终端上发生的时间。
本地交易时间不能改变,在自动冲正、存储转发交易时,本地交易时间也不能改变。
10,Bit14有效期(Date ,Expiration)
位图位置:14
格式:定长,YYMM
类型:N4
描述:卡的有效期,年年月月
由于卡类写磁格式不同,收单行可能提不出卡的有效期,授权机构从卡的二磁道中提取卡的有效期。如卡,无二磁道,收单行应要求手工录入卡的有效期。
选用条件:100、200、400等交易如没有2、3磁道时,一定要有此域。
11,Bit15结算日期(Date ,Settlement)
位图位置:15
格式:定长,MMDD
类型:N4
描述:
银行电子服务系统和主机结算的时间,格式月月日日。
结帐日期前发生的交易参加当天结算。
在结算时,结帐日期也用于计算处理、交易费用。
12,Bit17获取日期(Date ,Capture)
位图位置:17
格式:定长,MMDD
类型:N4
描述:从主机获取交易的记帐日期。通常用于主机和商户清算。
13,Bit18商户类型(Merchant's Type)
位图位置:18
格式:定长
类型:N4
描述:定义商户产品和服务类型的代码
商户类型用于金融、授权交易,用于指定服务点的类型。它主要有以下用途:
决定预授权交易得到确认的最长时间;
控制合法限额;
为交易授权处理,控制网络操作规则;
欺诈检测;
用于商户分类报表;
交易费用处理。
根据ISO8583标准,应使用相应的国家标准。
商户类型代码表如下:
商户类型代码行业类型说明
4215邮递服务
4511民航
4722旅游
4782过桥费
4789其他运输服务
4614电信服务
5542加油站
5812餐馆
5999购物
6010金融机构-人工现金支付
6011金融机构-自动现金支付
6012金融机构-各类服务
7011酒店、旅馆
7299各类个人服务:洗衣、美容、
7399各类商业服务:停车场、租车、广告、其他服务
7699各类维修服务:维修、洗车、拖车
7996娱乐:电影、剧院、体育、游戏
8099医疗服务
8111法律服务
8999各类专业服务:会计、教育、装修、工程
选用条件:服务点终端发起的交易一定要有此域。
14,Bit22服务点输入方式(Point-of-Service Entry Mode)
位图位置:22
格式:定长
类型:N3
描述:在服务终端上定义PIN和PAN的输入方式。
服务点输入方式包含以下两个方面组合而成:
位置描述
1-2在服务终端上PAN有效期输入方式
3-3在服务终端上PIN的输入方式
PAN的输入方式编码如下:
PAN输入方式描述
00不知
01手工
02读磁卡
03条码扫描仪(BAR)
04光学符号阅读器(OCR)
05集成电路卡(IC卡)
PIN的输入方式编码如下:
PIN输入方式描述
0不知
1终端能接收PIN
2终端不能接收PIN
选用条件:服务点终端发起的交易一定要有此域。
15,Bit25服务点条件代码(Point-of-Service Condition Code)
位图位置:25
格式:定长
类型:N2
描述:定义交易发生的服务点类型
用法说明:下面是CYBERBANK支持的服务点条件代码。
服务点条件代码服务点终端类型
2自动柜员机(ATM)
10银行终端(10)
14POS
20电话银行
16,Bit32收单机构标识码(Acquirer institution Identification)
位图位置:32
格式:LLVAR
类型:N..11
描述:在金融交易中此域表示交易发生的银行机构的标识码
应答数据包必须和请求数据包此域相同。
17,Bit33向前机构标识码(Forwarding Institution Identification Code)
位图位置:33
格式:LLVAR
类型:N..11
描述:在金融交易中此域表示帐户所在的银行机构的标识码
在网管交易800/810中,本域含有交易发起机构的代码。
应答数据包必须和请求数据包此域相同。
18,Bit35二磁道数据(Track 2 Data)
位图位置:35
格式:LLVAR
类型:Z..37
描述:写在卡二磁道的数据。数据组成遵循ISO7811-1985标准,数据中包含域分隔符,但不包含卡启始、结束符、LRC等。
收卡行应检测卡的二磁道是否符合国际标准。
为支持国际交换收单行应将二磁道中的分隔符换为“=”。除此外不能对二磁道数据进行任何修改,如修改PAN的校验字、有效期、服务码等。
19,Bit36三磁道数据(Track 3 Data)
位图位置:36
格式:LLLVAR
类型:Z...104
描述:写在卡三磁道的数据。数据应组成遵循ISO4909标准,数据中包含域分隔符,但不包含卡启始、结束符、LRC等。
注意:长度说明为3位数字长。
20,Bit37检索索引号(Retrieval Reference Number)
位图位置:37
格式:定长
类型:AN12
描述:检索索引号用来在任何时间标识一个金融、授权、自动冲正交易。
检索索引号不要求打印在持卡人的帐单上。它的主要目的是在收单行和授权行之间定义一个数据项用于跟踪和检索交易。授权机构可以将检索索引号打印在客户的对帐单上。
检索索引号由收单行分配。
选用条件:可包含在收单机构的交易请求中。如在交易请求中有,则应答数据中一定应原样返回。
21,Bit38授权码(Authorization Identification)
位图位置:38
格式:定长
类型:AN6
描述:交易授权机构返回的返回代码。
授权码用于在服务点终端上信用卡授权;
授权机构按网络操作规定,可选使用本域。
22,Bit39返回码(Response Code)
位图位置:39
格式:定长
类型:AN2
描述:对一交易定义其处理结果的编码。
返回码用于说明授权机构对金融(授权)交易的处理状态;也用来指明自动冲正交易的冲正原因;还用来指出目标主机已接收到文件修改、结算、管理、网管等交易请求。
返回码应尽可能准确,应尽可能描述清楚所遇到的问题和状态。网络交换主机、收单行主机有可能会按不同的返回码收取不同的交易处理费用,并执行不同的处理过程。
23,Bit41收卡单位终端标识码(Card Acceptor Terminal Identification)
位图位置:41
格式:定长
类型:ANS8
描述:定义在收单单位中定义一个服务终端的标识码,在同一商户中服务终端标识码应唯一。
24,Bit42收卡商户定义码(Card Acceptor Identification Code)
位图位置:42
格式:定长
类型:ANS15
描述:在本地和网络中定义交易单位(商户)的编码。
25,Bit43收卡商户位置(Card Acceptor Location)
位图位置:43
格式:定长
类型:ANS40
描述:在本地和网络中定义收卡单位(商户)的国家、省。城市等。
选用条件:如对外卡网络,一定要包含此域。