• 第三方支付之支付宝(电脑网站支付)



     
    第一步:蚂蚁金服开放平台注册账号
    该步骤的详细流程请参考蚂蚁金服官方说明,本示例主要关注Java后台代码的实现
     
    第二步:下载SDK,安装到本地或远程Maven仓库
     
    1. 进入下载的SDK的如下目录
    alipay.trade.page.pay-JAVA-UTF-8WebContentWEB-INFlib
     
    2. 安装alipay-sdk-javaXXX.jar
    mvn install:install-file -Dfile=D:alipay.trade.page.pay-JAVA-UTF-8WebContentWEB-INFlib alipay-sdk-java20170324180803.jar -DgroupId=com.bounter -DartifactId=bounter-alipay -Dversion=1.0.RELEASE -Dpackaging=jar
     
    第三步:创建第三方支付Maven项目
     
    1. 添加Maven依赖(这里支付宝的依赖包为上一步安装在本地的Jar)
    <!-- alipay -->
    <dependency>
       <groupId>com.bounter</groupId>
       <artifactId>bounter-alipay</artifactId>
       <version>1.0.RELEASE</version>
    </dependency>
    2. 创建支付宝支付的控制器、JSP页面
     
         2.1 实现支付接口(简单的跳转到支付页面)
    /**
     * 支付接口
     * @param order
     * @return
     * @throws Exception
     */
    @PostMapping("/alipay/pay")
    public String pay(AlipayOrder order) throws Exception {
       //跳转到支付页面
       return "alipay.payPage";
    }

      2.2 创建支付页面(这里我直接拿的官方Demo里的页面修改而来,核心代码如下;该支付页面请求支付成功后会生成一个支付的二维码)

    //获得初始化的AlipayClient
    AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
    
    //设置请求参数
    AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
    //设置付款成功后的同步通知的页面
    alipayRequest.setReturnUrl(AlipayConfig.return_url);
    alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
    
    //商户订单号,商户网站订单系统中唯一订单号,必填
    String out_trade_no = new String(request.getParameter("out_trade_no"));
    //付款金额,必填
    String total_amount = new String(request.getParameter("total_amount"));
    //订单名称,必填
    String subject = new String(request.getParameter("subject"));
    //商品描述,可空
    String body = new String(request.getParameter("body"));
    
    alipayRequest.setBizContent("{"out_trade_no":""+ out_trade_no +"","
          + ""total_amount":""+ total_amount +"","
          + ""subject":""+ subject +"","
          + ""body":""+ body +"","
          + ""product_code":"FAST_INSTANT_TRADE_PAY"}");
    
    //请求
    String result = alipayClient.pageExecute(alipayRequest).getBody();
    
    //输出
    out.println(result);

      2.3 创建扫码支付成功后的回调接口和页面( 回调的URL必须公网可以访问,测试时可以使用花生壳等工具映射一个公网地址;成功页面可根据自己公司业务创建)

    /**
         * 付款成功后同步跳转到商家页面
         * @return
         */
        @RequestMapping("/return_url")
        public String returnPage() {
            return "alipay.paySuccess";
        }

      2.4 创建支付成功异步回调的接口( 回调的URL必须公网可以访问,测试时可以使用花生壳等工具映射一个公网地址;支付是否成功以此回调为准,可以在这里实现支付成功后的业务处理,该结果不需要反馈给用户)

    /**
         * 支付结果异步通知,POST方式,支付结果以异步通知内容为准
         * @return
         * @throws Exception 
         */
        @PostMapping("/notify_url")
        public void notifyUrl(HttpServletRequest request, HttpServletResponse response) throws Exception {
            //获取支付宝POST过来反馈信息
            Map<String,String> params = new HashMap<String,String>();
            Map<String,String[]> requestParams = request.getParameterMap();
            for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
                String name = (String) iter.next();
                String[] values = (String[]) requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i]
                            : valueStr + values[i] + ",";
                }
                params.put(name, valueStr);
            }
            
            //验签
            boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名
    
            /* 实际验证过程建议商户务必添加以下校验:
            1、需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
            2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
            3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
            4、验证app_id是否为该商户本身。
            */
            if(signVerified) {//验证成功
                //商户订单号
                String out_trade_no = new String(request.getParameter("out_trade_no"));
                //交易状态
                String trade_status = new String(request.getParameter("trade_status"));
                
                //验证该通知数据中的out_trade_no是否为商户系统中创建的订单号
                AlipayOrder order =  alipayService.getOrder(out_trade_no);
                if(order != null) {
                    //TODO:更新订单
                    if(trade_status.equals("TRADE_FINISHED")){
                        //判断该笔订单是否在商户网站中已经做过处理
                        //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                        //如果有做过处理,不执行商户的业务程序
                            
                        //注意:
                        //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
                    }else if (trade_status.equals("TRADE_SUCCESS")){
                        //判断该笔订单是否在商户网站中已经做过处理
                        //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                        //如果有做过处理,不执行商户的业务程序
                        
                        //注意:
                        //付款完成后,支付宝系统发送该交易状态通知
                    }
                    System.out.println("success");
                    //通知支付宝交易成功,否则支付宝会一直尝试异步通知
                    response.getWriter().println("success");
                }
            } else {
                System.out.println("fail");
                response.getWriter().println("fail");
            }
        }

      2.5 实现交易退款接口

    /**
         * 统一收单交易退款接口 
         * @param order
         * @return
         * @throws Exception
         */
        @PostMapping("/alipay/refund")
        public void refund(AlipayOrder order, HttpServletResponse response) throws Exception {
            //创建退款请求,设置请求参数
            AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();
            
            alipayRequest.setBizContent("{"out_trade_no":""+ order.getOut_trade_no() +""," 
                    + ""trade_no":""+ order.getTrade_no() +""," 
                    + ""refund_amount":""+ order.getRefund_amount() +""," 
                    + ""refund_reason":""+ order.getRefund_reason() +""," 
                    + ""out_request_no":""+ order.getOut_request_no() +""}");
            
            //调用SDK发起请求
            String result = alipayClient.execute(alipayRequest).getBody();
            
            //TODO:解析返回对象,更新系统订单状态
            
            //输出
            response.getWriter().println(result);
        }
    至此,一个包含支付和退款功能的后台接口就做完了,下面就进行简单的测试
     
     
    第四步:测试支付和退款
     
    1. 运行项目 mvn jetty:run
     
    2. 浏览器输入:http://localhost:8080 打开测试首页(直接拿的官方Demo页面)
     
    3. 测试支付
     
    4. 测试退款
     
    说明:当前项目仅实现了简单的支付和退款功能,代码大部分搬自官方示例,并不包括完整的支付流程,有什么不明白的地方,欢迎留言
  • 相关阅读:
    Objective-C-使用NSMutableURLRequest发送POST请求,使用NSJSONSerialization解析JSON字符串
    js showModalDialog打开新的页面给原页面传值问题
    svn2git使用小记
    模拟等待事件row lock waits
    URAL 1994 The Emperor's plan 求组合数 大数用log+exp处理
    struts总结
    URAL 1992 CVS 链表
    android游戏物理引擎开发——粒子系统(三)
    状态模式与上机
    OpenCV——凸包
  • 原文地址:https://www.cnblogs.com/gdufs/p/7230897.html
Copyright © 2020-2023  润新知