银联在线Java接口开发

简介: chinapay接口整合到网站中要注意的一些细节这几天在做chinapay的接口整合,银联的文档写得太烂,代码规范也不行,给用户带来不便就不多说,废话少说了,整理一下碰到的一些文档中没有强调的问题或者容易忽视的问题。

chinapay接口整合到网站中要注意的一些细节


这几天在做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分配。

//第二个参数:使用私/公钥的方式,固定为 

//第三个参数:/公钥的文件路径(包含文件名称)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为测试地址

<form name="form1" action="https://payment.chinapay.com/pay/TransGet" METHOD=POST>

//MerIdChinaPay统一分配给商户的商户号,15位长度,必填
<input type=hidden name="MerId" value=""/> 

//商户提交给ChinaPay的交易订单号,16位长度,必填
<%String OrdId = (String)request.getAttribute("OrdId"); %>
<input type=hidden name="OrdId" value=<%=OrdId %>>

//订单交易金额,单位为分,12位长度,左补0,必填
<%String TransAmt = (String)request.getAttribute("TransAmt"); %>
<input type=hidden name="TransAmt" value=<%=TransAmt %>>

//订单交易币种,3位长度,固定为人民币156, 必填
<input type=hidden name="CuryId" value="156"/>

//订单交易日期,8位长度,必填
<%String TransDate = (String)request.getAttribute("TransDate"); %>
<input type=hidden name="TransDate" value=<%=TransDate %>>

//交易类型,4位长度,必填,取值范围为:"0001""0002", 其中"0001"表示消费交易,"0002"表示退货交易
<input type=hidden name="TransType" value="0001"/>

//支付接入版本号,必填,20040916的版本中,如果商户为二级商户,订单号从第5位到第9位必须和商户号的第11位到第15位相同
<input type=hidden name="Version" value="20040916"/>

//后台交易接收URL,必填,长度不要超过80个字节
<% String basePath = request.getScheme()+"://"+request.getServerName();
String BgRetUrl = basePath+"/返回页面"; %>
<input type=hidden name="BgRetUrl" value=<%=BgRetUrl %>>

//页面交易接收URL,长度不要超过80个字节,必填
<input type=hidden name="PageRetUrl" value=<%=basePath %>>

//支付网关号,可选
<input type=hidden name="GateId" value="">

//商户私有域,长度不要超过60个字节,可选
<%String Priv1 = (String)request.getAttribute("Priv1"); %>
<input type=hidden name="Priv1" value=<%=Priv1 %>>

//256字节长的ASCII,为此次交易提交关键数据的数字签名,必填
<%String ChkValue = (String)request.getAttribute("ChkValue"); %>
<input type=hidden name="ChkValue" value=<%=ChkValue %>>
</form>

<script language="JavaScript" type="text/JavaScript">
 form1.submit();
</script>

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

<form id="form1" runat="server">

    <div>
        <table cellpadding="0" cellspacing="0" border="1" style="border-collapse:collapse" bordercolor="#cccccc">
            <tr>
                <td>订单号</td>
                <td>
                    <asp:TextBox ID="txtOrderNo" runat="server">0700004350100289</asp:TextBox></td>
            </tr>
            <tr>
                <td>订单数量</td>
                <td><asp:TextBox ID="txtOrderQty" runat="server"></asp:TextBox></td>
            </tr>
            <tr>
                <td>金额</td>
                <td><asp:TextBox ID="txtAmount" runat="server"></asp:TextBox></td>
            </tr>
            <tr>
                <td colspan="2">
                <form name="frm1" action="http://payment.chinapay.com:8081/pay/TransGet" METHOD="POST" > 
                    <input type=hidden name="MerId" value="808080010500435" > 
                    <input type=hidden name="OrdId" value="0700004350100289" >
                    <input type=hidden name="TransAmt" value="000000106000" > 
                    <input type=hidden name="CuryId" value="156" >
                    <input type=hidden name="TransDate" value="20070703" > 
                    <input type=hidden name="TransType" value="0001" > 
                    <input type=hidden name="Version" value="20040916"> 
                    <input type=hidden name="BgRetUrl" value="accept.aspx"> 
                    <input type=hidden name="PageRetUrl" value="chinapayback.aspx"> 
                    <input type=hidden name="Priv1" value="Memo"> 
                    <input type=hidden name="ChkValue" value=<%= keyValue %> > 
                    
                    <input id="Button1" type="submit" class="button" value="进入银联支付平台" /></form>
                    </td>
            </tr>
        </table>
    </div>
    </form>


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

相关文章
|
15天前
|
算法 Java 数据处理
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。HashSet基于哈希表实现,提供高效的元素操作;TreeSet则通过红黑树实现元素的自然排序,适合需要有序访问的场景。本文通过示例代码详细介绍了两者的特性和应用场景。
33 6
|
15天前
|
存储 Java 数据处理
Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位
【10月更文挑战第16天】Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位。本文通过快速去重和高效查找两个案例,展示了Set如何简化数据处理流程,提升代码效率。使用HashSet可轻松实现数据去重,而contains方法则提供了快速查找的功能,彰显了Set在处理大量数据时的优势。
26 2
|
2天前
|
Java 开发者
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
12 4
|
8天前
|
安全 Java
在 Java 中使用实现 Runnable 接口的方式创建线程
【10月更文挑战第22天】通过以上内容的介绍,相信你已经对在 Java 中如何使用实现 Runnable 接口的方式创建线程有了更深入的了解。在实际应用中,需要根据具体的需求和场景,合理选择线程创建方式,并注意线程安全、同步、通信等相关问题,以确保程序的正确性和稳定性。
|
9天前
|
开发框架 JavaScript 前端开发
HarmonyOS UI开发:掌握ArkUI(包括Java UI和JS UI)进行界面开发
【10月更文挑战第22天】随着科技发展,操作系统呈现多元化趋势。华为推出的HarmonyOS以其全场景、多设备特性备受关注。本文介绍HarmonyOS的UI开发框架ArkUI,探讨Java UI和JS UI两种开发方式。Java UI适合复杂界面开发,性能较高;JS UI适合快速开发简单界面,跨平台性好。掌握ArkUI可高效打造符合用户需求的界面。
48 8
|
4天前
|
SQL Java 程序员
倍增 Java 程序员的开发效率
应用计算困境:Java 作为主流开发语言,在数据处理方面存在复杂度高的问题,而 SQL 虽然简洁但受限于数据库架构。SPL(Structured Process Language)是一种纯 Java 开发的数据处理语言,结合了 Java 的架构灵活性和 SQL 的简洁性。SPL 提供简洁的语法、完善的计算能力、高效的 IDE、大数据支持、与 Java 应用无缝集成以及开放性和热切换特性,能够大幅提升开发效率和性能。
|
5天前
|
存储 Java 关系型数据库
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践,包括连接创建、分配、复用和释放等操作,并通过电商应用实例展示了如何选择合适的连接池库(如HikariCP)和配置参数,实现高效、稳定的数据库连接管理。
16 2
|
5天前
|
监控 Java 数据库连接
在Java开发中,数据库连接管理是关键问题之一
在Java开发中,数据库连接管理是关键问题之一。本文介绍了连接池技术如何通过预创建和管理数据库连接,提高数据库操作的性能和稳定性,减少资源消耗,并简化连接管理。通过示例代码展示了HikariCP连接池的实际应用。
11 1
|
6天前
|
Java
Java基础(13)抽象类、接口
本文介绍了Java面向对象编程中的抽象类和接口两个核心概念。抽象类不能被实例化,通常用于定义子类的通用方法和属性;接口则是完全抽象的类,允许声明一组方法但不实现它们。文章通过代码示例详细解析了抽象类和接口的定义及实现,并讨论了它们的区别和使用场景。
|
6天前
|
Java 测试技术 API
Java零基础-接口详解
【10月更文挑战第19天】Java零基础教学篇,手把手实践教学!
15 1