02-生成支付二维码

大家好, 我是上白书妖!

知识源于积累,登峰造极源于自律

今天我根据以前所以学的一些文献,笔记等资料整理出一些小知识点,有不当之处,欢迎各位斧正

一、添加依赖

service-order中添加微信sdk依赖
<dependency>
    <groupId>com.github.wxpay</groupId>
    <artifactId>wxpay-sdk</artifactId>
    <version>0.0.3</version>
</dependency>

2、配置yml参数

微信参数
weixin:
  pay:
    #关联的公众号appid
    appid: wx74862e0dfcf69954
    #商户号
    partner: 1558950191
    #商户key
    partnerkey: T6m9iK73b0kn9g5v426MKfHQH7X8rKwb
    #回调地址
    notifyurl: http://guli.shop/api/order/weixinPay/weixinNotify
redis参数
spring:
  redis:
    host: 39.106.16.235
    port: 6379
    database: 0
    timeout: 1800000
    password: 123456
    jedis:
      pool:
        max-active: 20 #最大连接数
        max-wait: -1    #最大阻塞等待时间(负数表示没限制)
        max-idle: 5    #最大空闲
        min-idle: 0     #最小空闲

3、参数读取工具类

package com.atguigu.guli.service.order.util;

@Data
@Component
//注意prefix要写到最后一个 "." 符号之前
@ConfigurationProperties(prefix="weixin.pay")
public class WeixinPayProperties {
    private String appid;
    private String partner;
    private String partnerkey;
    private String notifyurl;
}

4、httpClinet工具类

HttpClient.java放入当前项目

二、根据订单号生成支付二维码

1、API:统一下单接口文档

https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1

2、辅助业务方法

OrderService:getOrderByOrderNo
接口:

/**
     * 根据订单号查询订单
     * @param orderNo
     * @return
     */
Order getOrderByOrderNo(String orderNo);

实现:

/**
     * 根据订单号查询订单实体
     *
     * @param orderNo
     * @return
     */
public Order getOrderByOrderNo(String orderNo) {

    QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("order_no", orderNo);
    return orderMapper.selectOne(queryWrapper);
}

3、下单业务(生成支付二维码)

创建 WeixinPayService:createNative
接口:

package com.atguigu.guli.service.order.service;
public interface WeixinPayService {
	/**
	 * 根据订单号下单,生成支付链接
	 * @param orderNo
	 * @return
	 */
	Map<String, Object> createNative(String orderNo, String remoteAddr);
}

实现:

package com.atguigu.guli.service.order.service.impl;
@Service
@Slf4j
public class WeixinPayServiceImpl implements WeixinPayService {

	@Autowired
	private OrderService orderService;
	@Autowired
	private RedisTemplate redisTemplate;
	@Autowired
	private WeixinPayProperties weixinPayProperties;

	/**
	 * 根据订单号下单,生成支付链接
	 * @param orderNo
	 * @return
	 */
	@Override
	public Map<String, Object> createNative(String orderNo, String remoteAddr) {
		try {
			Map<String, Object> payMap = (Map)redisTemplate.opsForValue().get(orderNo);
			if(payMap != null) {
				return payMap;
			}

			Order order = orderService.getOrderByOrderNo(orderNo);

			Map<String, String> m = new HashMap<>();

			//1、设置参数
			m.put("appid", weixinPayProperties.getAppid());
			m.put("mch_id", weixinPayProperties.getPartner());
			m.put("nonce_str", WXPayUtil.generateNonceStr());
			m.put("body", order.getCourseTitle());
			m.put("out_trade_no", orderNo);
			int totalFee = order.getTotalFee().multiply(new BigDecimal("100")).intValue();
			//转成string,否则在下面generateSignedXml中会有java.lang.Integer cannot be cast to java.lang.String
			m.put("total_fee", totalFee + "");
			m.put("spbill_create_ip", remoteAddr);
			m.put("notify_url", weixinPayProperties.getNotifyurl());
			m.put("trade_type", "NATIVE");
			
			//2、HTTPClient来根据URL访问第三方接口并且传递参数
			HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
			
			//client设置参数
			client.setXmlParam(WXPayUtil.generateSignedXml(m, weixinPayProperties.getPartnerkey()));
			client.setHttps(true);
			client.post();
			//3、返回第三方的数据
			String xml = client.getContent();
			Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
			//4、封装返回结果集

			System.out.println(xml);
			System.out.println(resultMap.get("return_code"));
			System.out.println(resultMap.get("return_msg"));
			System.out.println(resultMap.get("err_code"));
			System.out.println(resultMap.get("err_code_des"));

			if("FAIL".equals(resultMap.get("return_code")) || "FAIL".equals(resultMap.get("result_code")) ){
				log.error("统一下单错误 - " +
						"return_msg: " + resultMap.get("return_msg") + ", " +
						"err_code: " + resultMap.get("err_code") + ", " +
						"err_code_des: " + resultMap.get("err_code_des"));
				throw new GuliException(ResultCodeEnum.PAY_UNIFIEDORDER_ERROR);
			}
			
			Map<String, Object> map = new HashMap<>();
			map.put("result_code", resultMap.get("result_code"));
			map.put("code_url", resultMap.get("code_url"));
			map.put("course_id", order.getCourseId());
			map.put("total_fee", order.getTotalFee());
			map.put("out_trade_no", orderNo);

			//微信支付二维码2小时过期,可采取2小时未支付取消订单
			redisTemplate.opsForValue().set(orderNo, map, 120, TimeUnit.MINUTES);
			return map;
		} catch (Exception e) {
			log.error(ExceptionUtils.getMessage(e));
			throw new GuliException(ResultCodeEnum.PAY_UNIFIEDORDER_ERROR);
		}
	}

}

4、下单接口

ApiWeixinPayController:createNative

package com.atguigu.guli.service.order.controller.api;

@RestController
@RequestMapping("/api/order/weixinPay")
@Api(description = "网站微信支付")
@CrossOrigin //跨域
@Slf4j
public class ApiWeixinPayController {
    
    @Autowired
    private WeixinPayService weixinPayService;

    /**
     * 生成二维码
     *
     * @return
     */
    @GetMapping("/createNative/{orderNo}")
    public R createNative(@PathVariable String orderNo, HttpServletRequest request) {
        String remoteAddr = request.getRemoteAddr();
        Map map = weixinPayService.createNative(orderNo, remoteAddr);
        return R.ok().data(map);
    }
}

三、支付前端

根据微信支付下单接口返回的二维码url,在页面生成二维码,然后根据订单号定时调用支付查询接口,查看是否支付成功,如果支付成功返回课程详情页观看课程视频

1、安装二维码生成器
npm install [email protected]

2、配置插件

创建 plugins/vue-qriously-plugin.js

import Vue from 'vue'
import VueQriously from 'vue-qriously'
Vue.use(VueQriously)

nuxt.config.js中配置

plugins: [
    { src: '~/plugins/vue-qriously-plugin.js', ssr: false }
],

3、api

创建api/pay.js

import request from '@/utils/request'
const apiPath = '/api/order/weixinPay'
export default {
  createNative(orderId) {
    return request({
      baseURL: 'http://localhost:8170',
      url: `${apiPath}/createNative/${orderId}`,
      method: 'get'
    })
  }
}

4、支付页面

创建pages/pay/_id.vue

<template>
  <div class="cart py-container">
    <!--主内容-->
    <div class="checkout py-container  pay">
      <div class="checkout-tit">
        <h4 class="fl tit-txt"><span class="success-icon"/><span class="success-info">订单提交成功,请您及时付款!订单号:{{ payObj.out_trade_no }}</span>
        </h4>
        <span class="fr"><em class="sui-lead">应付金额:</em><em class="orange money">¥{{ payObj.total_fee }}</em></span>
        <div class="clearfix"/>
      </div>
      <div class="checkout-steps">
        <div class="fl weixin">微信支付</div>
        <div class="fl sao">
          <p class="red">请使用微信扫一扫。</p>
          <div class="fl code">
            <!-- <img id="qrious" src="~/assets/img/erweima.png" alt=""> -->
            <qriously :value="payObj.code_url" :size="338"/>
            <div class="saosao">
              <p>请使用微信扫一扫</p>
              <p>扫描二维码支付</p>
            </div>

          </div>

        </div>
        <div class="clearfix"/>
        <!-- <p><a href="pay.html" target="_blank">> 其他支付方式</a></p> -->
      </div>
    </div>

  </div>
</template>
<script>
import pay from '~/api/pay'

export default {

  async asyncData({ params }) {
    const response = await pay.createNative(params.id)
    return {
      payObj: response.data.data
    }
  },

  // 在created中获取数据,报告Invalid prop: type check failed for prop "value".
  // created() {
  //   pay.createNative(this.$route.params.id).then(response => {
  //     this.payObj = response.data.data
  //   })
  // }
}

</script>
结束寄语: 知识源于积累,登峰造极源于自律
发布了9 篇原创文章 · 获赞 1 · 访问量 265

猜你喜欢

转载自blog.csdn.net/weixin_45016497/article/details/104356276