• 记一次微信支付走过的坑


     起因:公司平台网站需要接入微信支付

     经过:有了新的需求后,作为最底层的码农,只能想办法去码出代码。什么都不管,先看官方文档。

        最后使用,扫码支付中模式二的支付方式。商户后台系统先调用微信支付的统一下单接口,微信后台系统返回链接参数code_url,商户后台系统将code_url值生成二维码图片,用户使用微信客户端扫码后发起支付。注意:code_url有效期为2小时,过期后扫码不能再发起支付。

               支付流程图

       

       选定模式后,查看api,设置请求参数,接收到code_url,生成二维码,支付。到这都没有问题

       接下来问题来了,支付完成后,微信会异步回调商户网址(notify_url),在这一步出现了几个问题:

        1.使用request接收不到返回参数

                   2.(在问题1解决后)接收到的参数出现乱码

        3.我们在处理完异步回调的业务逻辑后,需要同步返回信息给微信(文档中为一段xml

    <xml>
      <return_code><![CDATA[SUCCESS]]></return_code>
      <return_msg><![CDATA[OK]]></return_msg>
    </xml>

    ),表明支付成功,否则微信会多次请求你的回调地址。我试用response对象输出,结果微信一直会回调我的地址

    经过多方支援,以上问题终得解决,解决方式如下:

       1.微信回调的时候,参数信息是在流中,需要通过流来接收

       2.在接收流的时候,做一次格式化

      3.同步通知微信,任然需要时试用流的方式

      下面贴出代码:

           

     @RequestMapping(value = "/test/wxpaytest6")
        public void wxPay(HttpServletRequest request, HttpServletResponse response) {
            BufferedReader bis = null;
            try {
                bis = new BufferedReader(new InputStreamReader(request.getInputStream(),"UTF-8"));
    
                String line = null;
                String result = "";
    
    
                while ((line = bis.readLine()) != null) {
                    result += line + "
    ";
                }
                Map<String, String> map = WXPayUtil.xmlToMap(result);
    
                //签名验证
                boolean signFlag = WXPayUtil.isSignatureValid(map, BTWXPayConfig.getInstance().getKey());
                System.out.println(signFlag);
                System.out.println(map.get("out_trade_no"));
                System.out.println(map.get("result_code"));
                System.out.println(map.get("return_code"));
    
            //试用流输出
                BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
                out.write("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>".getBytes());
                out.flush();
                out.close();
    
    //无效代码
    //            response.setContentType("text/xml");
    //            response.getWriter().write("<xml>" +
    //                    "<return_code><![CDATA[SUCCESS]]></return_code>" +
    //                    "<return_msg><![CDATA[OK]]></return_msg>" +
    //                    "</xml>");
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
    
            }
        }

    至此,结尾。

  • 相关阅读:
    C#基础系列——一场风花雪月的邂逅:接口和抽象类
    C#进阶系列——动态Lamada(二:优化)
    C#进阶系列——动态Lamada
    JS组件系列——Bootstrap Table 表格行拖拽(二:多行拖拽)
    JS组件系列——Bootstrap Table 表格行拖拽
    C#进阶系列——DDD领域驱动设计初探(七):Web层的搭建
    C#进阶系列——MEF实现设计上的“松耦合”(四):构造函数注入
    C#进阶系列——DDD领域驱动设计初探(六):领域服务
    C#进阶系列——DDD领域驱动设计初探(五):AutoMapper使用
    C#进阶系列——DDD领域驱动设计初探(四):WCF搭建
  • 原文地址:https://www.cnblogs.com/nww57/p/7144564.html
Copyright © 2020-2023  润新知