一、支付接口表單定義
新模式接口的交易數據整合到一個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和商戶證書將tranData的xml明文串進行簽名,得到二進制簽名數據,然后進行BASE64編碼后得到可視的merSignMsg; 注意:簽名時是針對tranData的xml明文,不是將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、商戶提交數據中的空格將被認為是有效字符被接收,請商戶開發時注意對多余空格的控制。
5、tranData交易數據的xml串需要有xml的頭,即<?xml version="1.0" encoding="GBK" standalone="no"?>
變量名稱 |
變量命名 |
長度定義 |
說明 |
接口名稱 |
interfaceName |
=16 |
必輸, 取值:“ICBC_PERBANK_B2C” |
接口版本號 |
interfaceVersion |
MAX(15) |
必輸, 取值:“1.0.0.11” |
交易日期時間 |
orderDate |
=14 |
必輸, 格式為:YYYYMMDDHHmmss 目前要求在銀行系統當前時間的前后十分鍾范圍內,否則判定交易時間非法。 |
訂單號 |
orderid |
MAX(30) |
必輸,每筆訂單都需要有不同的訂單號; 客戶支付后商戶網站產生的一個唯一的定單號,該訂單號應該在相當長的時間內不重復。工行通過訂單號加訂單日期來唯一確認一筆訂單的重復性。 |
訂單金額 |
amount |
MAX(10) |
必輸,每筆訂單一個; 客戶支付訂單的總金額,一筆訂單一個,以分為單位。不可以為零,必需符合金額標准。 |
分期付款期數 |
installmentTimes |
MAX(2) |
必輸,每筆訂單一個; 取值:1、3、6、9、12、18、24;1代表全額付款,必須為以上數值,否則訂單校驗不通過。 |
商戶賬號 |
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”。取值范圍為0、1、2,其中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格式(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編碼后的字符串。 注意:簽名是對notifyData的xml明文進行簽名,不是其BASE64編碼后的串;簽名后得到二進制數據,對此數據進行BASE64編碼得到signMsg |
變量名稱 |
變量命名 |
長度定義 |
說明 |
接口名稱 |
interfaceName |
=16 |
取值:“ICBC_PERBANK_B2C” |
接口版本號 |
interfaceVersion |
MAX(15) |
取值:“1.0.0.11” |
交易日期時間 |
orderDate |
=14 |
格式為:YYYYMMDDHHmmss 要求在銀行系統當前時間的前1小時和后12小時范圍內,否則判定交易時間非法。 |
訂單號 |
orderid |
MAX(30) |
客戶支付后商戶網站產生的一個唯一的定單號,該訂單號應該在相當長的時間內不重復。工行通過訂單號加訂單日期來唯一確認一筆訂單的重復性。 |
訂單金額 |
amount |
MAX(10) |
客戶支付訂單的總金額,一筆訂單一個,以分為單位。不可以為零,必需符合金額標准。 |
分期付款期數 |
installmentTimes |
MAX(2) |
必輸,每筆訂單一個; 取值:1、3、6、9、12、18、24;1代表全額付款,必須為以上數值,否則訂單校驗不通過。 |
商戶賬號 |
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) |
錯誤描述 |
注:紅色字體部分內容,每筆訂單都有一份。
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)開放對賬號的權限;
組件下載:點擊下載