7. 微信支付
7.1. HTTPClient
- 介绍: HttpClient 是可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。
- 功能: 实现了所有 HTTP 的方法(GET、POST、PUT、HEAD、DELETE、HEAD、OPTIONS 等)响应数据
- 使用场景
- 需要 调用其他系统 接口时,尤其是基于HTTP协议的接口
- 例如:微信支付、查看地图、获取短信验证码、获取天气
- 核心API
String JwtToken = Jwts.builder()
.setHeaderParam("typ", "JWT")
.setHeaderParam("alg", "HS256")
.setSubject("qinxue-user")
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRE))
.claim("id", id)
.claim("nickname", nickname)
.signWith(SignatureAlgorithm.HS256, APP_SECRET)
.compact();
- HttpClient:Http客户端对象,使用该类型对象可发起Http请求。(接口)
- HttpClients:构建器,用于获得HttpClient对象。
- CloseableHttpClient:具体实现类,实现了HttpClient接口。
- HttpGet:Get方式请求类型。
- HttpPost:Post方式请求类型。
- 发送请求步骤
- 创建HttpClient对象
- 创建Http请求对象(比如我们要发送一个get请求,我们就需要构造HttpGet对象)
- 调用HttpClient的execute对象方法发送请求
- 依赖引入
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
- 工具类:为了方便在项目中更好地使用它,可使用以下工具类
7.2. 微信支付
- 前端支付后回到详情页面过程实现
- 每隔三秒查询订单支付状态
-
mounted() { //在页面渲染之后执行 //每隔三秒,去查询一次支付状态 this.timer1 = setInterval(() => { this.queryPayStatus(this.payObj.out_trade_no) }, 3000); },
- 订单状态为已支付,清除页面中的定时器
-
queryPayStatus(out_trade_no) { order.queryPayStatus(out_trade_no).then(response => { if (response.data.success) { //如果支付成功,清除定时器 clearInterval(this.timer1) this.$message({ type: 'success', message: '支付成功!' }) //跳转到课程详情页面观看视频 this.$router.push({path: '/course/' + this.payObj.course_id}) } }) }
- 如果已支付,后端接口
- 跟新订单状态 -- > 支付记录表添加一条记录
- 后端实现生成二维码
- 依赖导入
-
<dependencies> <dependency> <groupId>com.github.wxpay</groupId> <artifactId>wxpay-sdk</artifactId> <version>0.0.3</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> </dependency> </dependencies>
-
- 根据订单id获取订单信息生成一个订单对象
-
QueryWrapper<TOrder> wrapper = new QueryWrapper<>(); wrapper.eq("order_no",orderNo); TOrder order = orderService.getOne(wrapper);
-
- 设置支付参数,准备一些参数,比如说订单编号,商品信息,支付的ip地址,支付的回调地址,支付的类型
-
Map m = new HashMap(); m.put("appid", "wx74862e0dfcf69954"); // 我们的项目在微信中的id m.put("mch_id", "1558950191"); // 商户号 m.put("nonce_str", WXPayUtil.generateNonceStr()); // 生成一个随机的字符串 m.put("body", order.getCourseTitle()); // 商品的信息 m.put("out_trade_no", orderNo); // 订单号 m.put("total_fee", order.getTotalFee().multiply(new BigDecimal("100")).longValue()+""); // 总金额 m.put("spbill_create_ip", "127.0.0.1"); // 支付的ip地址 m.put("notify_url", "http://guli.shop/api/order/weixinPay/weixinNotify\n"); // 支付的回调地址,没什么用 m.put("trade_type", "NATIVE"); // 支付的类型
-
- 使用HTTPClient来根据URL访问第三方接口并且传递参数,用client设置参数
-
//2、HTTPClient来根据URL访问第三方接口并且传递参数 HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder"); //client设置参数 client.setXmlParam(WXPayUtil.generateSignedXml(m, "T6m9iK73b0kn9g5v426MKfHQH7X8rKwb")); client.setHttps(true); client.post();
-
- 返回第三方的数据,封装到Map集合中
-
String xml = client.getContent(); Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
-
- 封装返回结果集
-
Map map = new HashMap<>(); map.put("out_trade_no", orderNo); map.put("course_id", order.getCourseId()); map.put("total_fee", order.getTotalFee()); map.put("result_code", resultMap.get("result_code")); map.put("code_url", resultMap.get("code_url")); //微信支付二维码2小时过期,可采取2小时未支付取消订单 //redisTemplate.opsForValue().set(orderNo, map, 120, TimeUnit.MINUTES); return map;