公司最近要将原先的1.0.0.0支付接口升级为1.0.0.11 版本,在工行技术人员给出的实例中有ASP、C、JAVA的就是没有ASP.NET与PHP的(先鄙视下)。
下面是根据1.0.0.0转换成1.0.0.11的并参考了http://www.liufangfang.net/blog/148 这个网站
首先将工行提供的 ICBCEBankUtil.dll 注册(如何注册就不说了)注册好后在项目中引用(infosecapi.dll刚开始一直在这个文件上纠缠,结果......)。
然后将public.crt、商户.crt、商户.key 这三个文件放到工程下,
下面就是具体代码了
ICBCTest
1 /// <summary>
2 /// 工商银行调用接口示例
3 /// </summary>
4 public class ICBCTest
5 {
6 string strCertFN = @"E:\XXXX\public.crt";
7 string strCertFNM = @"E:\XXX\商户.crt";
8 string strKeyFN = @"E:\XXX\商户.key";
9 string strKey = "88888888";
10
11 /// <summary>
12 /// 获取工商银行验证信息
13 /// </summary>
14 /// <returns></returns>
15 public ICBC GetCheckInfo(ICBC argIcbc)
16 {
17 string strMerSignMsg = string.Empty;
18 B2CUtil icbcObj = new B2CUtil();
19
20 if (icbcObj.init(strCertFN, strCertFNM, strKeyFN, strKey) == 0)
21 {
22 argIcbc.MerSignMsg = icbcObj.signC(argIcbc.TranData, argIcbc.TranData.Length);
23 argIcbc.MerCert = icbcObj.getCert(1);
24 argIcbc.TranData = Encode(argIcbc.TranData);
25 }
26 else
27 {
28 return null;
29 }
30 return argIcbc;
31 }
32
33 /// <summary>
34 /// 获取工商银行验证信息
35 /// </summary>
36 /// <returns></returns>
37 public ICBC GetCheckReturnInfo(ICBC argIcbc)
38 {
39 string strMerSignMsg = string.Empty;
40 B2CUtil icbcObj = new B2CUtil();
41
42 if (icbcObj.init(strCertFN, strCertFNM, strKeyFN, strKey) == 0)
43 {
44 argIcbc.TranData = Decode(argIcbc.TranData);
45
46 if (icbcObj.verifySignC(argIcbc.TranData, argIcbc.TranData.Length, argIcbc.MerSignMsg, argIcbc.MerSignMsg.Length) == 0) //判断验证银行签名是否成功
47 {
48 argIcbc.IsCheck = true;
49 }
50 else
51 argIcbc.IsCheck = true;
52 }
53 else
54 {
55 argIcbc.IsCheck = false;
56 }
57 return argIcbc;
58 }
59
60
61
62 /// <summary>
63 /// 加密
64 /// </summary>
65 /// <param name="data">加密字符串</param>
66 /// <returns>string</returns>
67 public string Encode(string data)
68 {
69 try
70 {
7172 //这里是加密算法7374 }
75 catch (Exception e)
76 {
77 throw;
78 }
79 }
80
81 /// <summary>
82 /// 解密
83 /// </summary>
84 /// <param name="str">解密字符串</param>
85 /// <returns>string</returns>
86 public string Decode(string str)
87 {
888990 //这里是解密算法91 }
92
93
94 }
工行信息实体类(这些属性是什么意思一般在开发文档中都有详细的提到)
View ICBC
1 public class ICBC
2 {
3 private string _orderPostUrl = "https://mybank.dccnet.com.cn/servlet/ICBCINBSEBusinessServlet
4 ";
5 private string _interfaceName = "ICBC_PERBANK_B2C";
6 private string _interfaceVersion = "1.0.0.11";
7 private string _orderid;
8 private string _amount;
9 private string _curType = "001";
10 private string _merID = "XXXXXX";
11 private string _merAcct = "XXXXXXXXXXXX";
12 private string _verifyJoinFlag = "0";
13 private string _notifyType = "HS";
14 private string _merURL;
15 private string _resultType = "1";
16 private string _orderDate = System.DateTime.Now.ToString("yyyyMMddHHmmss");
17 private string _merSignMsg;
18 private string _merCert;
19 private string _goodsID = "001";
20 private string _goodsName = "XXXX";
21 private string _goodsNum;
22 private string _carriageAmt;
23 private string _remark1;
24 private string _remark2;
25 private string _merHint;
26 private string _tranData;
27 private string _merReference = "localhost";
28
29 private bool _isCheck = false;
30
31 /// <summary>
32 /// 是否检测成功
33 /// </summary>
34 public bool IsCheck
35 {
36 get { return _isCheck; }
37 set { _isCheck = value; }
38 }
39
40 public string MerReference
41 {
42 get { return _merReference; }
43 set { _merReference = value; }
44 }
45
46 /// <summary>
47 /// 报文数据
48 /// </summary>
49 public string TranData
50 {
51 get { return _tranData; }
52 set { _tranData = value; }
53 }
54
55 /// <summary>
56 /// 工商支付接口路径
57 /// </summary>
58 public string OrderPostUrl
59 {
60 get { return _orderPostUrl; }
61 set { _orderPostUrl = value; }
62 }
63
64 /// <summary>
65 /// 接口名称
66 /// </summary>
67 public string InterfaceName
68 {
69 get { return _interfaceName; }
70 set { _interfaceName = value; }
71 }
72
73 /// <summary>
74 /// 接口版本号
75 /// </summary>
76 public string InterfaceVersion
77 {
78 get { return _interfaceVersion; }
79 set { _interfaceVersion = value; }
80 }
81
82 /// <summary>
83 /// 订单号
84 /// </summary>
85 public string Orderid
86 {
87 get { return _orderid; }
88 set { _orderid = value; }
89 }
90
91 /// <summary>
92 /// 订单金额
93 /// </summary>
94 public string Amount
95 {
96 get { return _amount; }
97 set { _amount = value; }
98 }
99
100 /// <summary>
101 /// 支付币种 RMB:001
102 /// </summary>
103 public string CurType
104 {
105 get { return _curType; }
106 set { _curType = value; }
107 }
108
109 /// <summary>
110 /// 商户代码
111 /// </summary>
112 public string MerID
113 {
114 get { return _merID; }
115 set { _merID = value; }
116 }
117
118 /// <summary>
119 /// 商户账号
120 /// </summary>
121 public string MerAcct
122 {
123 get { return _merAcct; }
124 set { _merAcct = value; }
125 }
126
127 /// <summary>
128 /// 检验联名标志
129 /// 取值“1”:客户支付时,网银判断该客户是否与商户联名,是则按上送金额扣帐,否则展现未联名错误;
130 /// 取值“0”:不检验客户是否与商户联名,按上送金额扣帐。
131 /// </summary>
132 public string VerifyJoinFlag
133 {
134 get { return _verifyJoinFlag; }
135 set { _verifyJoinFlag = value; }
136 }
137
138 /// <summary>
139 /// 通知类型
140 /// 取值“HS”:在交易完成后实时将通知信息以HTTP协议POST方式,主动发送给商户,发送地址为商户端随订单数据提交的接收工行支付结果的URL即表单中的merURL字段;
141 /// 取值“AG”:在交易完成后不通知商户。商户需使用浏览器登录工行的B2C商户服务网站,或者使用工行提供的客户端程序API主动获取通知信息。
142 /// </summary>
143 public string NotifyType
144 {
145 get { return _notifyType; }
146 set { _notifyType = value; }
147 }
148
149 /// <summary>
150 /// 返回商户URL
151 /// </summary>
152 public string MerURL
153 {
154 get { return _merURL; }
155 set { _merURL = value; }
156 }
157
158 /// <summary>
159 /// 结果发送类型
160 /// </summary>
161 public string ResultType
162 {
163 get { return _resultType; }
164 set { _resultType = value; }
165 }
166
167 /// <summary>
168 /// 交易日期时间
169 /// </summary>
170 public string OrderDate
171 {
172 get { return _orderDate; }
173 set { _orderDate = value; }
174 }
175
176 /// <summary>
177 /// 订单签名数据
178 /// </summary>
179 public string MerSignMsg
180 {
181 get { return _merSignMsg; }
182 set { _merSignMsg = value; }
183 }
184
185 /// <summary>
186 /// 商城证书公钥
187 /// </summary>
188 public string MerCert
189 {
190 get { return _merCert; }
191 set { _merCert = value; }
192 }
193
194 /// <summary>
195 /// 商品编号
196 /// </summary>
197 public string GoodsID
198 {
199 get { return _goodsID; }
200 set { _goodsID = value; }
201 }
202
203 /// <summary>
204 /// 商品名称
205 /// </summary>
206 public string GoodsName
207 {
208 get { return _goodsName; }
209 set { _goodsName = value; }
210 }
211
212 /// <summary>
213 /// 商品数量
214 /// </summary>
215 public string GoodsNum
216 {
217 get { return _goodsNum; }
218 set { _goodsNum = value; }
219 }
220
221 /// <summary>
222 /// 已含运费金额
223 /// </summary>
224 public string CarriageAmt
225 {
226 get { return _carriageAmt; }
227 set { _carriageAmt = value; }
228 }
229
230 /// <summary>
231 /// 备注字段1
232 /// </summary>
233 public string Remark1
234 {
235 get { return _remark1; }
236 set { _remark1 = value; }
237 }
238
239 /// <summary>
240 /// 备注字段2
241 /// </summary>
242 public string Remark2
243 {
244 get { return _remark2; }
245 set { _remark2 = value; }
246 }
247
248 /// <summary>
249 /// 商城提示
250 /// </summary>
251 public string MerHint
252 {
253 get { return _merHint; }
254 set { _merHint = value; }
255 }
256 }
这里处理好了 下面就是页面代码
ICBCPay.aspx
1 <body>
2 <form name="sendOrder" method="post" action="<%= icmcModel.OrderPostUrl %>" id="order">
3 <input type="hidden" name="interfaceName" value="<%= icmcModel.InterfaceName %>">
4 <input type="hidden" name="interfaceVersion" value="<%= icmcModel.InterfaceVersion %>">
5 <input type="hidden" name="tranData" value="<%= icmcModel.TranData %>">
6 <input type="hidden" name="merSignMsg" value="<%= icmcModel.MerSignMsg %>">
7 <input type="hidden" name="merCert" value="<%= icmcModel.MerCert %>">
8 </form>
9 <script type="text/javascript">
10 document.order.submit();
11 </script>
12 </body>
ICBCPay.aspx.cs
1 public partial class ICBCPay : System.Web.UI.Page
2 {
3 public ICBC icmcModel = new ICBC();
4
5 protected void Page_Load(object sender, EventArgs e)
6 {
7 ICBCTest it = new ICBCTest();
8 StringBuilder strXml = new StringBuilder();
9 OrderInfo oi = OrderFactory.GetOrderInfo();
10 strXml.Append("<?xml version=\"1.0\" encoding=\"GBK\" standalone=\"no\"?>");
11 strXml.Append("<B2CReq>");
12 //接口名称
13 strXml.Append("<interfaceName>" + icmcModel.InterfaceName + "</interfaceName>");
14 //接口版本号
15 strXml.Append("<interfaceVersion>" + icmcModel.InterfaceVersion + "</interfaceVersion>");
16 //订单信息
17 strXml.Append("<orderInfo>");
18 //交易日期时间
19 strXml.Append("<orderDate>" + icmcModel.OrderDate + "</orderDate>");
20 //支付币种
21 strXml.Append("<curType>" + icmcModel.CurType + "</curType>");
22 //商户代码
23 strXml.Append("<merID>" + icmcModel.MerID + "</merID>");
24 //订单信息列表
25 strXml.Append("<subOrderInfoList>");
26 //订单信息
27 strXml.Append("<subOrderInfo> ");
28 //订单编号
29 strXml.Append("<orderid>" + oi.OrderID + "</orderid>");
30 //订单金额
31 strXml.Append("<amount>" + oi.Amount + "</amount> ");
32 //分期付款期数 1代表全额付款
33 strXml.Append("<installmentTimes>1</installmentTimes>");
34 //商户账号
35 strXml.Append("<merAcct>" + icmcModel.MerAcct + "</merAcct>");
36 //商品编号
37 strXml.Append("<goodsID>" + oi.OrderNo + "</goodsID>");
38 //商品名称
39 strXml.Append("<goodsName>" + oi.OrderName + "</goodsName>");
40 //商品数量
41 strXml.Append("<goodsNum>" + oi.OrderNum + "</goodsNum>");
42 //已含运费金额
43 strXml.Append("<carriageAmt></carriageAmt>");
44 strXml.Append("</subOrderInfo>");
45 ////订单信息
46 //strXml.Append("<subOrderInfo> ");
47 ////订单编号
48 //strXml.Append("<orderid>1106003222031772</orderid>");
49 ////订单金额
50 //strXml.Append("<amount>1000</amount> ");
51 ////分期付款期数 1代表全额付款
52 //strXml.Append("<installmentTimes>1</installmentTimes>");
53 ////商户账号
54 //strXml.Append("<merAcct>" + icmcModel.MerAcct + "</merAcct>");
55 ////商品编号
56 //strXml.Append("<goodsID>XXXXXXX</goodsID>");
57 ////商品名称
58 //strXml.Append("<goodsName>XXXXXXX</goodsName>");
59 ////商品数量
60 //strXml.Append("<goodsNum>1000</goodsNum>");
61 ////已含运费金额
62 //strXml.Append("<carriageAmt>15</carriageAmt>");
63 //strXml.Append("</subOrderInfo>");
64 strXml.Append("</subOrderInfoList>");
65 strXml.Append("</orderInfo>");
66 strXml.Append("<custom>");
67 //检验联名标志 取值“1”:客户支付时,网银判断该客户是否与商户联名
68 strXml.Append("<verifyJoinFlag>" + icmcModel.VerifyJoinFlag + "</verifyJoinFlag>");
69 //语言版本 取值:“EN_US”为英文版;取值:“ZH_CN”或其他为中文版
70 strXml.Append("<Language>ZH_CN</Language>");
71 strXml.Append("</custom>");
72 strXml.Append("<message>");
73 //支持订单支付的银行卡种类
74 strXml.Append("<creditType>2</creditType>");
75 //通知类型
76 strXml.Append("<notifyType>" + icmcModel.NotifyType + "</notifyType>");
77 //结果发送类型
78 strXml.Append("<resultType>" + icmcModel.ResultType + "</resultType>");
79 //商户reference
80 strXml.Append("<merReference>" + icmcModel.MerReference + "</merReference>");
81 //客户端IP 当商户reference项送空时,该项必输
82 strXml.Append("<merCustomIp></merCustomIp>");
83 //虚拟商品/实物商品标志位 取值“0”:虚拟商品 取值“1”,实物商品
84 strXml.Append("<goodsType>1</goodsType>");
85 //买家用户号
86 strXml.Append("<merCustomID></merCustomID>");
87 //买家联系电话
88 strXml.Append("<merCustomPhone></merCustomPhone>");
89 //收货地址
90 strXml.Append("<goodsAddress></goodsAddress>");
91 //订单备注
92 strXml.Append("<merOrderRemark></merOrderRemark>");
93 //商城提示
94 strXml.Append("<merHint></merHint>");
95 //备注字段1
96 strXml.Append("<remark1></remark1>");
97 //备注字段2
98 strXml.Append("<remark2></remark2>");
99 //返回商户URL
100 strXml.Append("<merURL>http://localhost/ICPCPayReturn.aspx</merURL>");
101 //返回商户变量
102 strXml.Append("<merVAR>" + oi.OrderID + "</merVAR>");
103 strXml.Append("</message>");
104 strXml.Append("</B2CReq>");
105
106 icmcModel.TranData = strXml.ToString();
107 icmcModel = it.GetCheckInfo(icmcModel);
108 }
109
110
111 }
OrderInfo 这个为产品信息,这里自己看实际情况来
到此就好了,返回画面就不多写了,只是调用ICBCTest 类中的 GetCheckReturnInfo 方法 从而返回 解密后的值 然后解析解密后的值就可以了。
最后需要注意的是,测试必须在80端口下进行,不然跳过去回报错。
不好意思,前一段时间有点忙,自己还没弄完返回页面就已经发博客了,今天将返回页面也贴出来
ICPCPayReturn.aspx.cs
1 public partial class ICPCPayReturn : System.Web.UI.Page
2 {
3 protected void Page_Load(object sender, EventArgs e)
4 {
5 if (Request.Form["notifyData"] != null)
6 {
7 try
8 {
9 ICBCTest icbcCheck = new ICBCTest();
10 ICBC icbcInfo = new ICBC();
11
12 icbcInfo.TranData = Request.Form["notifyData"];
13 icbcInfo.MerSignMsg = Request.Form["signMsg"].ToString();
14
15 icbcInfo = icbcCheck.GetCheckReturnInfo(icbcInfo);
16 //自定义返回
17 string strOrderSN = Request.Form["merVAR"].ToString();
18
19 if (icbcInfo.IsCheck)
20 {
21 DataSet myds = new DataSet();
22 StringReader strReader = new StringReader(icbcInfo.TranData);
23 myds.ReadXml(strReader);
24 DataTable mytable = new DataTable();
25 mytable = myds.Tables["bank"];
26
27 if (null != mytable && mytable.Rows.Count > 0)
28 {
29 if (mytable.Rows[0]["tranStat"].ToString().Trim() == "1")
30 {
31 //这里做成功操作
32 Response.Write("http://XXXXXX/PaySuccess.aspx");
33 }
34 else
35 {
36 Response.Write("http://XXXX/PayError.aspx");
37 //Response.Write(mytable.Rows[0]["comment"].ToString());
38 }
39 }
40 }
41 else
42 {
43 Response.Write("http://XXXX/PayError.aspx");
44 //Response.Write("签名失败!");
45 }
46 }
47 catch (Exception)
48 {
49 Response.Write("http://XXXX/PayError.aspx");
50 }
51 }
52 else
53 {
54 //Response.Write("银行数据返回失败,请通知管理员!");
55 Response.Write("http://XXXXX/PayError.aspx");
56 }
57
58
59
60
61 }
62 }
1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ICPCPayReturn.aspx.cs"
2 Inherits="ICPCPayReturn" %>
到此才真正的完成支付并返回
折腾了好久才弄好。