工行支付接口开发(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>
</form>

你可能感兴趣的:(java)