这几天在做chinapay的接口整合,银联的文档写得太烂,代码规范也不行,给用户带来不便就不多说,废话少说了,整理一下碰到的一些文档中没有强调的问题或者容易忽视的问题。
一、注册ChinaPay.dll这个文件
如果想调用银联的接口,必须在机器上配置好环境:运行窗口中 regsvr32 ChinaPay.dll的绝对路径。
二、后台响应地址(即要配置的BgRetUrl)需要用外网的地址才能获取到支付成功后返回的数据
由于开发在本地测试,刚开始使用本地localhost的链接,结果接收不到支付成功后返回的数据,困扰了我好久。
三、验证数字签名的方法返回的不是布尔,是字符串的true或false
Com类型信息转换为.NET元数据tlbimp ChinaPay.dll /out: ChinaPay_tsl.dll后,并不是像文档中说的那样返回的布尔值,返回的是字符串。
四、支付版本号问题
808080开头的商户用此版本“20040916”。
五、支付成功后返回的数据要判断状态
对返回的数据除了要进行数字签名验证外,还需要进行状态的判断,如if(Request["status"]==”1001”){}
netpayclinet.jar |
根据项目工程的需要放置对应路径下 |
用于提供数字签名的方法调用 |
MerPrk.key |
可以放置到任意路径下,但是需要调用方法指定文件位置和名称 |
商户签名私钥 |
PgPubk.key |
可以放置到任意路径下,但是需要调用方法指定文件位置和名称 |
ChinaPay签名公钥 |
把jar包放进项目lib里后直接调用方法:
1.创建公/私钥对象buildKey
chinapay.PrivateKey key=new chinapay.PrivateKey();
chinapay.SecureLink t;
boolean flag;
//buildKey用于创建私/公钥的对象,用于签名或者验证签名,该方法在类chinapay. PrivateKey中。
//第一个参数:MerId 商户号,长度为15个字节的数字串,由ChinaPay分配。
//第二个参数:使用私/公钥的方式,固定为 0
//第三个参数:私/公钥的文件路径(包含文件名称)baseDiskPath, File.separator(不同系统自适应路径)
String baseDiskPath = request.getSession().getServletContext().getRealPath(File.separator);
flag=key.buildKey(MerId,0,baseDiskPath+File.separator+"chinapaykey"+File.separator+"MerPrK.key");
if (flag==false)
{
System.out.println("build key error!");
}else {
System.out.println("build key ok!");
}
2.订单签名函数signOrder 该方法在类chinapay. SecureLink中
String MerId, OrdId, TransAmt, CuryId, TransDate, TransType,ChkValue;
// 对订单的签名,参数说明见页面表单
ChkValue= t.signOrder(MerId, OrdId, TransAmt, CuryId, TransDate, TransType) ;
//将订单数据送往页面提交
request.setAttribute("ChkValue", ChkValue);
request.setAttribute("TransAmt", TransAmt);
request.setAttribute("OrdId", OrdId);
request.setAttribute("TransDate", TransDate);
3.//页面接收参数并自动提交
//这里action的内容为提交交易数据的URL地址 http://payment-test.chinapay.com/pay/TransGet为测试地址
//MerId为ChinaPay统一分配给商户的商户号,15位长度,必填
//商户提交给ChinaPay的交易订单号,16位长度,必填
<%String OrdId = (String)request.getAttribute("OrdId"); %>
>
//订单交易金额,单位为分,12位长度,左补0,必填
<%String TransAmt = (String)request.getAttribute("TransAmt"); %>
>
//订单交易币种,3位长度,固定为人民币156, 必填
//订单交易日期,8位长度,必填
<%String TransDate = (String)request.getAttribute("TransDate"); %>
>
//交易类型,4位长度,必填,取值范围为:"0001"和"0002", 其中"0001"表示消费交易,"0002"表示退货交易
//支付接入版本号,必填,20040916的版本中,如果商户为二级商户,订单号从第5位到第9位必须和商户号的第11位到第15位相同
//后台交易接收URL,必填,长度不要超过80个字节
<% String basePath = request.getScheme()+"://"+request.getServerName();
String BgRetUrl = basePath+"/返回页面"; %>
>
//页面交易接收URL,长度不要超过80个字节,必填
>
//支付网关号,可选
//商户私有域,长度不要超过60个字节,可选
<%String Priv1 = (String)request.getAttribute("Priv1"); %>
>
//256字节长的ASCII码,为此次交易提交关键数据的数字签名,必填
<%String ChkValue = (String)request.getAttribute("ChkValue"); %>
>
4.验证交易应答函数verifyTransResponse 该方法在类chinapay. SecureLink中
//后台返回页验证
chinapay.PrivateKey key=new chinapay.PrivateKey();
chinapay.SecureLink t;
boolean flag;
boolean flag1;
String MerId, OrdId, TransAmt, CuryId, TransDate, TransType,ChkValue,OrderStatus,Priv1;
String plainData, ChkValue2;
MerId = request.getParameter("merid");
OrdId = request.getParameter("orderno");
TransAmt = request.getParameter("amount");
CuryId = request.getParameter("currencycode");
TransDate = request.getParameter("transdate");
TransType = request.getParameter("transtype");
OrderStatus = request.getParameter("status");
ChkValue = request.getParameter("checkvalue");
Priv1 = request.getParameter("Priv1");
String baseDiskPath = request.getSession().getServletContext().getRealPath(File.separator);
flag=key.buildKey("999999999999999",0,baseDiskPath+File.separator+"chinapaykey"+File.separator+"PgPubk.key");
if (flag==false)
{
//System.out.println("build key error!");
}else {
//System.out.println("build key ok!");
}
t=new chinapay.SecureLink (key);
flag1=t.verifyTransResponse(MerId,OrdId, TransAmt, CuryId, TransDate, TransType, OrderStatus, ChkValue);
------------
demo
订单号
订单数量
金额
>
get方式:
http://payment-test.chinapay.com/pay/TransGet?MerId=001320554110008&OrdId=0001320554110008&TransAmt=000000001234&CuryId=156&TransDate=20130410&TransType=0001&Version=20040916&BgRetUrl=http://www.baidu.com&PageRetUrl=http://www.baidu.com&ChkValue=
00132055411000800132055411000800132055411000800
13205541100080013205541100080013205541100081000800
13205541100081000800132055411000810008001320554110008
18018018011801801801180180013205541100080013205541100
08001320554110008001320554110008001320554110008000080