• 微信扫码支付功能(1)---通过谷歌二维码工具生成付款码


    生成付款二维码

    一、微信网站扫码支付介绍

       1、扫码支付文档

       微信开发官方文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5

      有关微信支付的流程图微信官方已经说的很清楚了,这里也无需其它解释。这边采用微信支付扫码模式二(不依赖商户平台设置回调url),所以在生成二维码之前

    要先调用微信统一下单支付接口,获得code_url,再通过谷歌二维码工具将code_url生成二维码图片。

        2、名称理解

    在微信扫码支付功能开发之前,首先要获得微信认证而得到的一些信息如下:

    开发者账户信息

    公众号 appid: wx0pi2m4x6we76140w

    公众号 appsecret: x82552d8w0y1i161lp9o7821s5d7osry

    商户号 mer_id: 5731202714

    支付    key: PL9wT9n9Ljav4zSN66J0bmzT1Yl54429

        3、和微信支付交互方式

    (1)、post方式提交

      (2)、xml格式的协议

      (3)、签名算法MD5

      (4)、接口交易单位为 分

      (5)、交易类型:JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付

      (6)、商户订单号规则:

          商户支付的订单号由商户自定义生成,仅支持使用字母、数字、中划线-、下划线_、竖线|、星号*这些英文半角字符的组合,请勿使用汉字或全角等特殊字符,

    微信支付要求商户订单号保持唯一性

       (7)、安全规范:

        签名算法:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=4_3

        校验工具:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=20_1

       (8)、采用微信支付扫码模式二(不依赖商户平台设置回调url)

    二、实战开发

       1、点击购买商品调用接口

    接口需要接收购买商品ID,用户ID,返回的就是二维码图片供用户扫码支付。

    /**
     * 订单接口
     */
    @RestController
    @RequestMapping("/api/v1/order")
    public class OrderController {
    
        @Autowired
        private VideoOrderService videoOrderService;
    
        /**
         * 用户点击购买下单接口
         */
        @GetMapping("buy")
        public void saveOrder(@RequestParam(value = "video_id",required = true)int videoId,
                                  HttpServletRequest request,
                                  HttpServletResponse response) throws Exception {
    
            /**
             * 实际开发需要获取用户id和用户当前ip,这里临时写死的配置
             * String ip = IpUtils.getIpAddr(request);
             * int userId = request.getAttribute("user_id");
             */
            int userId = 1;
            String ip = "120.25.1.43";
            //1、根据用户id和商品id生成订单
            VideoOrderDto videoOrderDto = new VideoOrderDto();
            videoOrderDto.setUserId(userId);
            videoOrderDto.setVideoId(videoId);
            videoOrderDto.setIp(ip);
    
            //2、保存订单同时返回codeUrl
            String codeUrl = videoOrderService.save(videoOrderDto);
            if(codeUrl == null) {
                throw new  NullPointerException();
            }
    
            //3、通过google工具生成二维码供用户扫码支付
             try{
                //3、1生成二维码配置
                Map<EncodeHintType,Object> hints =  new HashMap<>();
    
                //3、2设置纠错等级
                hints.put(EncodeHintType.ERROR_CORRECTION,ErrorCorrectionLevel.L);
    
                //3、3编码类型
                hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");
    
                BitMatrix bitMatrix = new MultiFormatWriter().encode(codeUrl,BarcodeFormat.QR_CODE,400,400,hints);
                OutputStream out =  response.getOutputStream();
    
                MatrixToImageWriter.writeToStream(bitMatrix,"png",out);
    
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

      2、进入VideoOrderService具体业务实现类

    该类的主要业务逻辑是:

     (1)通过商品ID查询是否有该商品信息

     (2)通过用户ID查询是否存在该用户

     (3)如果上面两步没有问题,则生成用户订单信息保存到数据库中

        @Override
        @Transactional(propagation = Propagation.REQUIRED)
        public String save(VideoOrderDto videoOrderDto) throws Exception {
    
            //1、查找商品信息(这里商品指的是视频课程)
            Video video =  videoMapper.findById(videoOrderDto.getVideoId());
    
            //2、查找用户信息
            User user = userMapper.findByid(videoOrderDto.getUserId());
    
            //3、生成订单,插入数据库
            VideoOrder videoOrder = new VideoOrder();
            videoOrder.setTotalFee(video.getPrice());
            videoOrder.setVideoImg(video.getCoverImg());
            videoOrder.setVideoTitle(video.getTitle());
            videoOrder.setCreateTime(new Date());
            videoOrder.setVideoId(video.getId());
            videoOrder.setState(0);
            videoOrder.setUserId(user.getId());
            videoOrder.setHeadImg(user.getHeadImg());
            videoOrder.setNickname(user.getName());
            videoOrder.setDel(0);
            videoOrder.setIp(videoOrderDto.getIp());
            videoOrder.setOutTradeNo(CommonUtils.generateUUID());
    
            videoOrderMapper.insert(videoOrder);
    
            //4、获取codeurl
            String codeUrl = unifiedOrder(videoOrder);
    
            return codeUrl;
        }

         3、回调微信统一下单接口,获取codeurl方法主要逻辑

    微信官方统一下单接口文档说明: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1

      (1)  根据接口需求添加所需参数:比如appid,mch_id,body等等......

    (2)sign签名获取:具体获取规则官方已经说明: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=4_3

      (3) 通过工具类将map集合转为xml格式字符串

    (4)回调微信统一下单接口,接口地址:https://api.mch.weixin.qq.com/pay/unifiedorder

    5)如果上一步成功(成功标志返回SUSSCUSS),则将返回成功的xml格式再通过工具类转为map

    (6)通过key=code_url,获取value字符串,这也是最终生成二维码的字符串。code_url格式大致为:weixin://wxpay/s/An4baqw

    接下来只要将code_url值变成二维码就可以供用户扫码付款了。

        4、测试

      调用http://localhost:8081/api/v1/order/buy?video_id=1接口

      成功返回二维码:code_url有效期是两个小时

     微信扫码之后:看到具体信息

     

    再看数据库该商品信息:

    github源码

    github: https://github.com/yudiandemingzi/spring-boot-wechat-pay

    我只是偶尔安静下来,对过去的种种思忖一番。那些曾经的旧时光里即便有过天真愚钝,也不值得谴责。毕竟,往后的日子,还很长。不断鼓励自己,

    天一亮,又是崭新的起点,又是未知的征程(上校16)

      

  • 相关阅读:
    分析建模中的行为分析
    SOLID总结(未完待续)
    分析建模的五个子过程中为什么有个编码子过程?
    用例建模的五个子过程
    类之间的关系
    python cx_Freeze安装详解、打包exe文件简解
    pyautoit:OSError: [WinError 193] %1 不是有效的 Win32 应用程序
    Python 动态导入类并运行其中的方法
    比较2个字符串,输出看起来一样,但比较起来不同
    pyautogui 文档(五):截图及定位功能
  • 原文地址:https://www.cnblogs.com/qdhxhz/p/9708534.html
Copyright © 2020-2023  润新知