工行支付接口开发(Java版)体会和问题解决
最近做了Java版本的工行支付接口版本。根据工行提供的Java的Demo程序,略经修改,可以用了。
支付流程大致如下:
1 在我们的页面,客户生成订单,发起支付请求(支付页面),支付页面包含银行回调页面(merchant_url)。
2 客户进入银行支付页面,完成支付
3 银行在支付成功后,服务器向我们的支付服务器发起页面请求
4 我们的页面接到银行post过来的数据,进行签名验证,成功后处理相关业务,最终返回一个只有一个供客户浏览(我们通知客户支付成功)的页面地址(URL)给工行
5 工行接到我们的返回URL后,将此URL返回给浏览器
6 客户看到我们的支付成功的通知。
在开发过程中,出现了一个问题,纠结了很久。原来是Base64编码的中文支持问题,
从明文生成字节数组时,原来没有指定编码,导致银行解码错误,从而不能支付。
后加入了参数"GBK",终于成功。
byte[] byteSrc = TranData.getBytes("gbk");
下面是代码的其中一部分
<%
SimpleDateFormat sdf = new SimpleDateFormat("HHmmss");
Calendar c = Calendar.getInstance();
c.setTime(new Date());
String curTime = "20111101" + sdf.format(c.getTime());
String merReference = "pay.xxx.com";
String TranData = "<?xml version="1.0" encoding="GBK" standalone="no"?>"
+"<B2CReq>"
+"<interfaceName>ICBC_PERBANK_B2C</interfaceName>"
+"<interfaceVersion>1.0.0.11</interfaceVersion>"
+"<orderInfo>"
+"<orderDate>" + curTime + "</orderDate>"
+"<curType>001</curType>"
+"<merID>" +"0200EC23750709" + "</merID>"
+"<subOrderInfoList>"
+"<subOrderInfo>"
+"<orderid>" + curTime +"1416290" +"</orderid>"
+"<amount>" + amount + "</amount>"
+"<installmentTimes>1</installmentTimes>"
+"<merAcct>" + "0200004519000100173" +"</merAcct>"
+"<goodsID>001</goodsID>"
+"<goodsName>商品</goodsName>"
+"<goodsNum>2</goodsNum>"
+"<carriageAmt>20</carriageAmt>"
+"</subOrderInfo>"
+"</subOrderInfoList>"
+"</orderInfo>"
+"<custom>"
+"<verifyJoinFlag>0</verifyJoinFlag>"
+"<Language>ZH_CN</Language>"
+"</custom>"
+"<message>"
+"<creditType>2</creditType>"
+"<notifyType>" +"HS" + "</notifyType>"
+"<resultType>1</resultType>"
+"<merReference>" + merReference+"</merReference>"
+"<merCustomIp>" + request.getRemoteAddr().toString() + "</merCustomIp>"
+"<goodsType>1</goodsType>"
+"<merCustomID>80004000</merCustomID>"
+"<merCustomPhone>85865623</merCustomPhone>"
+"<goodsAddress>朝阳</goodsAddress>"
+"<merOrderRemark>loongtao</merOrderRemark>"
+"<merHint></merHint>"
+"<remark1></remark1>"
+"<remark2></remark2>"
+"<merURL>http://"+ merReference+"/pay/IcbcPayback.jsp</merURL>"
+"<merVAR>" + "varTest" + "</merVAR>"
+"</message>"
+"</B2CReq>";
out.println("<font face='Arial' size='4' color='Green'>明文:</font>"+TranData+"<br>");
String password = "12345678";
String TranDataBase64 = "";
String SignMsgBase64 = "";
String CertBase64 = "";
try{
byte[] byteSrc = TranData.getBytes("gbk");
char[] keyPass = password.toCharArray();
byte [] byteSrcBase64= ReturnValue.base64enc(byteSrc);
TranDataBase64 = new String(byteSrcBase64).toString();
String linuxdir = "/home/xxx/icbc/";
String windir = "d:\\icbc\";
String selDir = windir;
String osName = System.getProperty("os.name");
if (!osName.contains("Windows"))
selDir = linuxdir;
out.println("KeyDir = " + selDir);
File f = new File(selDir + "tranData.log");
FileWriter fw = null;
fw = new FileWriter(f,true);
fw.write("time\t" + curTime+"\n");
fw.write("TranData\t" + TranData + "\n\n");
//fw.write("TranDataBase64\t" + TranDataBase64 + "\n\n");
fw.flush();
fw.close();
FileInputStream in1 = new FileInputStream(selDir+ "user.crt");
byte[] bcert = new byte[in1.available()];
in1.read(bcert);
in1.close();
FileInputStream in2 = new FileInputStream(selDir + "user.key");
byte[] bkey = new byte[in2.available()];
in2.read(bkey);
in2.close();
byte[] sign =ReturnValue.sign(byteSrc,byteSrc.length,bkey,keyPass);
if (sign==null) {
out.println("<font face='Arial' size='4' color='Red'>签名失败,签名返回为空。<br>请检查证书私钥和私钥保护口令是否正确。</font><br>");
}else{
//out.println("<font face='Arial' size='4' color='Green'>签名成功</font><br>");
%>
<form name="form1" method="post" action="https://mybank.dccnet.com.cn/servlet/ICBCINBSEBusinessServlet">
<table width="100%" height="35" border="0" cellpadding="0" cellspacing="0">
<tr>
<td height="80" align="center"><input type="submit" value="确认支付">
<INPUT NAME="interfaceName" TYPE="hidden" value="ICBC_PERBANK_B2C" >
<INPUT NAME="interfaceVersion" TYPE="hidden" value="1.0.0.11">
<INPUT NAME="tranData" TYPE="hidden" value="<%=TranDataBase64%>">
<INPUT NAME="merSignMsg" TYPE="hidden" value="<%=SignMsgBase64%>">
<INPUT NAME="merCert" TYPE="hidden" value="<%=CertBase64%>">
</td>
</tr>
</table>
最近做了Java版本的工行支付接口版本。根据工行提供的Java的Demo程序,略经修改,可以用了。
支付流程大致如下:
1 在我们的页面,客户生成订单,发起支付请求(支付页面),支付页面包含银行回调页面(merchant_url)。
2 客户进入银行支付页面,完成支付
3 银行在支付成功后,服务器向我们的支付服务器发起页面请求
4 我们的页面接到银行post过来的数据,进行签名验证,成功后处理相关业务,最终返回一个只有一个供客户浏览(我们通知客户支付成功)的页面地址(URL)给工行
5 工行接到我们的返回URL后,将此URL返回给浏览器
6 客户看到我们的支付成功的通知。
在开发过程中,出现了一个问题,纠结了很久。原来是Base64编码的中文支持问题,
从明文生成字节数组时,原来没有指定编码,导致银行解码错误,从而不能支付。
后加入了参数"GBK",终于成功。
byte[] byteSrc = TranData.getBytes("gbk");
下面是代码的其中一部分
<%
SimpleDateFormat sdf = new SimpleDateFormat("HHmmss");
Calendar c = Calendar.getInstance();
c.setTime(new Date());
String curTime = "20111101" + sdf.format(c.getTime());
String merReference = "pay.xxx.com";
String TranData = "<?xml version="1.0" encoding="GBK" standalone="no"?>"
+"<B2CReq>"
+"<interfaceName>ICBC_PERBANK_B2C</interfaceName>"
+"<interfaceVersion>1.0.0.11</interfaceVersion>"
+"<orderInfo>"
+"<orderDate>" + curTime + "</orderDate>"
+"<curType>001</curType>"
+"<merID>" +"0200EC23750709" + "</merID>"
+"<subOrderInfoList>"
+"<subOrderInfo>"
+"<orderid>" + curTime +"1416290" +"</orderid>"
+"<amount>" + amount + "</amount>"
+"<installmentTimes>1</installmentTimes>"
+"<merAcct>" + "0200004519000100173" +"</merAcct>"
+"<goodsID>001</goodsID>"
+"<goodsName>商品</goodsName>"
+"<goodsNum>2</goodsNum>"
+"<carriageAmt>20</carriageAmt>"
+"</subOrderInfo>"
+"</subOrderInfoList>"
+"</orderInfo>"
+"<custom>"
+"<verifyJoinFlag>0</verifyJoinFlag>"
+"<Language>ZH_CN</Language>"
+"</custom>"
+"<message>"
+"<creditType>2</creditType>"
+"<notifyType>" +"HS" + "</notifyType>"
+"<resultType>1</resultType>"
+"<merReference>" + merReference+"</merReference>"
+"<merCustomIp>" + request.getRemoteAddr().toString() + "</merCustomIp>"
+"<goodsType>1</goodsType>"
+"<merCustomID>80004000</merCustomID>"
+"<merCustomPhone>85865623</merCustomPhone>"
+"<goodsAddress>朝阳</goodsAddress>"
+"<merOrderRemark>loongtao</merOrderRemark>"
+"<merHint></merHint>"
+"<remark1></remark1>"
+"<remark2></remark2>"
+"<merURL>http://"+ merReference+"/pay/IcbcPayback.jsp</merURL>"
+"<merVAR>" + "varTest" + "</merVAR>"
+"</message>"
+"</B2CReq>";
out.println("<font face='Arial' size='4' color='Green'>明文:</font>"+TranData+"<br>");
String password = "12345678";
String TranDataBase64 = "";
String SignMsgBase64 = "";
String CertBase64 = "";
try{
byte[] byteSrc = TranData.getBytes("gbk");
char[] keyPass = password.toCharArray();
byte [] byteSrcBase64= ReturnValue.base64enc(byteSrc);
TranDataBase64 = new String(byteSrcBase64).toString();
String linuxdir = "/home/xxx/icbc/";
String windir = "d:\\icbc\";
String selDir = windir;
String osName = System.getProperty("os.name");
if (!osName.contains("Windows"))
selDir = linuxdir;
out.println("KeyDir = " + selDir);
File f = new File(selDir + "tranData.log");
FileWriter fw = null;
fw = new FileWriter(f,true);
fw.write("time\t" + curTime+"\n");
fw.write("TranData\t" + TranData + "\n\n");
//fw.write("TranDataBase64\t" + TranDataBase64 + "\n\n");
fw.flush();
fw.close();
FileInputStream in1 = new FileInputStream(selDir+ "user.crt");
byte[] bcert = new byte[in1.available()];
in1.read(bcert);
in1.close();
FileInputStream in2 = new FileInputStream(selDir + "user.key");
byte[] bkey = new byte[in2.available()];
in2.read(bkey);
in2.close();
byte[] sign =ReturnValue.sign(byteSrc,byteSrc.length,bkey,keyPass);
if (sign==null) {
out.println("<font face='Arial' size='4' color='Red'>签名失败,签名返回为空。<br>请检查证书私钥和私钥保护口令是否正确。</font><br>");
}else{
//out.println("<font face='Arial' size='4' color='Green'>签名成功</font><br>");
%>
<form name="form1" method="post" action="https://mybank.dccnet.com.cn/servlet/ICBCINBSEBusinessServlet">
<table width="100%" height="35" border="0" cellpadding="0" cellspacing="0">
<tr>
<td height="80" align="center"><input type="submit" value="确认支付">
<INPUT NAME="interfaceName" TYPE="hidden" value="ICBC_PERBANK_B2C" >
<INPUT NAME="interfaceVersion" TYPE="hidden" value="1.0.0.11">
<INPUT NAME="tranData" TYPE="hidden" value="<%=TranDataBase64%>">
<INPUT NAME="merSignMsg" TYPE="hidden" value="<%=SignMsgBase64%>">
<INPUT NAME="merCert" TYPE="hidden" value="<%=CertBase64%>">
</td>
</tr>
</table>
</form>
转 http://www.myexception.cn/program/771498.html