• javaEE(9)_在线支付


    一、目前主要的两种支付方案

    二、支付流程

    1、用户在提交订单完成选择易宝支付按钮后,会跳转到如下页面选择要支付的银行,如下所示:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>在线支付</title>
      </head>
      <body>
            <form action="${pageContext.request.contextPath }/servlet/PayRequestServlet" method="post">
              您的订单是:<input type="text" name="orderid">
              订单的金额是:<input type="text" name="money">
              <table width="60%">
                <tr><td><br/></td></tr>
                <tr>
                    <td>请您选择在线支付银行</td>
                </tr>
                <tr>
            //这些银行编码是易宝提供的 <td><INPUT TYPE="radio" NAME="pd_FrpId" value="CMBCHINA-NET">招商银行 </td> <td><INPUT TYPE="radio" NAME="pd_FrpId" value="ICBC-NET">工商银行</td> <td><INPUT TYPE="radio" NAME="pd_FrpId" value="ABC-NET">农业银行</td> <td><INPUT TYPE="radio" NAME="pd_FrpId" value="CCB-NET">建设银行 </td> </tr> <tr> <td><INPUT TYPE="submit" value="确定支付"></td> </tr> </table> </form> </body> </html>

    2、网站按照易宝接口文档构建请求地址:

    //处理支付请求
    public class PayRequestServlet extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            String p0_Cmd = "Buy";
            String p1_MerId = PayConfig.getValue("p1_MerId");
            String p2_Order = request.getParameter("orderid");
            String p3_Amt = request.getParameter("money");
            String p4_Cur = "CNY";
            String p5_Pid = "";
            String p6_Pcat = "";
            String p7_Pdesc = "";
            String p8_Url = PayConfig.getValue("responseURL");
            String p9_SAF = "";
            String pa_MP = "";
            String pd_FrpId = request.getParameter("pd_FrpId");
            String pr_NeedResponse = "1";
            String keyValue = PayConfig.getValue("keyValue");
            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);
    
            // 构建请求地址
            String requestUrl = "https://www.yeepay.com/app-merchant-proxy/node?p0_Cmd="
                    + p0_Cmd + "&p1_MerId=" + p1_MerId;// 后面的省略
    
            request.getRequestDispatcher(requestUrl).forward(request,response);
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    }
    //支付配置文件
    p1_MerId=10001126856   //商户编号
    keyValue=69cl522AV6q613Ii4W6u8K6XuW8vM1N6bFgyv769220IuYe9u37N4y7rI4Pl //密钥
    responseURL=http://localhost:8080/payment/servlet/PaymentResponse    //易宝支付成功后通知网站的地址

    ps:

    1>p1_MerId: 商户编号,申请易宝账户的时候易宝会给.

    2>p8_Url: 商户接收支付成功数据的地址,也就是易宝支付成功后通知网站的地址,注意:如不填p8_Url的参数值支付成功后您将得不到支付成功的通知.

    3>pd_FrpId: 支付通道编码,也就是用户选择的银行编码.

    4>pr_NeedResponse: 应答机制,固定值为"1": 需要应答机制; 收到易宝支付服务器点对点支付成功通知,必须回写以"success"(无关大小写)开头的字符串,即使您收到成功通知时发现该订单已经处理过,也要正确回写"success",否则易宝支付将认为您的系统没有收到通知,启动重发机制,直到收到"success"为止.

    5>hmac: 用户发的数据拼成字符串再结合易宝给的密钥再md5(申请易宝账户的时候易宝会给)算出的一个hmac码,易宝会给这个工具类,用以确定网站发给易宝的数据没有被串改.

    3、只有支付成功时易宝支付才会通知商户.支付成功回调有两种,都会以GET形式通知到在线支付请求参数中的p8_Url上:

    ■ 浏览器重定向
    ■ 服务器点对点通讯
    关于两种通知和业务处理说明:如果用户在支付成功后,并没有通知商家而是直接关闭了重定向的窗口,那么重定向就不会通知到商户,网站的订单状态就不会置为已支付,所以不管用户是否重定向通知到商户,服务器点对点通知都会通知到商户,所以在callback页中r9_btype=1和r9_btype=2的两种通知类型中都要进行业务处理.并注意处理重复订单的问题,以防两次通知都处理了相同的业务造成损失.
    //支付成功响应地址
    public class PaymentResponse extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            String p1_MerId = PayConfig.getValue("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 hmac = request.getParameter("hmac");
    
            String keyValue = PayConfig.getValue("keyValue");
    
            boolean b = 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 (!b) {
                response.getWriter().write("交易签名已被修改!!!");
                return;
            }
    
            if ("1".equals(r1_Code)) { // 处理支付成功
                if ("1".equals(r9_BType)) {
                    response.getWriter().write("支付成功!!");
                    return;
                }
                if ("2".equals(r9_BType)) {
                    response.getWriter().write("success");
                }
            }
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    }

    ps:

    1>r1_Code: 支付结果.

    2>r9_BType: 交易结果返回类型: 为"1": 浏览器重定向; 为"2": 服务器点对点通讯.

    3>hmac: 网站需要确定易宝发送的数据没有被串改.

    三、具体支付流程图和易宝文档参考文件.

  • 相关阅读:
    【API知识】类型转换工具ConvertUtils引发的思考
    【API知识】MongoTemplate非映射方式操作Document
    python+scrapy分析博客园首页4000篇优质博客(图解)
    px和dp(内含大量的像素单位详解)
    【惊!】代码中出现“//保重,兄弟!”
    用故事解析setTimeout和setInterval(内含js单线程和任务队列)
    css_transition_animation(内含贝赛尔曲线详解)
    你绝对不知道的head标签
    css3的@media
    安利一个免费下载VIP文档神器
  • 原文地址:https://www.cnblogs.com/wangweiNB/p/5070097.html
Copyright © 2020-2023  润新知