微信native支付

本文介绍了如何通过微信统一下单API进行Native支付,包括获取prepay_id和code_url,前端生成二维码,以及后端处理支付订单状态查询。同时展示了前端使用jQuery实现用户扫码支付后的交互逻辑和支付状态跟踪。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

微信native支付同样调用微信统一下单api,返回prepay_id (支付订单id) 和code_url(扫码支付的链接),把code_url返回给前端,前端生成二维码,用户扫码支付,也可以后端生成

@PostMapping("/nativePayOrder")
    @ApiOperation("微信Native支付")
    public R nativePayOrder(@RequestBody PayOrderForm form, @RequestHeader HashMap<String,Object> map) {
        ValidatorUtils.validateEntity(form);
        String token = map.get("token").toString();
        Integer userId = Integer.parseInt(jwtUtils.getClaimByToken(token).getSubject());
        LambdaQueryWrapper<UserEntity> uew = new LambdaQueryWrapper<>();
        uew.eq(UserEntity::getUserId, userId);
        UserEntity user = userService.getOne(uew);
        if (user == null) {
            return R.error("用户不存在!");
        }
        LambdaQueryWrapper<Order> oew = new LambdaQueryWrapper<>();
        Integer orderId = form.getOrderId();
        oew.eq(Order::getId, orderId);
        Order order = orderService.getOne(oew);
        if (order == null) {
            return R.error("该用户没有此订单!");
        }
        if (!Objects.equals(order.getStatus(), EnumUtil.PAY_STATUS_NO_PAY.getCode())) {
            return R.error("该订单已支付!");
        }
        //判断优惠券是否过期


        //判断活动是否过期


        //向微信平台发送创建支付订单的请求

        try {
            //微信支付的单位是分,要转换一下
            String amount = String.valueOf(order.getAmount().multiply(BigDecimal.valueOf(100)).intValue());
            WXPay wxPay = new WXPay(wxPayConfig);
            Map<String, String> paramMap = new HashMap<>();
            String nonceStr = WXPayUtil.generateNonceStr();
            paramMap.put("nonce_str", nonceStr);    //随机字符串
            paramMap.put("body", "商品备注信息");
            paramMap.put("out_trade_no", order.getCode());   //商品订单流水号,必须为一
            paramMap.put("total_fee", amount);              //订单金额
            paramMap.put("spbill_create_ip", "127.0.0.1");
            paramMap.put("notify_url", "127.0.0.1/notify"); //异步通知url  必须为外网地址
            paramMap.put("trade_type", "NATIVE");            //交易类型
            String sign = WXPayUtil.generateSignature(paramMap, wxConfiguration.getMchKey());
            paramMap.put("sign", sign);
            Map<String, String> result = wxPay.unifiedOrder(paramMap);
            log.info("result:{}",result);
            //支付订单Id
            String prepayId = result.get("prepay_id");
            String codeUrl = result.get("code_url");
            if (StringUtils.isNotBlank(prepayId)) {
                order.setPrepayId(prepayId);
                orderService.updateById(order);
            }else {
                log.error("微信支付出现异常,订单号:{}",orderId);
                return R.error("微信支付出现异常,订单号:{}" + orderId);
            }
            Map<String, Object> map1 = new HashMap<>();
            map1.put("codeUrl", codeUrl);
            return R.ok(map1);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("微信支付出现异常,订单号:{}",orderId);
            return R.error("微信支付出现异常,订单号:{}" + orderId);
        }
    }

    @GetMapping("/qrcode")
    @ApiOperation("根据前端传过来的codeUrl生成二维码图片")
    public void qrCode(HttpServletRequest request,HttpServletResponse response) throws IOException {
        String codeUrl = request.getParameter("codeUrl");
        QrConfig qrConfig = new QrConfig();
        qrConfig.setHeight(250);
        qrConfig.setWidth(250);
        qrConfig.setMargin(2);
        OutputStream outputStream = response.getOutputStream();
        QrCodeUtil.generate(codeUrl,qrConfig,"jpg",outputStream);
        outputStream.close();
    }

前端代码使用jquery编写
用户扫码支付完成之后,前端使用定时器调用后端接口查询支付订单状态,然后刷新页面,或者用户点击<我已支付>按钮查询支付订单状态进行页面跳转刷新

$(function () {
//查询遍历订单
  $.ajax({
    url: wxUrl.searchUserOrderList,
    type: 'post',
    dataType: 'json',
    contentType: 'application/json',
    beforeSend: function (request) {
      request.setRequestHeader('token', localStorage.getItem('token'));
    },
    data: JSON.stringify({
      pageNum: 1,
      pageSize: 20,
    }),
    success(res) {
      let list = res.list;
      console.log(list);
      let temp = '';
      for (let one of list) {
        if (one.status === 1) {
          one.status = '未付款';
        } else if (one.status == 2) {
          one.status = '已付款';
        } else if (one.status == 3) {
          one.status = '已发货';
        } else if (one.status == 4) {
          one.status = '已签收';
        }
        let button = '';
        if (one.status == '未付款') {
          button = '<input type="button" value="支付" class="pay-btn">';
        }
        temp += `
          <div class="order" data-order-id=${one.id}>
				      <div class="row row-1">
					      <span>订单编号:${one.code}</span>
					      <span>${one.status}</span>
				      </div>
				      <div class="row row-2">
					        假设这里是商品订单概要信息
				      </div>
				      <div class="row row-3">
					    <div>
						     金额:<span>${one.amount}元</span>
					    </div>
              ${button}
				     </div>
			  </div>
          `;
      }
      $('.order-list').append(temp);
      // 给支付按钮绑定点击事件
      $('.pay-btn').click(function () {
        let orderId = $(this).parents('.order').data('order-id');
        $.ajax({
          url: wxUrl.nativePayOrder,
          type: 'post',
          dataType: 'json',
          contentType: 'application/json',
          beforeSend: function (request) {
            request.setRequestHeader('token', localStorage.getItem('token'));
          },
          data: JSON.stringify({
            orderId: orderId,
          }),
          success(res) {
            console.log(res);
            let codeUrl = res.codeUrl;
            $('.qrcode').attr('src', wxUrl.qrcode + '?codeUrl=' + codeUrl);
            // 添加自定义属性  orderId
            $('.close-btn').attr('data-order-id', orderId);
            $('#native').show();
            /* 创建一个定时器,调用后端查询支付订单状态,最多执行5次 */
            let num = 0;
            let timer = setInterval(() => {
              num++;
              let result = searchOrderStatus(orderId);
              if (result) {
                clearInterval(timer);
                location.reload();
              } else {
                if (num == 5) {
                  clearInterval(timer);
                }
              }
            }, 5000);
          },
        });
      });
    },
  });
  /* 查询支付订单状态 */
  function searchOrderStatus(orderId) {
    let flag = false;
    $.ajax({
      url: wxUrl.searchOrderStatus,
      type: 'post',
      dataType: 'json',
      contentType: 'application/json',
      // 使用同步
      async: false,
      beforeSend: function (request) {
        request.setRequestHeader('token', localStorage.getItem('token'));
      },
      data: JSON.stringify({
        orderId: orderId,
      }),
      success(res) {
        if (res.msg == '微信支付成功') {
          flag = true;
        }
      },
    });
    return flag;
  }
  /* 点击<我已支付>按钮主动查询支付订单状态 */
  $('.close-btn').click(function () {
    let orderId = $(this).data('order-id');
    let result = searchOrderStatus(orderId);
    if (result) {
      location.reload();
    }
  });
  /* 关闭弹出图层事件 */
  $('.close-icon').click(function () {
    $('#native').hide();
  });
});

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值