700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 易宝Java版支付

易宝Java版支付

时间:2024-02-09 03:47:08

相关推荐

易宝Java版支付

整个过程只有两个步骤:发起支付请求和响应支付结果

首先是Web.xml

[html]view plaincopyprint?<?xmlversion="1.0"encoding="UTF-8"?> <web-appversion="2.5"xmlns="/xml/ns/javaee" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/xml/ns/javaee /xml/ns/javaee/web-app_2_5.xsd"> <servlet> <description>发起支付请求</description> <servlet-name>PaymentRequestServlet</servlet-name> <servlet-class>com.jadyer.servlet.PaymentSendServlet</servlet-class> </servlet> <servlet> <description>响应支付结果</description> <servlet-name>PaymentResponseServlet</servlet-name> <servlet-class>com.jadyer.servlet.PaymentResultServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>PaymentRequestServlet</servlet-name> <url-pattern>/servlet/yeepay/PaymentSendServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>PaymentResponseServlet</servlet-name> <url-pattern>/servlet/yeepay/PaymentResultServlet</url-pattern> </servlet-mapping> </web-app> <!-- ******************************************************************************* 网上支付,两种接入方案:1)直接与银行对接。2)通过中间公司间接与银行对接 1)直接与银行对接 优点:由于是直接与银行进行财务结算,故交易资金比较安全 适合资金流量比较大的(比如每月结算金额达到佰万以上)的企业 缺点:开发工作量比较大。银行会不定期升级交易系统,故企业也需要作相应改动 而且企业每年还需要向银行交纳一定数量的接口应用费 2)通过中间公司间接与银行对接 优点:开发工作量较少。由于使用的是中间企业提供的接入规范,故银行升级系统时不需要企业作相应修改 除非中间企业的接入规范发生了改变,企业才作相应修改 由于只是与一家中间企业对接,故其接入费用也比较低 适合资金流量比较小的(比如每月结算金额在几十万以下的中小企业) 缺点:由于是与中间企业进行资金结算,而目前所有中间企业都是私企,故资金安全是个大问题 ******************************************************************************** 目前国内做的比较好的中间支付公司 首信易支付: 每年交纳一定的接口使用费,并从交易金额中扣除1%的手续费。红孩子、当当网、京东商城等用之 易宝支付: 接入免费,只从交易金额中扣除1%的手续费。盛大、艺龙网、巴巴运动网等用之 ******************************************************************************** 支付流程,大致如下:(可参考//WebRoot//WEB-INF//page//connection.jsp来理解) 通过HTTP的方式向易宝支付网关发起支付请求,即向connection.jsp中注释部分的测试或正式网关发起请求 该请求可以是GET或者POST方式,页面应采用GBK或者GB2312编码 易宝支付网关对企业发来的数据,使用用户的密钥生成HMAC-MD5 然后与企业发来的HMAC-MD5(即表单中hmac字段提供的值)比较 若二者相同,则将请求转发到银行网关 当用户支付完成后,银行网关会引导用户的浏览器重定向到易宝支付网关 接着易宝支付网关再引导浏览器重定向到企业提供的url页面(即表单中p8_Url提供的值) ******************************************************************************** -->

下面是本Web应用的首页index.jsp[html]view plaincopyprint?<%@pagelanguage="java"pageEncoding="GBK"%> <title>Java在线支付_第一步_选择银行</title> <formaction="${pageContext.request.contextPath}/servlet/yeepay/PaymentSendServlet"method="POST"> <tablealign="center"width="600"border="6"cellspacing="0"cellpadding="2"> <tr> <tdalign="center"colspan="4"bgcolor="#FFD2E9"> <b>订单号:</b><inputtype="text"name="orderID"> <b>应付金额:¥</b><inputtype="text"name="amount"size="6"><b>元</b> </td> </tr> <tr> <tdcolspan="4"></td> </tr> <tr> <tdcolspan="4"bgcolor="#C0C0C0">请选择在线支付银行</td> </tr> <tr> <tdheight="25"width="24%"><inputtype="radio"name="pd_FrpId"value="ICBC-NET">工商银行</td> <tdheight="25"width="24%"><inputtype="radio"name="pd_FrpId"value="CMBCHINA-NET">招商银行</td> <tdheight="25"width="24%"><inputtype="radio"name="pd_FrpId"value="ABC-NET">农业银行</td> <tdheight="25"width="28%"><inputtype="radio"name="pd_FrpId"value="CCB-NET">建设银行</td> </tr> <tr> <tdheight="25"><inputtype="radio"name="pd_FrpId"value="CEB-NET">光大银行</td> <tdheight="25"><inputtype="radio"name="pd_FrpId"value="BOCO-NET">交通银行</td> <tdheight="25"><inputtype="radio"name="pd_FrpId"value="CMBC-NET">民生银行</td> <tdheight="25"><inputtype="radio"name="pd_FrpId"value="SDB-NET">深圳发展银行</td> </tr> <tr> <tdheight="25"><inputtype="radio"name="pd_FrpId"value="BCCB-NET">北京银行</td> <tdheight="25"><inputtype="radio"name="pd_FrpId"value="CIB-NET">兴业银行</td> <tdheight="25"><inputtype="radio"name="pd_FrpId"value="ECITIC-NET">中信银行</td> <tdheight="25"><inputtype="radio"name="pd_FrpId"value="SPDB-NET">浦东发展银行</td> </tr> <tr> <tdcolspan="4"></td> </tr> <tr> <tdcolspan="4"align="center"bgcolor="#FFDAB5"><inputtype="submit"value="确认支付"/></td> </tr> </table> </form>

下面是用于发起支付请求的PaymentSendServlet.java

[java]view plaincopyprint?packagecom.jadyer.servlet; importjava.io.IOException; importjavax.servlet.ServletException; importjavax.servlet.http.HttpServlet; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importcom.jadyer.util.PaymentUtil; /** *发起支付请求 *@see============================================================================================== *@see测试商户 *@seep1_MerId=10000432521 *@seekeyValue=8UPp0KE8sq73zVP370vko7C39403rtK1YwX40Td6irH216036H27Eb12792t *@see============================================================================================== *@see正式商户:本人亲测,可以直接连到银行页面 *@seep1_MerId=10001126856 *@seekeyValue=69cl522AV6q613Ii4W6u8K6XuW8vM1N6bFgyv769220IuYe9u37N4y7rI4Pl *@see============================================================================================== *@seeaccountCallbackURL=http://127.0.0.1:8088/payment/servlet/yeepay/PaymentResultServlet *@see此时机器需联网。若使用路由上的网,只要把路由的IP写进去,再在路由里配置一个8088端口的转发规则,即可 *@see============================================================================================== */ @SuppressWarnings("serial") publicclassPaymentSendServletextendsHttpServlet{ publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{ this.doPost(request,response); } publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{ request.setCharacterEncoding("GBK"); //测试商户:商户编号 StringaccountID="10000432521"; //测试商户:密钥 StringkeyValue="8UPp0KE8sq73zVP370vko7C39403rtK1YwX40Td6irH216036H27Eb12792t"; //测试商户:商户接收支付成功数据的地址 StringaccountCallbackURL="http://127.0.0.1:8088/payment/servlet/yeepay/PaymentResultServlet"; StringorderID=request.getParameter("orderID");//获取订单号 Stringamount=request.getParameter("amount");//获取支付金额 StringaccountBankID=request.getParameter("pd_FrpId");//获取用户所选择的银行 StringbusinessType="Buy";//业务类型。Buy为在线支付 Stringcurrency="CNY";//交易币种。CNY为人民币 StringproductDesc="";//商品描述 StringproductCategory="";//商品种类 StringproductID="";//商品ID StringaddressFlag="0";//送货地址。0为不需要,1为需要 StringaccountMoreInfo="";//商户扩展信息 Stringpr_NeedResponse="0";//应答机制 Stringmd5hmac=PaymentUtil.buildHmac( businessType,accountID,orderID,amount,currency,productID,productCategory, productDesc,accountCallbackURL,addressFlag,accountMoreInfo,accountBankID, pr_NeedResponse,keyValue); request.setAttribute("businessType",businessType); request.setAttribute("accountID",accountID); request.setAttribute("orderID",orderID); request.setAttribute("amount",amount); request.setAttribute("currency",currency); request.setAttribute("productID",productID); request.setAttribute("productCategory",productCategory); request.setAttribute("productDesc",productDesc); request.setAttribute("accountCallbackURL",accountCallbackURL); request.setAttribute("addressFlag",addressFlag); request.setAttribute("accountMoreInfo",accountMoreInfo); request.setAttribute("accountBankID",accountBankID); request.setAttribute("needResponse",pr_NeedResponse); request.setAttribute("md5hmac",md5hmac); request.getRequestDispatcher("/WEB-INF/page/connection.jsp").forward(request,response); } }

下面是用于连接本地支付请求和易宝之间的connection.jsp

[html]view plaincopyprint?<%@pagelanguage="java"pageEncoding="GBK"%> <title>Java在线支付_第二步_支付请求</title> <bodyonload="javascript:document.forms[0].submit()"> <%--易宝的正式网关:/app-merchant-proxy/node--%> <%--易宝的测试网关::8080/robot/debug.action--%> <formaction=":8080/robot/debug.action"method="POST"name="yeepay"> <!--以下hidden中的name值为易宝支付规范的固定命名和顺序--> <inputtype='hidden'name='p0_Cmd'value="${businessType}"> <inputtype='hidden'name='p1_MerId'value="${accountID}"> <inputtype='hidden'name='p2_Order'value="${orderID}"> <inputtype='hidden'name='p3_Amt'value="${amount}"> <inputtype='hidden'name='p4_Cur'value="${currency}"> <inputtype='hidden'name='p5_Pid'value="${productID}"> <inputtype='hidden'name='p6_Pcat'value="${productCategory}"> <inputtype='hidden'name='p7_Pdesc'value="${productDesc}"> <inputtype='hidden'name='p8_Url'value="${accountCallbackURL}"> <inputtype='hidden'name='p9_SAF'value="${addressFlag}"> <inputtype='hidden'name='pa_MP'value="${accountMoreInfo}"> <inputtype='hidden'name='pd_FrpId'value="${accountBankID}"> <inputtype="hidden"name='pr_NeedResponse'value="${needResponse}"> <inputtype='hidden'name='hmac'value="${md5hmac}"> </form> </body>

下面是用于响应支付结果的PaymentResultServlet.java

[java]view plaincopyprint?packagecom.jadyer.servlet; importjava.io.IOException; importjavax.servlet.ServletException; importjavax.servlet.http.HttpServlet; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importcom.jadyer.util.PaymentUtil; /** *响应银行支付结果 *@see============================================================================================== *@see测试商户 *@seep1_MerId=10000432521 *@seekeyValue=8UPp0KE8sq73zVP370vko7C39403rtK1YwX40Td6irH216036H27Eb12792t *@see============================================================================================== *@see正式商户:本人亲测,可以直接连到银行页面 *@seep1_MerId=10001126856 *@seekeyValue=69cl522AV6q613Ii4W6u8K6XuW8vM1N6bFgyv769220IuYe9u37N4y7rI4Pl *@see============================================================================================== */ @SuppressWarnings("serial") publicclassPaymentResultServletextendsHttpServlet{ publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{ this.doPost(request,response); } publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{ request.setCharacterEncoding("GBK"); //测试商户:商家ID Stringp1_MerId="10000432521"; //测试商户:商家密钥 StringkeyValue="8UPp0KE8sq73zVP370vko7C39403rtK1YwX40Td6irH216036H27Eb12792t"; Stringr0_Cmd=request.getParameter("r0_Cmd");//业务类型 Stringr1_Code=request.getParameter("r1_Code");//扣款结果。1:扣款成功 Stringr2_TrxId=request.getParameter("r2_TrxId");//易宝交易订单号 Stringr3_Amt=request.getParameter("r3_Amt");//扣款金额。交易结束后,易宝交易系统将实际扣款金额返回给商户 Stringr4_Cur=request.getParameter("r4_Cur");//交易币种。人民币为CNY Stringr5_Pid=request.getParameter("r5_Pid");//商品ID Stringr6_Order=request.getParameter("r6_Order");//商户订单号 Stringr7_Uid=request.getParameter("r7_Uid");//易宝会员ID Stringr8_MP=request.getParameter("r8_MP");//商户扩展信息。可任意填写1K的字符串,交易返回时将原样返回 Stringr9_BType=request.getParameter("r9_BType");//交易结果通知类型。1:交易成功回调(浏览器重定向),2:交易成功主动通知(服务器点对点通讯) Stringhmac=request.getParameter("hmac");//MD5交易签名 booleanresult=PaymentUtil.verifyCallback( hmac,p1_MerId,r0_Cmd,r1_Code,r2_TrxId,r3_Amt,r4_Cur, r5_Pid,r6_Order,r7_Uid,r8_MP,r9_BType,keyValue); if(result){ if("1".equals(r1_Code)){ StringBuffermessage=newStringBuffer(); message.append("订单号为:"+r6_Order+"的订单支付成功,");//此时数据库中订单支付状态应为已支付,否则容易出现"无限刷点卡"的BUG message.append("用户支付了"+r3_Amt+"元。<br/>"); message.append("交易结果通知类型:"); if("1".equals(r9_BType)){ message.append("浏览器重定向。<br/>"); }elseif("2".equals(r9_BType)){ message.append("易宝支付网关后台程序通知。<br/>"); } message.append("易宝订单系统中的订单号为:"+r2_TrxId); request.setAttribute("message",message); }else{ request.setAttribute("message","用户支付失败"); } }else{ request.setAttribute("message","数据来源不合法"); } request.getRequestDispatcher("/WEB-INF/page/paymentResult.jsp").forward(request,response); } }

下面是用于显示支付结果的paymentResult.jsp

[html]view plaincopyprint?<%@pagelanguage="java"pageEncoding="GBK"%> <title>Java在线支付_第三步_支付结果</title> <center> <h3><fontcolor="red">${message}</font></h3> </center>

接下来是我们用到的支付工具类PaymentUtil.java

[java]view plaincopyprint?packagecom.jadyer.util; /** *支付工具类 */ publicclassPaymentUtil{ /** *对支付请求的数据,加密生成md5-hmac *@see以下参数都是易宝支付规范要求发送的,并且它们的顺序是固定的 *@see并且以下所有参数的值,都不能为null,只能为空字符串,即"" *@paramp0_Cmd业务类型 *@paramp1_MerId商户编号 *@paramp2_Order商户订单号 *@paramp3_Amt支付金额 *@paramp4_Cur交易币种 *@paramp5_Pid商品ID *@paramp6_Pcat商品种类 *@paramp7_Pdesc商品描述 *@paramp8_Url商户接收支付成功数据的地址 *@paramp9_SAF送货地址 *@parampa_MP商户扩展信息 *@parampd_FrpId银行编码 *@parampr_NeedResponse应答机制 *@paramkeyValue商户密钥 */ publicstaticStringbuildHmac(Stringp0_Cmd,Stringp1_MerId, Stringp2_Order,Stringp3_Amt,Stringp4_Cur,Stringp5_Pid, Stringp6_Pcat,Stringp7_Pdesc,Stringp8_Url,Stringp9_SAF, Stringpa_MP,Stringpd_FrpId,Stringpr_NeedResponse, StringkeyValue){ StringBuffersb=newStringBuffer(); sb.append(p0_Cmd);//业务类型。目前我们使用的是在线支付的业务类型,它的命令是Buy sb.append(p1_MerId);//商户编号。使用易宝支付前,须成为其用户,然后会分配商户编号和密钥给我们 sb.append(p2_Order);//商户订单号。在我们的系统中,用于跟踪订单的号码 sb.append(p3_Amt);//支付金额 sb.append(p4_Cur);//交易币种 sb.append(p5_Pid);//商品ID。可选,该信息可以不提供给易宝 sb.append(p6_Pcat);//商品种类。可选,该信息可以不提供给易宝 sb.append(p7_Pdesc);//商品描述。可选,该信息可以不提供给易宝 sb.append(p8_Url);//商户接收支付成功数据的地址。也就是交易结果通知地址 sb.append(p9_SAF);//送货地址。可以不提供给易宝,但要设其值为空字符串。注意不是null sb.append(pa_MP);//商户扩展信息。它会发送给支付网关,在支付处理完成后,它会原样返回。可不提供给易宝,但要设其为空字符串 sb.append(pd_FrpId);//银行编码。这是易宝自己制定的,例如工商银行的编码为ICBC-NET sb.append(pr_NeedResponse);//应答机制。默认为0和1两种 //0代表易宝请求p8_Url时得到的页面状态是200,就表示该页面已成功接收到数据 //假设接收程序出现了例外,并捕获了例外,那么此时的请求仍是成功的,但实际上程序并没有接受到数据,这种情况下可以使用1应答 //1代表易宝请求p8_Url时,页面返回的代码中,没有html代码,而只有一个success,则表示该页面已成功接收到数据 returnDigestUtil.hmacSign(sb.toString(),keyValue); } /** *返回校验hmac方法 *@see以下参数的顺序,都是易宝支付规范规定的 *@paramhmac支付网关发来的加密验证码 *@paramp1_MerId商户编号 *@paramr0_Cmd业务类型 *@paramr1_Code支付结果 *@paramr2_TrxId易宝支付交易流水号 *@paramr3_Amt支付金额 *@paramr4_Cur交易币种 *@paramr5_Pid商品名称 *@paramr6_Order商户订单号 *@paramr7_Uid易宝支付会员ID *@paramr8_MP商户扩展信息 *@paramr9_BType交易结果返回类型 *@paramkeyValue密钥 *@return */ publicstaticbooleanverifyCallback(Stringhmac,Stringp1_MerId, Stringr0_Cmd,Stringr1_Code,Stringr2_TrxId,Stringr3_Amt, Stringr4_Cur,Stringr5_Pid,Stringr6_Order,Stringr7_Uid, Stringr8_MP,Stringr9_BType,StringkeyValue){ StringBuffersb=newStringBuffer(); sb.append(p1_MerId);//商户编号。可以为"",但不能为null sb.append(r0_Cmd);//业务类型 sb.append(r1_Code);//支付结果 sb.append(r2_TrxId);//易宝支付交易流水号。其属于易宝支付的订单系统 sb.append(r3_Amt);//支付金额 sb.append(r4_Cur);//交易币种 sb.append(r5_Pid);//商品名称 sb.append(r6_Order);//商户订单号 sb.append(r7_Uid);//易宝支付会员ID sb.append(r8_MP);//商户扩展信息 sb.append(r9_BType);//交易结果返回类型 returnhmac.equals(DigestUtil.hmacSign(sb.toString(),keyValue)); } }

最后是支付工具类中用到的MD5-hmac加密类DigestUtil.java

[java]view plaincopyprint?packagecom.jadyer.util; importjava.io.UnsupportedEncodingException; importjava.security.MessageDigest; importjava.security.NoSuchAlgorithmException; importjava.util.Arrays; /** *MD5-hmac加密类 *@seeHMAC-MD5是一种秘密的密钥验证算法。HMAC提供的数据完整性和源身份验证完全取决于秘密密钥分配的范围 *@see如果只有发起者和接收者知道HAMC密钥,那么这就对两者间发送的数据提供了源身份验证和完整性保证 */ publicclassDigestUtil{ /** *加密源数据 *@see这是针对多条字符串(即数组)进行加密的方法。它会把数组元素拼成新字符串,然后再加密 *@see本文暂未用到该方法 *@paramaValue加密的原文,即源数据 *@paramaKey密钥 */ publicstaticStringgetHmac(String[]args,Stringkey){ if(args==null||args.length==0){ return(null); } StringBufferstr=newStringBuffer(); for(inti=0;i<args.length;i++){ str.append(args[i]); } return(hmacSign(str.toString(),key)); } /** *加密源数据 *@see这是针对一条字符串进行加密的方法 *@paramaValue加密的原文,即源数据 *@paramaKey密钥 */ publicstaticStringhmacSign(StringaValue,StringaKey){ bytek_ipad[]=newbyte[64]; bytek_opad[]=newbyte[64]; bytekeyb[]; bytevalue[]; try{ keyb=aKey.getBytes("UTF-8"); value=aValue.getBytes("UTF-8"); }catch(UnsupportedEncodingExceptione){ keyb=aKey.getBytes(); value=aValue.getBytes(); } Arrays.fill(k_ipad,keyb.length,64,(byte)54); Arrays.fill(k_opad,keyb.length,64,(byte)92); for(inti=0;i<keyb.length;i++){ k_ipad[i]=(byte)(keyb[i]^0x36); k_opad[i]=(byte)(keyb[i]^0x5c); } MessageDigestmd=null; try{ md=MessageDigest.getInstance("MD5"); }catch(NoSuchAlgorithmExceptione){ returnnull; } md.update(k_ipad); md.update(value); bytedg[]=md.digest(); md.reset(); md.update(k_opad); md.update(dg,0,16); dg=md.digest(); returntoHex(dg); } publicstaticStringtoHex(byteinput[]){ if(input==null){ returnnull; } StringBufferoutput=newStringBuffer(input.length*2); for(inti=0;i<input.length;i++){ intcurrent=input[i]&0xff; if(current<16){ output.append("0"); } output.append(Integer.toString(current,16)); } returnoutput.toString(); } ///** //*本文暂未用到该方法 //*/ //publicstaticStringdigest(StringaValue){//aValue=aValue.trim(); //bytevalue[]; //try{//value=aValue.getBytes("UTF-8"); //}catch(UnsupportedEncodingExceptione){//value=aValue.getBytes(); //} //MessageDigestmd=null; //try{//md=MessageDigest.getInstance("SHA"); //}catch(NoSuchAlgorithmExceptione){//e.printStackTrace(); //returnnull; //} //returntoHex(md.digest(value)); //} // //publicstaticvoidmain(String[]args){//Stringvalue="adpoga234lkdsngoiuayv1111wekng123123korhjtg"; //String[]values={"adpoga234lkdsngoiuayv11","11wekng123123korhjtg"}; //Stringkey="abcdjadyer"; //System.out.println(hmacSign(value,key)); //System.out.println(getHmac(values,key)); //} }

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。