09_分析易宝支付网关的应答协议与处理代码
-------------------------------------------------------------------------------------------------------------------------
对支付结果返回的数据加密生成md5-hmac
public static boolean verifyCallback(String hmac,String p1_MerId,String r0_Cmd,
String r1_Code,String r2_TrxId,String r3_Amt,String r4_Cur,
String r5_Pid,String r6_Order,String r7_Uid,String r8_Mp,
String r9_BType,String keyValue){
StringBuffer sValue=new StringBuffer();
sValue.append(p1_MerId);//商户编号
sValue.append(r0_Cmd);//业务类型
sValue.append(r1_Code);//支付结果
sValue.append(r2_TrxId);//易宝支付交易流水号
sValue.append(r3_Amt);//支付金额
sValue.append(r4_Cur);//交易币种
sValue.append(r5_Pid);//商品名称
sValue.append(r6_Order);//商户订单号
sValue.append(r7_Uid);//易宝支付会员ID
sValue.append(r8_Mp);//商户扩展信息
sValue.append(r9_BType);//交易结果返回类型
String sNewString=null;
sNewString =DigestUtil.hmacSign(sValue.toString(), keyValue);
if(hmac.equals(sNewString)){
return true;
}
return false;
}
----------------------------------------------------------------------------------------------------
10_完成用于处理支付响应的Servlet的初步编写和调试
1.关于易宝支付中的ip地址的配置问题:当商户把用户的购物信息封装加密后发给易宝的时候,这时候访问的是易宝的地址,
当易宝处理完之后返回的地址:商户在软件中的配置,payment/src/merchantInfo.properties
p1_MerId=10000326625
keyValue=0acqgug6x57m0wrsiod6clpn1ezh47r2ot5h1zkq5dztiic8y5xkm5g0p0ek
merchantCallbackURL=http\://172.16.53.1\:8080/payment/servlet/yeepay/response
第三个:merchantCallbackURL=http\://172.16.53.1\:8080/payment/servlet/yeepay/response 这个地址就是需要接收易宝返回数据的地址。
-----------------------------------------------------------------------------------------------------
2.这里172.16.53.1就应该是外网的地址,但是即使是外网的地址,那么如果自己的电脑用的地址是通过路由器分配的,那么需要在路由器进行配置,也就是转发配置,就是把通过外网地址,返回的易宝支付的结果转发到你的电脑上。
转发的时候:在路由器中的转发规则中的端口填写:8080;地址填写:自己的内网地址,然后勾选启用。
----------------------------------------------------------------------------------------------------
11_完成用于处理支付网关响应结果的Servlet
1.payment/src/com/credream/servlet/PaymentResutlResponse.java
package com.credream.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcast.utils.ConfigInfo;
import cn.itcast.utils.PaymentUtil;
/**
*
* 响应银行支付结果请求
*
* **/
public class PaymentResutlResponse extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("GBK");
String merchantID=ConfigInfo.getValue("p1_MerId");//商家ID
String keyValue=ConfigInfo.getValue("keyValue");//商家密钥
//取得易宝支付返回的元数据
String sCmd=request.getParameter("r0_Cmd");//业务类型
String sResultCode=request.getParameter("r1_Code");//扣款结果,该字段值为1时,表示扣款成功。
String sTrxId =request.getParameter("r2_TrxId");//yeepay易宝交易订单号
String amount=request.getParameter("r3_Amt");//扣款金额,交易结束后,yeepay易宝交易系统将实际金额返回给客户
String currency =request.getParameter("r4_Cur");//交易币种,人民币为CNY
String productId =request.getParameter("r5_Pid");//商品ID
String orderId =request.getParameter("r6_Order");//商户订单号
String userId =request.getParameter("r7_Uid");//yeepay易宝会员ID
String mp=request.getParameter("r8_Mp");//商户扩展信息
String bType =request.getParameter("r9_BType");//交易结果通知类型,1: 交易成功回调(浏览器重定向)2: 交易成功主动通知(服务器点对点通讯)
String rb_BankId=request.getParameter("rb_BankId");//支付银行
String rp_PayDate=request.getParameter("rp_PayDate");//在线支付的时间
//取得md5加密后的字串.
String hmac = request.getParameter("hmac");//MD5交易签名
// 验证返回的数据是否合法
boolean result=PaymentUtil.verifyCallback(hmac, merchantID, sCmd, sResultCode, sTrxId, amount,
currency, productId,orderId, userId, mp, bType, keyValue);
if(result){
if("1".equals(sResultCode)) {//如果为1说明,这时候易宝支付扣款成功.
//你们这个地方应该把数据库中订单的支付状态设置成已经支付.
//2.这里一定要注意:如果是游戏点卡的话
// 那么这里只能增加一次,否则用户每刷新一次
// 浏览器点卡就会增加一部分,这样是很危险的
String message="订单号为"+orderId+"的订单支付成功了";
message+=",用户支付了"+amount+"元";
message+=",交易结果通知类型";
if("1".equals(bType)){
message += "浏览器重定向";
}else if("2".equals(bType)){
message += "易宝支付网关后台程序通知";
}
message+=",易宝订单系统中的订单号为:"+ sTrxId;
request.setAttribute("message", message);
}else{
request.setAttribute("message", "用户支付失败");
}
}else{
request.setAttribute("message", "数据来源不合法");
}
request.getRequestDispatcher("/WEB-INF/page/paymentResult.jsp").forward(request, response);
}
}
--------------------------------------------------------------------------------------------------------
12_大结局,从招行帐户中向本系统成功支付1分钱payment/WebRoot/WEB-INF/page/paymentResult.jsp
<%@ page language="java" pageEncoding="GBK"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>支付结果</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
<center>
<h3>
<font color="red">
${message }
</font>
</h3>
</center>
</body>
</html>