1、 . . . . . 银联商务自助终端收银系统Windows标准接口文档V3.3.0 银联商务技术开发中心MIS室 版本控制信息 版本 日期 拟稿和修改人 说明 1.0.0 2014-08-26 王玉珏 创建 2.0.0 2014-10-30 王玉珏 修改交易编号 增加全民付48域组织说明 3.0.0 2014-12-03 王玉珏 增加对传统业务IC卡的支持 3.1.0 2015-01-16
2、 王玉珏 增加对增值业务手机充值、信用卡还款IC卡的支持 3.2.0 2015-03-05 王玉珏 增加对外挂非接模块R50、R30的支持 3.3.0 2015-04-25 王玉珏 增加关闭读卡器函数、吞卡函数 3.3.0 2015-04-29 王玉珏 增加传统交易必填要素表 本文档中的所有容为中国银联商务的和专属所有。未经中国银联商务的明确书面许可,任何组织或个人不得以任何目的、任何形式与任何手段复制或传播本文档局部或全部容。 1 文档说明 本文档向收银软件开发商描述了
3、银联商务windows版本自助收银系统的接口和调用流程。此版本采用插卡器实现IC、磁条卡联机,采用外挂式非接模块〔R50、R30〕实现闪付交易〔目前只在传统应用支持闪付类的消费和查余交易〕。 2 函数调用流程 1) 调用初始化函数UMS_Init(appType),初始化应用类型根据所要进展的业务类型取值。 2) 调用进卡函数UMS_EnterCard(),系统根据配置设置读卡器为可插、挥卡状态。此函数同时尝试开启插卡器和外挂非接感应器,并返回设备开启情况。 3) 根据第2步返回结果,提示用户插、挥卡。 4) 调用检测卡函数UMS_CheckCard (byte *state_out
4、),判断读卡器或者非接感应器上是否有卡。如果有卡那么关闭另一个设备。并以返回值返回采用了哪个设备。〔此过程会阻滞约2秒钟时间〕建议循环调用,直至检测卡超时时间到来。 5) 当检测到卡片插入或在非接模块感应区之后,调用读卡函数UMS_ReadCard (char *cpData),此时会返回给ERP用户卡号。此函数会检测卡片类型,产生阻滞。 6) 对于联机交易,读卡成功后,调用打开密码键盘函数UMS_StartPin()。 7) 提示用户输入密码。 8) 调用取键值函数UMS_GetOnePass (unsigned char *key_out),根据具体的键值绘制密码输入画面。 9)
5、 密码输入完毕后,调用取用户密码密文函数UMS_GetPin ()。 10) 调用交易函数UMS_TransCard (char *strReq, char *strResp)进展交易。如果该交易函数是无磁无密函数,那么跳过2~9步。对于闪付类交易,跳过6~9步。 11) 调用关闭读卡器函数UMS_EjectCard (),弹出卡片〔关闭非接模块〕,并提示用户拔卡、取走卡片。〔假设为磁条卡,也可以在第5步之后弹出卡片,防止持卡人忘记取卡。假设为闪付交易,请让持卡人在交易过程中保持卡片在非接感应器上,不可以中途移走卡片。〕 12) 继续循环调用UMS_CheckCard (byte *st
6、ate_out),判断持卡人是否真正拿走了卡片。 13) 如持卡人在时限未拿走卡片,调用吞卡函数UMS_CardSwallow(),将卡片没收。 14) 调用关闭读卡器函数UMS_CardClose()。 3 函数说明 所有函数都封装在umsapi.dll里。使用前请先加载此动态库。也可以采用头文件加lib库的形式静态加载。发布文件请仅仅放置于c:\umsips文件夹目录下。 3.1 初始化 int UMS_Init(int appType); 功能描述:初始化密码键盘、检查冲正、检查签到结算、下公钥、下公参、检查设备能力、脱机交易上送、TC上送。 参数:apptype:应用类
7、型 1:传统银行卡应用 2:全民付应用 3:预付卡。不同应用支持的交易类型,见本章3.11节。 返回: 0:成功 其他情况: -101:appType非法 -102:加载主配置main.ini失败 -103:初始化密码键盘失败 -104:银联卡模块初始化失败 -105:增值模块初始化失败 -106:预付卡模块初始化失败 -107:暂不支持的appType -108:向EMV核下载IC卡参数失败 3.2 进卡 int __stdcall UMS_EnterCard() 功能描述:允许读卡器进卡,调用成功后,提示用户插卡。 参数:无。 返回: 0:插卡器启
8、动成功,外挂非接模块无法打开; 1:外挂非接模块启动成功,插卡器无法打开; 2:外挂非接模块、插卡器均启动成功; -201~-210:失败。 3.3 检测卡 int __stdcall UMS_CheckCard(byte *state_out) 功能描述:返回读卡器卡片位置,可循环调用,建议1秒为周期。 参数:state_out:卡片信息码 位置码 含义 说明 0x34 卡在插卡器卡口位置 可提示用户插、拔卡 0x35 未检测到卡 可提示用户插卡、挥卡 0x37 插卡器部有卡 可以读卡 0x38 卡在外置非接感应器上 可以读卡 返回:
9、0:成功; -211~-220:失败。 3.4 读卡 int __stdcall UMS_ReadCard(char* cpData); 功能描述:读卡号、选择扣款账户。传统应用返回屏蔽〔除前六后四位之外,其他用*代替〕后的卡号,闪付类交易返回全卡号,全民付应用返回全卡号。 出参: cpData 卡号存储指针 返回: 0:磁条卡读取成功; 1:芯片卡读取成功; 2:非接卡读取成功; -221~-230:失败; 3.5 弹卡 int __stdcall UMS_EjectCard() 功能描述:把卡弹出到读卡器口。IC卡交易,请在交易完毕后,再弹卡。 参数:无
10、返回: 0:成功; -231~-240:失败 3.6 关闭读卡器 int __stdcall UMS_CardClose() 功能描述:关闭设备。当部有卡时,卡片将从卡口弹出。 参数:无 返回: 0 成功 其他 失败 3.7 吞卡 int __stdcall UMS_CardSwallow() 功能描述:当卡片停留在卡口或者在部时,从读卡器后部将卡片弹出。 参数:无 返回: 0 成功 其他 失败 3.8 开启密码键盘 int __stdcall UMS_StartPin() 假设为电子现金账户扣款,无需次步骤。 返回: 0 成功其他 失败 3.
11、9 获得键值 int __stdcall UMS_GetOnePass(byte* key_out) 假设为电子现金账户扣款,无需次步骤。 键值 含义 0x02 输入超时 0x08 退格 0x2A 一个按键 0x1B 用户取消交易 0x0D 输入确认 0xFF 用户暂时没有输入 返回: 0 成功 其他 失败 3.10 获取pin密文 int __stdcall UMS_GetPin() 假设为闪付类交易,无需次步骤。 返回: 0 成功 其他 失败 3.11 交易函数 int __stdcall UMS_TransCard(char* str
12、Req,char* strResp) 功能描述:自助终端交易函数。增值交易的strMemo字段需按照第四章所做说明填充。 参数: char* strReq:传入参数,格式如下: 字段名称 字段长度〔BYTE〕 字段含义 strCounterId 8 款台号 strOperId 8 操作员号 strTransType 2 交易编号 传统类交易:00:消费 01:撤销 02:退货03:查余 04:结算*05:签到*08:预授权 09:预授权撤销 10:预授权完成 全民付交易:01:手机充值 02:信用卡还款手续费查询* 03:信用卡还款缴费 04:卡卡转账
13、 05:公共事业查询* 06:公共事业缴费 预付卡:00 消费 strAmount 12 金额 strOldTrace 6 原流水号 strOldDate 8 原交易日期YYYYMMDD strOldRef 12 原系统参考号 strOldAuth 6 原授权号 strOldBatch 6 原批次号 strMemo 1024 48域附加信息〔采用第4章所述格式传入〕 strLrc 3 3个校验字符 请求中带*的为无磁无密交易。 char* strResp:返回参数,格式如下: 字段名称 字段长度〔BYTE〕 字段含义 strRe
14、spCode 2 应答码 strRespInfo 40 应答码说明信息〔汉字〕 strCardNo 20 交易卡号 strAmount 12 金额 strTrace 6 终端流水号〔凭证号〕 strBatch 6 批次号 strTransDate 4 交易日期MMDD strTransTime 6 交易时间hhmmss strRef 12 系统参考号〔中心流水号〕 strAuth 6 授权号 strMId 15 商户号 strTId 8 终端号 strMemo 1024 48域附加信息〔采用第4章所述格式传出〕 st
15、rLrc 3 3个校验字符 返回:该函数只返回0 注意:对于无磁无密的交易,初始化成功后,直接调用交易函数 应答码的具体中文说明,在程序包的rsp.ini中 3.11.1 传统交易必填要素表 交易名称 交易号 款台号 操作员号 金额 原流水号 原交易日期 原系统参考号 原授权号 原批次号 Memo LRC 00消费 √ ○ ○ √ □ □ □ □ □ □ ○ 01撤销 √ ○ ○ √ √ □ □ □ □ □ ○ 02退货 √ ○ ○ √ □ √ √ □ □ □ ○ 03查余 √
16、 ○ ○ □ □ □ □ □ □ □ ○ 04结算 √ ○ √ □ □ □ □ □ □ □ ○ 05签到 √ □ □ □ □ □ □ □ □ □ ○ 08预授权 √ ○ ○ √ □ □ □ □ □ □ ○ 09预授权撤销 √ ○ ○ √ □ √ □ √ □ □ ○ 10预授权完成 √ ○ ○ √ □ √ □ √ □ □ ○ ○:可随意填的字段,该字段会被打印或被校验 □:采用空格填充,此字段在该交易中无意义 √:必须填入实际值的字段 3.11.2 对
17、于信用卡还款、卡卡转账交易的流程说明 首先,初始化。然后获得信用卡或者转入卡的卡号。可以通过3.2~3.7函数来实现。然后再次读取转出卡。启动密码键盘,输入密码,调用交易函数。最后,弹卡,并判断卡片是否被取走。如未取走,吞卡。 4 全民付交易48域组织说明 4.1 数据格式 ERP传入48域数据在入参字段strMemo中,采用通常意义上的TLV〔tag-length-value〕格式,即每个子域由tag标签(T),子域取值的长度(L)和子域取值(V)构成。 tag标签的属性为bit,由16进制表示,占1~2个字节长度。例如,“9F33〞为一个占用两个字节的tag标签。而“95〞为一个
18、占用一个字节的tag标签。假设tag标签的第一个字节〔注:字节排序方向为从左往右数,第一个字节即为最左边的字节。bit排序规那么同理。〕的后四个bit为“1111〞,那么说明该tag占两个字节,例如“9F33〞;否那么占一个字节,例如“95〞。 子域长度〔即L本身〕的属性也为bit,占1~3个字节长度。具体编码规那么如下: a) 当L字段最左边字节的最左bit位〔即bit8〕为0,表示该L字段占一个字节,它的后续7个bit位〔即bit7~bit1〕表示子域取值的长度,采用二进制数表示子域取值长度的十进制数。例如,某个域取值占3个字节,那么其子域取值长度表示为“00000011〞。所以,假
19、设子域取值的长度在1~127字节之间,那么该L字段本身仅占一个字节。 b) 当L字段最左边字节的最左bit位〔即bit8〕为1,表示该L字段不止占一个字节,那么它到底占几个字节由该最左字节的后续7个bit位〔即bit7~bit1〕的十进制取值表示。例如,假设最左字节为10000010,表示L字段除该字节外,后面还有两个字节。其后续字节的十进制取值表示子域取值的长度。例如,假设L字段为“1000 0001 1111 1111〞,表示该子域取值占255个字节。所以,假设子域取值的长度在127~255字节之间,那么该L字段本身需占两个字节。 4.2 数据限制 本程序中使用的TLV数据除符合上
20、述TLV规那么以外,还符合下面的条件约束: 1:所有tag都是2个字节的。 2:L的长度不超过3字节。即一个子域最大数据长度为FFFF〔65535〕字节。 3:TLV数据段起始指针为strMemo+4。前面的四个字节为从strMemo+4开始的TLV数据总长度,采用AscII码标示〔左对齐,右补空格〕。 4.3 相关函数列表 为了方便厂商打TLV数据,在umsapi.dll中提供了一些工具函数供打TLV数据使用。 4.3.1 初始化TLV int __stdcall Tlv_Init(byte* bpInBuf, int iInBufLen) 功能说明: 初始化TLV
21、指针和总长度。在每一次打TLV数据前,都需要调用此函数,初始化。 只有初始化成功后,方可调用Tlv_AddTag。否那么会引起异常。 参数: byte* bpInBuf:外局部配的存储TLV数据的空间首地址 int iInBufLen:外局部配的存储TLV数据空间的大小 返回: 0:成功 -1:外局部配空间不可以小于4字节 4.3.2 增加一个tag int __stdcall Tlv_AddTag(char* cpInTagNameAsc, char* cpInData, int iInDataLen) 功能描述: 打一个tag 参数: char* c
22、pInTagNameAsc: AscII码标示的tag名 char* cpInData:数据首地址 int iInDataLen:数据长度 例子: 要在sbuf中打tag为"9F36"的数据"123456" byte sbuf[512] Tlv_Init(sbuf,512) Tlv_AddTag("9F36","123456",6); 返回: 大于0 成功,当前TLV的总长度 -1 外部越界 -2 部越界 -3 tag重复 -4 总长度超过可表示围 4.3.3 解出指定tag的数据 int __stdcall Tlv_GetTag(char* cpInT
23、lvData, char* cpInTagAsc,char* cpOutData); 功能描述: 解出指定tag的数据 参数: char* cpInTlvData 长度+TLV数据〔前4个字节为AscII码表示的后面TLV数据的总长度〕 char* cpInTagAsc 采用AscII码表示的tag char* cpOutData 取得的数据 返回: 大于0 成功,所获得的数据长度 -1 未找到所要tag 例子: iRet = Tlv_AddTag("9F36","123456",6); iRet = Tlv_AddTag("9F37","11",2)
24、 //此时数据为"\x31\x34\x20\x20\x9F\x36\x06\x31\x32\x33\x34\x35\x36\x9F\x37\x02\x31\x31" Tlv_GetTag((char*)sbuf,"9F37",sbuf2);//此时sbuf2为"11" Tlv_GetTag((char*)sbuf,"9F36",sbuf2);//此时sbuf2为"123456" 4.3.4 将TLV数据转换成可见AscII字符 int __stdcall Tlv_GetAscData(const char* cpInDataTLV, char* cpOutDataAs
25、c) 参数: const char* cpInDataTLV:传入TLV数据指针 char* cpOutDataAsc:返回AscII字符数据指针 返回: 该函数只返回0 例子: char BufTlv[MEMOLEN]; char BufAsc[MEMOLEN*2+1]; iRet= Tlv_Init(BufTlv,MEMOLEN); iRet = Tlv_AddTag("9F36","123",3); Tlv_GetAscData(BufTlv,BufAsc); //此时BufAsc里面为"362020209F3603313233" 注意:
26、此函数执行前无需外部清cpOutDataAsc 4.4 增值交易必须传入的tag 交易类型 必须传入的tag 需要获得的返回数据 手机充值 手机〔0F12〕、运营商类别〔0F13〕 信用卡还款查询 信用卡卡号〔0F14〕、手机〔0F12〕 手续费〔0F15〕、提示信息〔0F17〕 信用卡还款缴费 信用卡卡号〔0F14〕、手机〔0F12〕 卡卡转账 转入账户〔0F16〕 公共事业查询 地区码〔0F1A〕、出账机构代码〔0F1B〕、条码号〔或者账单号、户号〕〔0F1C〕、出账机构特殊需要的域〔0F19〕、手机〔可选〕〔0F12〕 总金额〔0F0D〕、账期
27、〔0F18〕、出账机构特殊需要的域〔0F19〕 公共事业缴费 无 订单号〔0F1E〕 交警罚没款账单查询 处罚书号〔0F00〕、处罚书类型〔0F01〕、交警校验码〔0F02〕 操作结果信息〔0F03〕、当事人〔0F04〕、执行单位编码〔0F05〕、执行单位名称〔0F06〕、缴费状态〔0F07〕、处罚日期〔0F08〕、车牌〔0F09〕、处理机关名称〔0F0A〕、罚款金额〔0F0B〕、滞纳金〔0F0C〕、总金额〔0F0D〕、查询新一代流水号〔0F0E〕 交警罚没款缴费 查询新一代流水号〔0F0E〕 操作结果信息〔0F03〕、业务流水号〔0F10〕、校验码〔0F11〕、销账新一代流
28、水号〔0F0E〕 4.5 要素Tag列表 字段名 Tag 最大长度 说明 来源 处罚书号 0F00 40 财政非税〔交警罚没〕终端接口V1.4.1.doc 处罚书类型 0F01 1 1=简易处罚决定书,2=行政处罚决定书 同上 交警校验码 0F02 1 校验码为一位字符,如果断定书上还没有的,就置为字符〞0〞。 同上 操作结果信息 0F03 30 保存使用 同上 当事人 0F04 10 同上 执行单位编码 0F05 10 同上 执行单位名称 0F06 30 同上 缴费状态 0F07 1 1
29、已缴)0(未缴) 同上 处罚日期 0F08 20 同上 车牌 0F09 20 同上 处理机关名称 0F0A 20 同上 罚款金额 0F0B 20 同上 滞纳金 0F0C 20 同上 总金额 0F0D 20 同上 新一代流水号 0F0E 12 银商新一代流水号 同上 透传标志 0F0F 1 0代表透传,无需校验消费信息〔非新一代平台〕,1表示验证缴费〔新一代〕 同上 业务流水号 0F10 30 同上 校验码 0F11 30 缴费确认校验码,来自第三方。仅用于显示。 同上 手机
30、 0F12 20 左对齐,右补空格 运营商类别 0F13 2位固定长度 01—移动; 02—联通; 03—电信; 信用卡卡号 0F14 20 左对齐,右补空格 手续费 0F15 12 右对齐,左补空格,分为单位 转入账户卡号 0F16 20 左对齐,右补空格 终端提示信息 0F17 100 左对齐,右补空格 账期 0F18 6 便民终端接口-公用事业缴费局部V1.7.doc 出账机构特殊需要的域 0F19 100 缴费的时候原样上送 同上 地区码 0F1A 4 所属地区的区号,不满四位的左补0 出账机构代码 0F1B 15 参考《CP便民缴费渠道与缴费项目明细表.xls》 条码号〔或者账单号、户号〕 0F1C 50 请求上送 支付日期 0F1D 8 YYYYMMDD 订单号 0F1E 20 12 / 12