工商银行EBank B2C支付接口v1.0.0.11 开发说明

 

 

 

一、支付接口表单定义

新模式接口的交易数据整合到一个xml格式串,作为表单的一项整体提交,不再同原来每个字段都是key-value形式;

FORM表单数据如下:

 

变量名称

变量命名

长度定义

说明

接口名称

interfaceName

MAX(30)

必输,

取值:ICBC_PERBANK_B2C

接口版本号

interfaceVersion

MAX(15)

必输,

取值:“1.0.0.11”

交易数据

tranData

无限制

必输,签名;

整合所有交易数据形成的xml明文串,并做BASE64编码;

具体格式定义见下文;

注意:

需有xml头属性;整个字段使用BASE64编码;

xml明文中没有回车换行和多余空格;

订单签名数据

merSignMsg

无限制

必输,

商户使用工行提供的签名API和商户证书将tranDataxml明文串进行签名,得到二进制签名数据,然后进行BASE64编码后得到可视的merSignMsg

注意:签名时是针对tranDataxml明文,不是将tranData进行BASE64编码后的串;

商城证书公钥

merCert

无限制

必输,

商户用二进制方式读取证书公钥文件后,进行BASE64编码后产生的字符串;

 

注:

1、数据中不能包含“|”“&”“=”,这些字符为银行端程序保留字符;中文变量使用GBK编码。

2、从商户Post过来的数据,参数名的名称必须与上表中完全相同,名称中的字母大小写均要相同,不能进行随意更改(form中的提交按钮<input type="submit"……>submit不能有Name属性);此外,如果其他input 项的Name中使用了双引号,如:<input type=text name=" merCert " value="xxxxxxx">,则一定注意在引号内不要包含空格,不要写成“mer URL ”,如果拼写错误或者多了空格,将造成数据无法识别,无法正常进行支付

3、接口名称和版本号一定要和上表中相同.

4、商户提交数据中的空格将被认为是有效字符被接收,请商户开发时注意对多余空格的控制。

5tranData交易数据的xml串需要有xml的头,即<?xml version="1.0" encoding="GBK"  standalone="no"?>

 

 

tranData数据定义

变量名称

变量命名

长度定义

说明

接口名称

interfaceName

16

必输,

取值:ICBC_PERBANK_B2C

接口版本号

interfaceVersion

MAX(15)

必输,

取值:“1.0.0.11”

交易日期时间

orderDate

=14

必输,

格式为:YYYYMMDDHHmmss

目前要求在银行系统当前时间的前后十分钟范围内,否则判定交易时间非法。

订单号

orderid

MAX(30)

必输,每笔订单都需要有不同的订单号;

客户支付后商户网站产生的一个唯一的定单号,该订单号应该在相当长的时间内不重复。工行通过订单号加订单日期来唯一确认一笔订单的重复性。

订单金额

amount

MAX(10)

必输,每笔订单一个;

客户支付订单的总金额,一笔订单一个,以分为单位。不可以为零,必需符合金额标准。

分期付款期数

installmentTimes

MAX2

必输,每笔订单一个;

取值:13691218241代表全额付款,必须为以上数值,否则订单校验不通过。

商户账号

merAcct

MAX(19)

必输,每笔订单一个,可以相同;

商户入账账号,只能交易时指定。(商户付给银行手续费的账户,可以在开户的时候指定,也可以用交易指定方式;用交易指定方式则使用此商户账号)

商品编号

goodsID

MAX(30)

选输,每笔订单一个;

商品名称

goodsName

MAX(60)

必输,每笔订单一个;

商品数量

goodsNum

MAX(10)

选输,每笔订单一个;

已含运费金额

carriageAmt

MAX(10)

选输,每笔订单一个;

注:银行支付页面不会向客户显示该项内容。

检验联名标志

verifyJoinFlag

=1

 

必输,

取值“1”:客户支付时,网银判断该客户是否与商户联名,是则按上送金额扣帐,否则展现未联名错误;

取值“0”:不检验客户是否与商户联名,按上送金额扣帐。

语言版本

Language

MAX(10)

选输,默认为中文版

取值:“EN_US”为英文版;

取值:“ZH_CN”或其他为中文版。

注意:大小写敏感。

支付币种

curType

= 3

必输,

用来区分一笔支付的币种,目前工行只支持使用人民币(001)支付。

取值: “001”

商户代码

merID

MAX(20)

必输,

唯一确定一个商户的代码,由商户在工行开户时,由工行告知商户。

支持订单支付的银行卡种类

creditType

= 1

必输

默认“2”取值范围为012,其中0表示仅允许使用借记卡支付,1表示仅允许使用信用卡支付,2表示借记卡和信用卡都能对订单进行支付

通知类型

notifyType

= 2

必输

在交易转账处理完成后把交易结果通知商户的处理模式。

取值“HS”:在交易完成后实时将通知信息以HTTP协议POST方式,主动发送给商户,发送地址为商户端随订单数据提交的接收工行支付结果的URL即表单中的merURL字段;

取值“AG”:在交易完成后不通知商户。商户需使用浏览器登录工行的B2C商户服务网站,或者使用工行提供的客户端程序API主动获取通知信息。

结果发送类型

resultType

=1

 

选输

取值“0”:无论支付成功或者失败,银行都向商户发送交易通知信息;

取值“1”,银行只向商户发送交易成功的通知信息。

只有通知方式为HS时此值有效,如果使用AG方式,可不上送此项,但签名数据中必须包含此项,取值可为空。

商户reference

merReference

MAX(200)

选输,上送商户网站域名(支持通配符,例如“*.B2C商城.com”),如果上送,工行会在客户支付订单时,校验商户上送域名与客户跳转工行支付页面之前网站域名的一致性。

客户端IP

merCustomIp

MAX(20)

选输,工行在支付页面显示该信息。使用IPV4格式。当商户reference项送空时,该项必输。

虚拟商品/实物商品标志位

goodsType

=1

选输,若输入:

取值“0”:虚拟商品;

取值“1”,实物商品。

买家用户号

merCustomID

MAX(100)

选输,工行在支付页面显示该信息。

买家联系电话

merCustomPhone

MAX(20)

选输,工行在支付页面显示该信息。

收货地址

goodsAddress

MAX(200)

选输,工行在支付页面显示该信息。

订单备注

merOrderRemark

MAX(200)

选输,工行在支付页面显示该信息。

商城提示

merHint

MAX(120)

选输

备注字段1

remark1

MAX(100)

选输单位:字节

备注字段2

remark2

MAX(100)

选输单位:字节

返回商户URL

merURL

MAX(1024)

必输

必须合法的URL,交易结束,将客户引导到商户的此url,即通过客户浏览器post交易结果信息到商户的此URL

注意:该URL应使用http协议(不能使用https协议),端口号应为80或不指定。

返回商户变量

merVAR

MAX(1024)

选输

商户自定义,当返回银行结果时,作为一个隐藏域变量,商户可以用此变量维护session等等。由客户端浏览器支付完成后提交通知结果时是明文传输,建议商户对此变量使用额外安全防范措施,如签名、base64

 

注:红色字体部分内容,每笔订单都有一份。

 

 

tranData格式定义

tranData格式(xml格式固定,选输字段的取值可以为空,标签需保留)

<?xml version="1.0" encoding="GBK" standalone="no"?>

<B2CReq>

<interfaceName>ICBC_PERBANK_B2C</interfaceName>

<interfaceVersion>1.0.0.11</interfaceVersion>

<orderInfo>

       <orderDate>20100308141629</orderDate>

       <curType>001</curType>

       <merID>0200EC20001119</merID>

       <subOrderInfoList>

       <subOrderInfo>

              <orderid>201003081416290</orderid>

              <amount>1</amount>

              <installmentTimes>1</installmentTimes>

              <merAcct>0200026009018372212</merAcct>

              <goodsID>001</goodsID>

              <goodsName>威尼熊</goodsName>

              <goodsNum>2</goodsNum>

              <carriageAmt>20</carriageAmt>

       </subOrderInfo>

       <subOrderInfo>

              <orderid>201003081416291</orderid>

              <amount>1</amount>

              <installmentTimes>1</installmentTimes>

              <merAcct>0200026009018372212</merAcct>

              <goodsID>001</goodsID>

              <goodsName>威尼熊</goodsName>

              <goodsNum>2</goodsNum>

              <carriageAmt>20</carriageAmt>

       </subOrderInfo>

<subOrderInfo>

    

     </subOrderInfo>

       </subOrderInfoList>

</orderInfo>

<custom>

       <verifyJoinFlag>0</verifyJoinFlag>

       <Language>ZH_CN</Language>

</custom>

<message>

       <creditType>2</creditType>

       <notifyType>AG</notifyType>

       <resultType>1</resultType>

       <merReference>localhost</merReference>

       <merCustomIp>127.0.0.1</merCustomIp>

       <goodsType>1</goodsType>

       <merCustomID>123456</merCustomID>

       <merCustomPhone>13466780886</merCustomPhone>

       <goodsAddress>三里屯</goodsAddress>

       <merOrderRemark>防欺诈接口专用</merOrderRemark>

       <merHint>请保留包装</merHint>

       <remark1></remark1>

       <remark2></remark2>

       <merURL>http://localhost:9080/EbizSimulate/emulator/Newb2c_Pay_Mer.jsp</merURL>

       <merVAR>test</merVAR>

</message>

</B2CReq>

注:红色字体部分,即<subOrderInfo>是循环部分,最大5次,超过则接口校验报错。

 

表单样例

表单数据:

<INPUT NAME="interfaceName" TYPE="text" value="ICBC_PERBANK_B2C" >

<INPUT NAME="interfaceVersion" TYPE="text" value="1.0.0.11">

<INPUT NAME="tranData" TYPE="text" value="PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iR0JLIiBzdGFuZGFsb25lPSJubyI/PjxCMkNSZXE+PGludGVyZmFjZU5hbWU+SUNCQ19QRVJCQU5LX0IyQzwvaW50ZXJmYWNlTmFtZT48aW50ZXJmYWNlVmVyc2lvbj4xLjAuMC4xMTwvaW50ZXJmYWNlVmVyc2lvbj48b3JkZXJJbmZvPjxvcmRlckRhdGU+MjAxMDA5MDExNjIxNDI8L29yZGVyRGF0ZT48Y3VyVHlwZT4wMDE8L2N1clR5cGU+PG1lcklEPjAyMDBFQzIwMDAxMTE5PC9tZXJJRD48c3ViT3JkZXJJbmZvTGlzdD48c3ViT3JkZXJJbmZvPjxvcmRlcmlkPjIwMTAwOTAxMTYyMTQyMDwvb3JkZXJpZD48YW1vdW50PjEwMDwvYW1vdW50PjxpbnN0YWxsbWVudFRpbWVzPjE8L2luc3RhbGxtZW50VGltZXM+PG1lckFjY3Q+MDIwMDAyNjAwOTAxODM3MjIxMjwvbWVyQWNjdD48Z29vZHNJRD4wMDE8L2dvb2RzSUQ+PGdvb2RzTmFtZT7N/sTh0Nw8L2dvb2RzTmFtZT48Z29vZHNOdW0+MjwvZ29vZHNOdW0+PGNhcnJpYWdlQW10PjwvY2FycmlhZ2VBbXQ+PC9zdWJPcmRlckluZm8+PHN1Yk9yZGVySW5mbz48b3JkZXJpZD4yMDEwMDkwMTE2MjE0MjE8L29yZGVyaWQ+PGFtb3VudD4xMjA8L2Ftb3VudD48aW5zdGFsbG1lbnRUaW1lcz4xPC9pbnN0YWxsbWVudFRpbWVzPjxtZXJBY2N0PjAyMDAwMjYwMDkwMTgzNzIyMTI8L21lckFjY3Q+PGdvb2RzSUQ+MDAxPC9nb29kc0lEPjxnb29kc05hbWU+zf7E4dDcPC9nb29kc05hbWU+PGdvb2RzTnVtPjI8L2dvb2RzTnVtPjxjYXJyaWFnZUFtdD48L2NhcnJpYWdlQW10Pjwvc3ViT3JkZXJJbmZvPjwvc3ViT3JkZXJJbmZvTGlzdD48L29yZGVySW5mbz48Y3VzdG9tPjx2ZXJpZnlKb2luRmxhZz4wPC92ZXJpZnlKb2luRmxhZz48TGFuZ3VhZ2U+WkhfQ048L0xhbmd1YWdlPjwvY3VzdG9tPjxtZXNzYWdlPjxjcmVkaXRUeXBlPjI8L2NyZWRpdFR5cGU+PG5vdGlmeVR5cGU+QUc8L25vdGlmeVR5cGU+PHJlc3VsdFR5cGU+MTwvcmVzdWx0VHlwZT48bWVyUmVmZXJlbmNlPmxvY2FsaG9zdDwvbWVyUmVmZXJlbmNlPjxtZXJDdXN0b21JcD4xMjcuMC4wLjE8L21lckN1c3RvbUlwPjxnb29kc1R5cGU+MTwvZ29vZHNUeXBlPjxtZXJDdXN0b21JRD4xMjM0NTY8L21lckN1c3RvbUlEPjxtZXJDdXN0b21QaG9uZT4xMzkwMDAwMDAwMDwvbWVyQ3VzdG9tUGhvbmU+PGdvb2RzQWRkcmVzcz7I/cDvzc08L2dvb2RzQWRkcmVzcz48bWVyT3JkZXJSZW1hcms+t8DG29WpvdO/2teo08M8L21lck9yZGVyUmVtYXJrPjxtZXJIaW50PsfrsaPB9LD817A8L21lckhpbnQ+PHJlbWFyazE+PC9yZW1hcmsxPjxyZW1hcmsyPjwvcmVtYXJrMj48bWVyVVJMPmh0dHA6Ly9sb2NhbGhvc3QvRWJpelNpbXVsYXRlL2VtdWxhdG9yL05ld2IyY19QYXlfTWVy

LmpzcDwvbWVyVVJMPjxtZXJWQVI+dGVzdDwvbWVyVkFSPjwvbWVzc2FnZT48L0IyQ1JlcT4=">

<INPUT NAME="merSignMsg" TYPE="text" value="eJn7IO1i2d7E/tGEpSqItg7RXYzgRCYk0kLTyk4N/LpUDsWGDMu4ExuoFyzVjfdkHQvrQexqhl8XqmiWQm+bJ3+HbO7lYAww9kq8dAShFTQRWMDCBVHVCrp7D5pN8ZbLAyhHksd1rOmy0AsMCjwDhMCtC+w1fF6Le3MsH5ogyCk=">

<INPUT NAME="merCert" TYPE="text" value="MIICVjCCAb+gAwIBAgIKI9fKEDP6AAAO3DANBgkqhkiG9w0BAQUFADA0MRgwFgYDVQQDEw9wYmouaWNiYy5jb20uY24xGDAWBgNVBAoTD3Biai5pY2JjLmNvbS5jbjAeFw0yMDA5MjAwOTI3NDFaFw0yMTA5MjAwOTI3NDFaMEMxGDAWBgNVBAMTD2JpYW5sdTIyLmUuMDIwMDENMAsGA1UECxMEMDIwMDEYMBYGA1UEChMPcGJqLmljYmMuY29tLmNuMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDG+u/C5pad0ZbwvAk9Gv1rr+SpknfFUsTMhJLcI2KiYa+XLSf5vCib0OclOoDDXKIWPt/hkMEz+ED8YukQpsstXHvnxVFxVtPh23dubQjB8/kJ7X5EbwngsHMLFEXqr3UvNfcGZHuAFqMRPtr8ys3YnL3UG43Xienc3cD8jXFdQQIDAQABo2AwXjBLBgNVHR8ERDBCMECgPqA8pDowODEOMAwGA1UEAxMFY3JsMTMxDDAKBgNVBAsTA2NybDEYMBYGA1UEChMPcGJqLmljYmMuY29tLmNuMA8GA1UdYwQIAwYA/wAAAAAwDQYJKoZIhvcNAQEFBQADgYEAQe6tLhKaNX8OPNT2XzH7dTXIFmTm37hSvmbEL/Q/pWV386KVrNSCnyN3fowanMt5TE9qZFn9enVvyDJw4nAUx38F2PFn2Tt7JUtzt/pNKC5FiebpFJH48AXIP1Xt5GjdcBx0oXM9QNBtYvY0189t357EH4UaBfO+c+L8fkOt37o=">

 

 

tranData对应的xml明文:

<?xml version="1.0" encoding="GBK" standalone="no"?><B2CReq><interfaceName>ICBC_PERBANK_B2C</interfaceName><interfaceVersion>1.0.0.11</interfaceVersion><orderInfo><orderDate>20100901162142</orderDate><curType>001</curType><merID>0200EC20001119</merID><subOrderInfoList><subOrderInfo><orderid>201009011621420</orderid><amount>100</amount><installmentTimes>1</installmentTimes><merAcct>0200026009018372212</merAcct><goodsID>001</goodsID><goodsName>威尼熊</goodsName><goodsNum>2</goodsNum><carriageAmt></carriageAmt></subOrderInfo><subOrderInfo><orderid>201009011621421</orderid><amount>120</amount><installmentTimes>1</installmentTimes><merAcct>0200026009018372212</merAcct><goodsID>001</goodsID><goodsName>威尼熊</goodsName><goodsNum>2</goodsNum><carriageAmt></carriageAmt></subOrderInfo></subOrderInfoList></orderInfo><custom><verifyJoinFlag>0</verifyJoinFlag><Language>ZH_CN</Language></custom><message><creditType>2</creditType><notifyType>AG</notifyType><resultType>1</resultType><merReference>localhost</merReference><merCustomIp>127.0.0.1</merCustomIp><goodsType>1</goodsType><merCustomID>123456</merCustomID><merCustomPhone>13900000000</merCustomPhone><goodsAddress>三里屯</goodsAddress><merOrderRemark>防欺诈接口专用</merOrderRemark><merHint>请保留包装</merHint><remark1></remark1><remark2></remark2><merURL>http://localhost/EbizSimulate/emulator/Newb2c_Pay_Mer.jsp</merURL><merVAR>test</merVAR></message></B2CReq>

 

 

二、通知接口

2.1通知接口表单定义

变量名称

变量命名

长度定义

说明

返回商户变量

merVAR

无限制

取值:商户提交接口中merVAR字段当返回银行结果时,作为一个隐藏域变量,商户可以用此变量维护session等等。由客户端浏览器支付完成后提交通知结果时是明文传输,建议商户对此变量使用额外安全防范措施,如签名、base64银行端将此字段原样返回

通知结果数据

notifyData

无限制

银行通知消息,xml格式定义见下文,提交商户时对xml明文串进行了base64编码;

xml串中没有回车换行和多余空格;包含xml头属性,且格式固定;

银行对通知结果的签名数据

signMsg

无限制

银行使用自己证书对商户通知消息notifyData字段的xml格式明文串进行的签名,然后进行BASE64编码后的字符串。

注意:签名是对notifyDataxml明文进行签名,不是其BASE64编码后的串;签名后得到二进制数据,对此数据进行BASE64编码得到signMsg

 

2.2 notifyData数据定义

变量名称

变量命名

长度定义

说明

接口名称

interfaceName

16

取值:ICBC_PERBANK_B2C

接口版本号

interfaceVersion

MAX(15)

取值:“1.0.0.11”

交易日期时间

orderDate

=14

格式为:YYYYMMDDHHmmss

要求在银行系统当前时间的前1小时和后12小时范围内,否则判定交易时间非法。

订单号

orderid

MAX(30)

客户支付后商户网站产生的一个唯一的定单号,该订单号应该在相当长的时间内不重复。工行通过订单号加订单日期来唯一确认一笔订单的重复性。

订单金额

amount

MAX(10)

客户支付订单的总金额,一笔订单一个,以分为单位。不可以为零,必需符合金额标准。

分期付款期数

installmentTimes

MAX2

必输,每笔订单一个;

取值:13691218241代表全额付款,必须为以上数值,否则订单校验不通过。

商户账号

merAcct

MAX(19)

商户收费入账账号(只能交易时指定)。

银行指令序号

TranSerialNo

MAX(30)

银行端指令流水号

支付币种

curType

= 3

用来区分一笔支付的币种,目前工行只支持使用人民币(001)支付。

取值: “001”

商户代码

merID

MAX(20)

唯一确定一个商户的代码,由商户在工行开户时,由工行告知商户。

检验联名标志

verifyJoinFlag

=1

 

取值“1”:客户支付时,网银判断该客户是否与商户联名,是则按上送金额扣帐,否则展现未联名错误;

取值“0”:不检验客户是否与商户联名,按上送金额扣帐。

客户联名标志

JoinFlag

=1

客户在银行端是否与商城联名标志位。1客户联名 0客户未联名

联名会员号

UserNum

MAX(40)

联名客户在商户的会员号。

批次号

TranBatchNo

MAX(15)

银行端为多笔一次提交的指令生成一个唯一的批次号

返回通知日期时间

notifyDate

MAX(14)

格式为:YYYYMMDDHHmmss

订单处理状态

tranStat

=1

1-“交易成功,已清算

2-“交易失败

3-“交易可疑

错误描述

comment

MAX(100)

错误描述

 

注:红色字体部分内容,每笔订单都有一份。

 

2.3 notifyData格式定义

notifyData格式(xml格式固定,选输字段的取值可以为空,标签需保留)

<?xml version="1.0" encoding="GBK" standalone="no"?>

<B2CRes>

       <interfaceName></interfaceName>

       <interfaceVersion></interfaceVersion>

       <orderInfo>

              <orderDate></orderDate>

<curType></curType>

              <merID></merID>

<subOrderInfoList>

<subOrderInfo>

                     <orderid></orderid>

                     <amount></amount>

                     <installmentTimes></installmentTimes>

                     <merAcct></merAcct>

                     <tranSerialNo></tranSerialNo>

                     </subOrderInfo>

                     ……

<subOrderInfo>

                     <orderid></orderid>

                     <amount></amount>

                     <installmentTimes></installmentTimes>

                     <merAcct></merAcct>

                     <tranSerialNo></tranSerialNo>

                     </subOrderInfo>

              </subOrderInfoList>

       </orderInfo>

       <custom>

              <verifyJoinFlag></verifyJoinFlag>

              <JoinFlag></JoinFlag>

              <UserNum></UserNum>

       </custom>

       <bank>

              <TranBatchNo></TranBatchNo>

              <notifyDate></notifyDate>

              <tranStat></tranStat>

              <comment></comment>

       </bank>

</B2CRes>

 

注:红色字体部分,即<subOrderInfo>是循环部分,最大5次,根据商户上送的数量返回。

 

2.4表单样例

表单数据:

<INPUT TYPE="hidden" NAME="merVAR" VALUE="test">

<INPUT TYPE="hidden" NAME="notifyData" VALUE="PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IkdCSyIgc3RhbmRhbG9uZT0ibm8iID8+PEIyQ1Jlcz48aW50ZXJmYWNlTmFtZT5JQ0JDX1BFUkJBTktfQjJDPC9pbnRlcmZhY2VOYW1lPjxpbnRlcmZhY2VWZXJzaW9uPjEuMC4wLjExPC9pbnRlcmZhY2VWZXJzaW9uPjxvcmRlckluZm8+PG9yZGVyRGF0ZT4yMDEwMDkwMTE2MjE0Mjwvb3JkZXJEYXRlPjxjdXJUeXBlPjAwMTwvY3VyVHlwZT48bWVySUQ+MDIwMEVDMjAwMDExMTk8L21lcklEPjxzdWJPcmRlckluZm9MaXN0PjxzdWJPcmRlckluZm8+PG9yZGVyaWQ+MjAxMDA5MDExNjIxNDIwPC9vcmRlcmlkPjxhbW91bnQ+MTAwPC9hbW91bnQ+PGluc3RhbGxtZW50VGltZXM+MTwvaW5zdGFsbG1lbnRUaW1lcz48bWVyQWNjdD4wMjAwMDI2MDA5MDE4MzcyMjEyPC9tZXJBY2N0Pjx0cmFuU2VyaWFsTm8+SEZHMDAwMDAwMDAwMDAwNDIxPC90cmFuU2VyaWFsTm8+PC9zdWJPcmRlckluZm8+PHN1Yk9yZGVySW5mbz48b3JkZXJpZD4yMDEwMDkwMTE2MjE0MjE8L29yZGVyaWQ+PGFtb3VudD4xMjA8L2Ftb3VudD48aW5zdGFsbG1lbnRUaW1lcz4xPC9pbnN0YWxsbWVudFRpbWVzPjxtZXJBY2N0PjAyMDAwMjYwMDkwMTgzNzIyMTI8L21lckFjY3Q+PHRyYW5TZXJpYWxObz5IRkcwMDAwMDAwMDAwMDA0MjI8L3RyYW5TZXJpYWxObz48L3N1Yk9yZGVySW5mbz48L3N1Yk9yZGVySW5mb0xpc3Q+PC9vcmRlckluZm8+PGN1c3RvbT48dmVyaWZ5Sm9pbkZsYWc+MDwvdmVyaWZ5Sm9pbkZsYWc+PEpvaW5GbGFnPjwvSm9pbkZsYWc+PFVzZXJOdW0+PC9Vc2VyTnVtPjwvY3VzdG9tPjxiYW5rPjxUcmFuQmF0Y2hObz4wMDAwMDAwMDAwMDAwOTg8L1RyYW5CYXRjaE5vPjxub3RpZnlEYXRlPjIwMTAwOTEwMTc0MDUwPC9ub3RpZnlEYXRlPjx0cmFuU3RhdD4xPC90cmFuU3RhdD48Y29tbWVudD69u9LXs8m5pqOhPC9jb21tZW50PjwvYmFuaz48L0IyQ1Jlcz4=">

<INPUT TYPE="hidden" NAME="signMsg" VALUE="auCDrEmFk0Hr0ItAsNZwL0CZD6LEpI/WKm/SMc1mnlZNZ8Hx4iZS1P1c+DrXG67BKh60YhcdjVyko18BN9k4QpVBMAsuRl57wffkMm8rNubS4foCyXhKN3RRjYwtu8lrxvGHvLWPNJv+eMjyrIoHUH5ZQYGuZYQGcY2iz+IldaY=">

 

notifyData对应的明文:

<?xml  version="1.0" encoding="GBK" standalone="no" ?><B2CRes><interfaceName>ICBC_PERBANK_B2C</interfaceName><interfaceVersion>1.0.0.11</interfaceVersion><orderInfo><orderDate>20100901162142</orderDate><curType>001</curType><merID>0200EC20001119</merID><subOrderInfoList><subOrderInfo><orderid>201009011621420</orderid><amount>100</amount><installmentTimes>1</installmentTimes><merAcct>0200026009018372212</merAcct><tranSerialNo>HFG000000000000421</tranSerialNo></subOrderInfo><subOrderInfo><orderid>201009011621421</orderid><amount>120</amount><installmentTimes>1</installmentTimes><merAcct>0200026009018372212</merAcct><tranSerialNo>HFG000000000000422</tranSerialNo></subOrderInfo></subOrderInfoList></orderInfo><custom><verifyJoinFlag>0</verifyJoinFlag><JoinFlag></JoinFlag><UserNum></UserNum></custom><bank><TranBatchNo>000000000000098</TranBatchNo><notifyDate>20100910174050</notifyDate><tranStat>1</tranStat><comment>交易成功!</comment></bank></B2CRes>

 

 

三、开发步骤

商户程序需在银行模拟测试环境上进行联调后,再投产,以下说明联调开发步骤。

 

3.1生成订单:

1  商户和当地行联系,申请联调测试;由当地行在模拟测试环境录入商户信息,生成商户证书(pfx格式);并提供银行模拟测试环境的银行证书公钥文件(用于验证银行签名时使用);

2  商户或者银行用证书拆分工具将pfx格式的商户证书拆分成扩展名为crt的公钥文件和扩展名为key的私钥文件;(这两个文件用于商户开发API调用来进行商户订单数据签名)

3  商户进行开发,准备要求的订单数据;

4  其中订单签名数据merSignMsg字段是对明文的签名数据;需要使用提供的API函数和商户私钥进行签名,得到签名串,然后做BASE64编码;

5  其中商城证书公钥merCert字段需要使用API函数做BASE64编码;

6  准备好订单数据,即完成订单提交的开发;之后只要将订单提交银行接收入口“https://银行地址/servlet/ICBCINBSEBusinessServlet”,银行来处理B2C指令的资金支付;

 

3.2接收通知:

交易处理后,会将客户定向回商户网站,此时包含交易结果信息和银行签名。商户接收到银行通知后,需使用开发API和银行公钥来验证银行签名,以确保通知消息的有效性,商户收到接受通知后,可将取货链接返回银行。

以下简要说明验证步骤:

1.    获得各字段取值后,注意提交的明文需要进行base64解码才能获得。使用商户开发API和银行公钥文件对表单中的银行签名signMsg进行验签;

2.    验签成功后,为确保数据一致,建议商户比较一下通知消息中订单金额、卖家卡号等关键信息和自己记录的是否一致;

3.    商户根据交易结果tranStat来更新自己的指令状态和相关数据库信息;

 

四、代码Demo

using ICBCEBANKUTILLib; //需要引入ICBCEbankUtil 组件

 

///<summary>

/// Demo

///</summary>

public string IcbcDemo()

{

    string response = ""; // 返回字符串

    string src = "this is a test";  //src xml明文内容

    B2CUtil util = new B2CUtil();

 

    ///初始化

    ///p1:银行证书文件

    ///p2:商户证书文件

    int ret = util.init("d:\\user.crt", "d:\\user.crt", "d:\\user.key", "11111111");

    if (ret == 0)

    {

        response = "初始化成功";

    }

    else

    {

        response = "初始化失败";

        goto exit;

    }

 

    //签名

    //是对src xml明文内容签名,在签名过程中,signC已帮我们进行了Base64编码

    string ssrc = util.signC(src, src.Length);

    if (ssrc == "")

    {

        response += "签名失败,错误原因:" + util.getRC();

        goto exit;

    }

    else

    {

        response += "签名成功,签名为" + ssrc;

    }

 

///验签

/// 发送数据数据时,不需要验签

/// 只有接收银行回传数据时,才对银行数据验签

/// ret=util.verifySignC(notifyData, notifyData.Length, signMsg, signMsg.Length);

    ret = util.verifySignC(src, src.Length, ssrc, ssrc.Length);

    if (ret != 0)

    {

        response += "验签失败,错误原因:" + Convert.ToString(ret);

        goto exit;

    }

    else

    {

        response += "验签成功";

    }

 

    //获取商务证书

    string cert = util.getCert(1);

    if (cert == "")

    {

        response += "获取商户证书失败,错误原因:" + util.getRC();

        goto exit;

    }

    else

    {

        response += "获取商户证书成功,证书为:" + cert;

    }

exit:

    return response;

}

 

五、说明:

1、在提交数据给银行的页面:

B2CUtil util = new B2CUtil();

string src = tranData(); //按接口规范构造的xml明文字符串

string sTranData = EnCrypt.Base64Encode(src); //xml明文进行Base64编码

string merSignMsg = util.signC(src, src.Length); //src不需要进行base64编码

 

2、在接收银行回传数据的页面:

string merVAR = Request.Form["merVAR"];  //商户数据

//银行返回的通知结果数据,base64编码过的xml明文

string notifyData = Request.Form["notifyData"];

//银行使用自己证书对商户通知消息notifyData字段的xml格式明文串进行的签名,

//然后进行BASE64编码后的字符串

string signMsg = Request.Form["signMsg"];

 

B2CUtil util = new B2CUtil();

ret = util.verifySignC(notifyData, notifyData.Length, signMsg, signMsg.Length);

if (ret == 0)

{

    //验签成功的操作

}

else

{

    //验签失败的操作

}

 

//成功后,对notifyData进行Base64解码:

string xmlStr = EnCrypt.Base64Decode(notifyData);

 

//分析操作xmlStr

 

 

 

其中,Base64编码、解码方法:

///<summary>

///转成Base64形式的System.String

///</summary>

///<param name="str"></param>

///<returns></returns>

public static string Base64Encode(string str)

{

    byte[] b = System.Text.Encoding.Default.GetBytes(str);

 

    //转成Base64形式的System.String

    return Convert.ToBase64String(b);

}

 

public static string Base64Encode(Byte[] b)

{

    ///转成Base64形式的System.String

    return Convert.ToBase64String(b);

}

 

///<summary>

/// Base64转回到原来的 System.String

///</summary>

///<param name="str"></param>

///<returns></returns>

public static string Base64Decode(string str)

{

    byte[] c = Convert.FromBase64String(str);

 

    //转回到原来的 System.String

    return System.Text.Encoding.Default.GetString(c);

}

 

 

六、错误提示:

 

1 信息代码:96113258

提示信息:商户上送数据有误;

 

merReference字段的问题

Reference和客户IP两者必须上送1;

Reference必须上送商户自己的域名,不能带有“http://”前缀,支持通配符,例如“*.B2C商城.com”,更适合有多个二级域名的商户使用。

测试demo中由于reference字段上送localhost

所以表单的提交地址必须为“http://localhost/”开头格式地址才能提交成功。

待客户投产后再将“商户reference”字段换成商户自己的域名.

 

2 信息代码:96110438

  提示信息:商户证书ID异常

 

这是商户证书的问题,需要联系签约人才能操作;

ICBC技术人员的建议是:

1)解冻证书;

2)开放对账号的权限;

 

组件下载:点击下载

posted @ 2012-04-19 12:24  沙茶叶  阅读(8385)  评论(1编辑  收藏  举报