前言:
上一篇文章中(【在线支付】在线支付流程分析)说道,为了保证数据安全,网站把源数据和hmac码发送到第三方,那么,在代码中是如何实现的呢?接收到付款成功的消息,又是如何响应的呢?以向易宝支付为例
1、向易宝发送支付请求
导入算法工具类PaymentUtil
import cn.itcast.utils.PaymentUtil;
public class PayServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取的支付信息:ID,交易金额,订单号 String orderid = request.getParameter("orderid"); String money = request.getParameter("money"); String pd_Id = request.getParameter("pd_FrpId"); //源数据的规范,顺序不能变(参见“易宝支付产品通用接口帮助文档”支付请求参数说明) String p0_Cmd = "Buy"; //业务类型 String p1_MerId = "10001126856";// 商户编号(银行卡号),向此卡号支付 String p2_Order = orderid; //商户订单号 String p3_Amt = money; // 付款金额 String p4_Cur = "CNY"; // 交易币种 String p5_Pid = ""; // 商品名称 String p6_Pcat = ""; // 商品种类 String p7_Pdesc = ""; // 商品描述 String p8_Url = "http://localhost/day20pay/callback"; // 商户接收支付成功数据的地址 String p9_SAF = ""; // 送货地址 String pa_MP = ""; // 商户扩展信息 String pd_FrpId = this.pd_FrpId;// 支付通道编码 String pr_NeedResponse = "1"; // 应答机制 //秘钥(在算法工具类PaymentUtil中,需用到秘钥) String keyValue = "69cl522AV6q613Ii4W6u8K6XuW8vM1N6bFgyv769220IuYe9u37N4y7rI4Pl"; //根据源数据生成hmac码 String hmac = PaymentUtil.buildHmac(p0_Cmd, p1_MerId, p2_Order, p3_Amt, p4_Cur, p5_Pid, p6_Pcat, p7_Pdesc, p8_Url, p9_SAF, pa_MP, pd_FrpId, pr_NeedResponse, keyValue); // 将所有参数 发送给 易宝指定URL request.setAttribute("pd_FrpId", pd_FrpId); request.setAttribute("p0_Cmd", p0_Cmd); request.setAttribute("p1_MerId", p1_MerId); request.setAttribute("p2_Order", p2_Order); request.setAttribute("p3_Amt", p3_Amt); request.setAttribute("p4_Cur", p4_Cur); request.setAttribute("p5_Pid", p5_Pid); request.setAttribute("p6_Pcat", p6_Pcat); request.setAttribute("p7_Pdesc", p7_Pdesc); request.setAttribute("p8_Url", p8_Url); request.setAttribute("p9_SAF", p9_SAF); request.setAttribute("pa_MP", pa_MP); request.setAttribute("pr_NeedResponse", pr_NeedResponse); request.setAttribute("hmac", hmac); request.getRequestDispatcher("/confirm.jsp").forward(request, response); }
2、付款成功后,回调程序
public class CallbackServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 验证请求来源和数据有效性 // 阅读支付结果参数说明 // System.out.println("=============================================="); String p1_MerId = request.getParameter("p1_MerId"); String r0_Cmd = request.getParameter("r0_Cmd"); String r1_Code = request.getParameter("r1_Code"); String r2_TrxId = request.getParameter("r2_TrxId"); String r3_Amt = request.getParameter("r3_Amt"); String r4_Cur = request.getParameter("r4_Cur"); String r5_Pid = request.getParameter("r5_Pid"); String r6_Order = request.getParameter("r6_Order"); String r7_Uid = request.getParameter("r7_Uid"); String r8_MP = request.getParameter("r8_MP"); String r9_BType = request.getParameter("r9_BType"); String rb_BankId = request.getParameter("rb_BankId"); String ro_BankOrderId = request.getParameter("ro_BankOrderId"); String rp_PayDate = request.getParameter("rp_PayDate"); String rq_CardNo = request.getParameter("rq_CardNo"); String ru_Trxtime = request.getParameter("ru_Trxtime"); // hmac String hmac = request.getParameter("hmac"); // 利用本地密钥和加密算法 加密数据 String keyValue = "69cl522AV6q613Ii4W6u8K6XuW8vM1N6bFgyv769220IuYe9u37N4y7rI4Pl"; boolean isValid = 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 (isValid) { // 有效 if (r9_BType.equals("1")) { // 浏览器重定向 response.setContentType("text/html;charset=utf-8"); response.getWriter().println( "支付成功!订单号:" + r6_Order + "金额:" + r3_Amt); } else if (r9_BType.equals("2")) { // 服务器点对点,来自于易宝的通知 System.out.println("收到易宝通知,修改订单状态!");// // 回复给易宝success,如果不回复,易宝会一直通知 response.getWriter().print("success"); } } else { throw new RuntimeException("数据被篡改!"); } } }
整个支付的思路很简单,发送请求和支付后相应,具体的解释,还是要看代码注释,顺着代码走一遍,就可以理清了。
参考:《网上商城SSH》,在线支付demo