03、SpringBoot + 微信支付 ---- 创建订单、保存二维码url、显示订单列表

这篇具有很好参考价值的文章主要介绍了03、SpringBoot + 微信支付 ---- 创建订单、保存二维码url、显示订单列表。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Native 下单

1、创建课程订单保存到数据库

1-1:需求:

之前的下单,只是获取支付二维码,但是并没有将订单存到数据库

需求1:点击确认支付后,创建商品的订单存到数据库

需求2:每次确认支付之前,要判断这个人是否存在已下单未支付的订单,有的话就不用再创建订单了,把他的订单查询出来给他就行。

03、SpringBoot + 微信支付 ---- 创建订单、保存二维码url、显示订单列表,# SpringBoot 集成 微信支付,spring boot,微信,后端

1-2:代码:

03、SpringBoot + 微信支付 ---- 创建订单、保存二维码url、显示订单列表,# SpringBoot 集成 微信支付,spring boot,微信,后端

需求1:点击确认支付后,创建商品的订单存到数据库

03、SpringBoot + 微信支付 ---- 创建订单、保存二维码url、显示订单列表,# SpringBoot 集成 微信支付,spring boot,微信,后端

需求2:每次确认支付之前,要判断这个人是否存在已下单未支付的订单,有的话就不用再创建订单了,把他的订单查询出来给他就行。

03、SpringBoot + 微信支付 ---- 创建订单、保存二维码url、显示订单列表,# SpringBoot 集成 微信支付,spring boot,微信,后端

1-3:测试结果:

成功在数据库添加订单,并且多次点击确认下单,并不会重复添加订单到数据库

03、SpringBoot + 微信支付 ---- 创建订单、保存二维码url、显示订单列表,# SpringBoot 集成 微信支付,spring boot,微信,后端

2、保存支付二维码的url

2-1:需求:

上面创建订单的时候,是没有存二维码的url到数据库的,这里需要在创建订单的时候,把url存进去。
Native调起支付
03、SpringBoot + 微信支付 ---- 创建订单、保存二维码url、显示订单列表,# SpringBoot 集成 微信支付,spring boot,微信,后端

2-2:代码:

解释:

因为获取支付二维码url的代码在创建订单之后,所以第一次创建订单是没有支付二维码的url的。

所以在往下的代码中,添加了保存二维码的代码。
03、SpringBoot + 微信支付 ---- 创建订单、保存二维码url、显示订单列表,# SpringBoot 集成 微信支付,spring boot,微信,后端

03、SpringBoot + 微信支付 ---- 创建订单、保存二维码url、显示订单列表,# SpringBoot 集成 微信支付,spring boot,微信,后端

2-3:测试:

保存二维码成功,并且在重复访问的时候,因为存在二维码,所以不会再去调用微信的下单接口。

因为二维码有效期为2小时,所以后面还需要优化,如果二维码过期,需要再次更新数据库中的二维码。

03、SpringBoot + 微信支付 ---- 创建订单、保存二维码url、显示订单列表,# SpringBoot 集成 微信支付,spring boot,微信,后端

2-4:完整代码:

包含创建订单和保存支付二维码的代码

后端:
WxPayController
@CrossOrigin //跨域
@RestController
@RequestMapping("/api/wx-pay")
@Api(tags = "网站微信支付API") //swagger 注解
@Slf4j
public class WxPayController
{
    @Resource
    private WxPayService wxPayService;

    //调用统一下单API,生成支付二维码的链接和订单号
    //swagger注解
    @ApiOperation("调用统一下单API,生成支付二维码")
    @PostMapping("/native/{productId}")
    public R nativePay(@PathVariable Long productId) throws Exception
    {
        log.info("发起支付请求");
        //返回支付二维码的链接和订单号
        Map<String,Object> map = wxPayService.nativePay(productId);
        return R.ok().setData(map);
    }
}
WxPayService
public interface WxPayService
{
    //调用统一下单API,生成支付二维码的链接和订单号
    Map<String, Object> nativePay(Long productId) throws  Exception;
}
WxPayServiceImpl

//创建订单,调用 Native 支付接口
@Service
@Slf4j
public class WxPayServiceImpl implements WxPayService
{
    @Resource
    private WxPayConfig wxPayConfig;
    /* 原本应该注 入WxPayConfig 这个类,然后调用 getWxPayClient() 方法获取 HttpClient请求对象
     * 但是因为 getWxPayClient() 方法加了@Bean注解,交给了spring容器管理,所以项目启动的时候就会执行这个方法,
     * 就会存在返回值为 CloseableHttpClient 类型的 HttpClient请求对象
     * 所以这里可以直接注入这个 CloseableHttpClient 对象
     */
    @Resource
    private CloseableHttpClient wxPayClient;
    @Resource
    private OrderInfoService orderInfoService;

    /**
     * 创建订单,调用 Native 支付接口
     *
     * @param productId 商品id
     * @return code_url 和 订单号
     * @throws Exception
     */
    //调用统一下单API,生成支付二维码的链接和订单号
    @Override
    public Map<String, Object> nativePay(Long productId) throws Exception
    {
        //生成订单
        OrderInfo orderInfo = orderInfoService.createOrderInfoByProduct(productId);

        //获取二维码url-----如果是第一次生成订单,那么这个订单是没有二维码url的
        String codeUrl = orderInfo.getCodeUrl();
        //判断--如果订单存在,并且二维码的url也存在,那么就不需要再去调用微信的下单接口来获取支付二维码了
        if (orderInfo != null && !StringUtils.isEmpty(codeUrl))
        {
            //创建一个包含url和订单号的返回值
            Map<String, Object> map = new HashMap<>();
            map.put("codeUrl", codeUrl);
            map.put("orderNo", orderInfo.getOrderNo());
            return map;
        }



        /*
         * 官方提供的 Native下单 接口
         * 支持商户:【普通商户】
         * 请求方式:【POST】/v3/pay/transactions/native
         * 请求域名:【主域名】https://api.mch.weixin.qq.com
         * "https://api.mch.weixin.qq.com/v3/pay/transactions/native" 改成
         * wxPayConfig.getDomain().concat(WxApiType.NATIVE_PAY.getType())
         */

        log.info("调用统一下单API.....");

        //调用统一下单API---拷贝官网的实例代码进行修改---统一下单的接口地址
        //封装统一下单API 的url
        HttpPost httpPost = new HttpPost(wxPayConfig.getDomain().concat(WxApiType.NATIVE_PAY.getType()));

        // 请求body参数---------调用接口需要的参数
        Gson gson = new Gson();
        //数据类型不固定,所以就不写泛型了
        Map paramsMap = new HashMap();
        //设置参数 --- 根据官网要求设置对应的参数
        paramsMap.put("appid", wxPayConfig.getAppid()); //公众号ID
        paramsMap.put("mchid", wxPayConfig.getMchId()); //直连商户号
        paramsMap.put("description", orderInfo.getTitle()); // 商品描述
        paramsMap.put("out_trade_no", orderInfo.getOrderNo()); //商户订单号
        paramsMap.put("notify_url", wxPayConfig.getNotifyDomain().concat(WxNotifyType.NATIVE_NOTIFY.getType())); //通知地址
        //订单金额有两个参数--嵌套数据
        Map amountMap = new HashMap();
        amountMap.put("total", orderInfo.getTotalFee()); //总金额
        amountMap.put("currency", "CNY"); //货币类型
        paramsMap.put("amount", amountMap); // 订单金额

        //将参数转成字符串
        String jsonParams = gson.toJson(paramsMap);

        log.info("支付的请求参数:" + jsonParams);

        //把参数设置到请求体当中
        StringEntity entity = new StringEntity(jsonParams, "utf-8");
        entity.setContentType("application/json");
        httpPost.setEntity(entity);
        //希望得到的响应类型
        httpPost.setHeader("Accept", "application/json");

        //完成签名并执行请求
        CloseableHttpResponse response = wxPayClient.execute(httpPost);

        //这些就是对调用下单方法的响应结果的处理了
        try
        {
            //字符串形式的响应体
            String bodyAsString = EntityUtils.toString(response.getEntity());
            //响应状态码
            int statusCode = response.getStatusLine().getStatusCode();

            if (statusCode == 200)
            { //处理成功
                System.out.println("成功, 返回结果  = " + bodyAsString);
            } else if (statusCode == 204)
            { //处理成功,无返回Body
                System.out.println("成功");
            } else
            {
                System.out.println("下单失败, 响应码 = " + statusCode + ", 返回结果 = " + bodyAsString);
                throw new IOException("请求失败 request failed");
            }
            //响应结果---如果下单成功,获取响应结果,   gson.fromJson()用于将 JSON 字符串转换为 Java 对象
            Map<String, String> resultMap = gson.fromJson(bodyAsString, HashMap.class);
            //二维码---从返回的结果中获取二维码的url, 从官网看出 code_url 是 二维码的key
            codeUrl = resultMap.get("code_url");

            //保存二维码
            String orderNo = orderInfo.getOrderNo();
            orderInfoService.saveCodeUrl(orderNo,codeUrl);

            //创建一个包含url和订单号的返回值
            Map<String, Object> map = new HashMap<>();
            map.put("codeUrl", codeUrl);
            map.put("orderNo", orderInfo.getOrderNo());
            return map;
        } finally
        {
            response.close();
        }
    }
}
OrderInfoService

public interface OrderInfoService extends IService<OrderInfo> {


    /**
     * 根据商品id创建商品订单
     * @param productId 商品id
     * @return 订单对象
     */
    OrderInfo createOrderInfoByProduct(Long productId);


    /**
     * 将支付二维码的url存到订单中
     * @param orderNo 订单编号
     * @param codeUrl 支付二维码的地址url
     */
    void saveCodeUrl(String orderNo, String codeUrl);


}
OrderInfoServiceImpl

@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService
{
    @Resource
    private ProductMapper productMapper;
    @Resource
    private OrderInfoMapper orderInfoMapper;

    //创建商品订单
    @Override
    public OrderInfo createOrderInfoByProduct(Long productId)
    {
        //用户点击确认支付,要先查找该用户是否存在已下单未支付的订单
        OrderInfo orderInfo = this.getNoPayOrderByProductId(productId);
        if (orderInfo != null)
        {
            //表示该用户已经下单了,还没有支付,那就直接把他的订单返回回去就行了,否则就创建新订单
            return orderInfo;
        }
        //根据商品的id获取到该商品对象数据
        Product product = productMapper.selectById(productId);

        orderInfo = new OrderInfo();
        orderInfo.setTitle(product.getTitle()); //订单标题
        orderInfo.setOrderNo(OrderNoUtils.getOrderNo()); //生成订单号
        orderInfo.setProductId(productId); //商品id
        orderInfo.setTotalFee(1); //单位是:分
        orderInfo.setOrderStatus(OrderStatus.NOTPAY.getType()); //支付状态
        //把商品订单存到数据库
        orderInfoMapper.insert(orderInfo);
        return orderInfo;
    }

    /**
     * 根据商品id查询已下单未支付的订单,防止重复创建订单
     * @param productId 商品id
     * @return 订单对象
     */
    private OrderInfo getNoPayOrderByProductId(Long productId)
    {
        //QueryWrapper 是 MyBatis-Plus 提供的一个用于构建查询条件的工具类
        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();

        //相当于封装查询对象,这是查询条件
        //就是查询该表中,是否有 列名 product_id 对应的值等于这个 productId ,有就查询出来
        queryWrapper.eq("product_id", productId);
        queryWrapper.eq("order_status", OrderStatus.NOTPAY.getType());

        //把 queryWrapper 作为查询条件对象
        //selectOne 就是查询出一条,如果查询出多条,则会报错
        OrderInfo orderInfo = orderInfoMapper.selectOne(queryWrapper);

        return orderInfo;
    }


    /**
     * 将支付二维码的url存到订单中
     * @param orderNo 订单编号
     * @param codeUrl 支付二维码的地址url
     */
    @Override
    public void saveCodeUrl(String orderNo, String codeUrl)
    {
        //QueryWrapper 是 MyBatis-Plus 提供的一个用于构建查询条件的工具类
        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
        //组装查询条件
        queryWrapper.eq("order_no",orderNo);

        //要修改的字段,存到这个 orderInfo 对象里面
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setCodeUrl(codeUrl);

        //执行sql
        orderInfoMapper.update(orderInfo,queryWrapper);

    }

}

3、显示订单列表

3-1:需求:

在我的订单页面按时间倒序显示订单列表
目前是有订单,但是没展示出来。
03、SpringBoot + 微信支付 ---- 创建订单、保存二维码url、显示订单列表,# SpringBoot 集成 微信支付,spring boot,微信,后端

3-2:代码:

前端:

调用后端接口的是api模块

<script> 脚本模块
<template> 模板,是用来定义组件的模板部分,用于描述组件的结构和布局

03、SpringBoot + 微信支付 ---- 创建订单、保存二维码url、显示订单列表,# SpringBoot 集成 微信支付,spring boot,微信,后端

将后端返回的list商品订单列表赋值给 orders.vue 这个类后,就需要对这个数据进行渲染。
03、SpringBoot + 微信支付 ---- 创建订单、保存二维码url、显示订单列表,# SpringBoot 集成 微信支付,spring boot,微信,后端

后端:

创建一个订单的controller
03、SpringBoot + 微信支付 ---- 创建订单、保存二维码url、显示订单列表,# SpringBoot 集成 微信支付,spring boot,微信,后端

3-3:测试:

查看swagger

03、SpringBoot + 微信支付 ---- 创建订单、保存二维码url、显示订单列表,# SpringBoot 集成 微信支付,spring boot,微信,后端

查看订单列表

成功显示
03、SpringBoot + 微信支付 ---- 创建订单、保存二维码url、显示订单列表,# SpringBoot 集成 微信支付,spring boot,微信,后端文章来源地址https://www.toymoban.com/news/detail-745113.html

3-4:完整代码

后端:
OrderInfoController
@CrossOrigin //开放前端的跨域访问
@RestController
@RequestMapping(value = "/api/order-info")
@Api(tags = "商品订单管理")
public class OrderInfoController
{
    //依赖注入
    @Resource
    private OrderInfoService orderInfoService;

    @ApiOperation("显示商品订单列表")
    @GetMapping("/list")
    public R getOrderInfoList()
    {
        List<OrderInfo> list =
                orderInfoService.getOrderInfoListByCreateTimeDesc();
        return R.ok().data("list",list);
    }
}
OrderInfoService
    /**
     * 获取商品订单列表,并按时间倒序显示
     * @return 商品订单列表,倒序显示
     */
    List<OrderInfo> getOrderInfoListByCreateTimeDesc();
OrderInfoServiceImpl
    /**
     * 获取商品订单列表,并按时间倒序显示
     * @return 商品订单列表,倒序显示
     */
    @Override
    public List<OrderInfo> getOrderInfoListByCreateTimeDesc()
    {
        //QueryWrapper 是 MyBatis-Plus 提供的一个用于构建查询条件的工具类
        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
        //组装查询条件
        queryWrapper.orderByDesc("create_time");

        //查询
        List<OrderInfo> list = orderInfoMapper.selectList(queryWrapper);

        return list;
    }

到了这里,关于03、SpringBoot + 微信支付 ---- 创建订单、保存二维码url、显示订单列表的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 如何为微信小程序添加扫码支付和二维码收款功能

    微信小程序是一种轻量级的应用程序,它可以在微信客户端内运行。微信小程序支持扫码支付和二维码收款功能,以方便用户进行支付和收款。 本文将针对微信小程序的扫码支付和二维码收款功能进行详细的讲解,并提供相应的代码案例,帮助开发者了解如何为微信小程序添

    2024年02月04日
    浏览(59)
  • vue3-pc端生成微信二维码、扫码支付监听支付回调(WebSocket)功能实现

    项目场景:后台系统中采购订单列表需要支持微信扫描支付功能,支付成功需要返回到订单列表。 调用接口接收后端返回数据, npm install qrcode --save 安装插件,处理返回数据生成二维码。 1. 后端接口返回数据如下: 2. 前端代码如下: 3. 效果图如下: 生成二维码功能到这就完

    2024年02月12日
    浏览(52)
  • 一码多端,一个二维码适用微信小程序,支付宝小程序,h5页面

    最近公司研发自己的一个小程序,因为是线下树牌,涉及到扫码这个问题,但是扫码又分三个端,浏览器扫码,微信扫一扫,支付宝扫码,做这个需求也是遇到了很多坑,在此记录一下 1.扫码进入微信小程序 首先登录微信公众平台,链接 https://mp.weixin.qq.com/  原本此处会有一

    2024年02月08日
    浏览(80)
  • Taro+vue微信小程序根据字符串生成二维码图片,点击弹出图片,长按保存(可用!!!)

    效果:页面加载时生成二维码,点击二维码弹出图片,长按图片可保存。 借鉴了一个大佬的文章https://www.zhangshengrong.com/p/q0arZ9J4ax/#google_vignette

    2024年02月10日
    浏览(60)
  • 微信公众号二维码扫码登录(SpringBoot Java实现)

    用户扫描公众号的二维码,实现登录当前平台。 若未关注公众号,则关注后触发登录;若已关注,则直接登录。  登录时通过union_id判断用户是否在系统注册,若未注册则跳转到注册页面或提示未注册。 注意,此功能使用的接口,需要 公众号类型为 服务号 才支持! 开发阶

    2024年02月12日
    浏览(50)
  • 西米支付:支付二维码的简单介绍

    二维码支付从1.0到3.0时代的历史进程 实际上二维码技术被推出来已经有十多年了,这段悠久绵长的英雄无用武之地的时代属于二维码1.0时代,得益于互联网电子商务的飞速发展首先将二维码应用于支付并发扬光大的是两个第三方支付公司,支付宝微信,这种新型的支付方式支

    2024年02月01日
    浏览(44)
  • 【Uniapp】支付链转二维码

    提示:这个是一个很小的项目,大概30分钟就能搞定 实现方式:输入支付代码,存储到对应的数据库表中,二维码访问一个PHP文件通过id来进行重定向,这样就可以使每张二维码都是固定的,替换二维码内容也只需改数据库的即可 提示:以下代码需要导入B-ui插件,或者在页面

    2024年02月14日
    浏览(46)
  • uniapp小程序---二维码(生成、保存)

    JS库介绍 uniapp中生成二维码这里推荐使用 uQRCode ,uQRCode是一款基于 Javascript环境 开发的二维码生成插件, 适用所有Javascript运行环境 的前端应用和Node.js应用。 同时uQRCode可 扩展性高 ,它支持 自定义渲染二维码 ,可通过uQRCode API得到二维码绘制关键信息后,使用canvas、svg或

    2024年02月08日
    浏览(44)
  • uniapp(微信小程序/支付宝小程序) - 最新解决canavs绘制海报、二维码图片等不显示问题,在uniapp小程序开发中使用canavs制作base64图片在真机运行时空白不显示(详细解决方法)

    在uniapp微信小程序 | uniapp支付宝小程序中,详解canavs技术绘制图像后在真实手机上运行不显示的问题,解决uniapp安卓苹果ios运行小程序后二维码/海报无法加载和展示,完美解决兼容问题、图片太大画不出来、加载失败等。支持保存到相册中或长按保存。 很多教程都无效,本

    2024年04月25日
    浏览(53)
  • JAVA支付宝小程序授权登陆,并生成二维码(证书方式)

    接入准备 https://opendocs.alipay.com/open/284/106001?ref=api 根据文档进行创建小程序、配置相关信息(接口加签方式选择证书) 生成二维码文档https://opendocs.alipay.com/mini/02owto 开发接口

    2024年02月11日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包