生成微信支付二维码接口.png
一、准备阶段
需要提前准备好一下事情
weixin: pay: #关联的公众号appid appid: wx74862e0dfcf695956 #商户号 partner: 155000000 #商户key partnerkey: T6m9iK73b0kn9g5v426MKfHQH7X8rKwb #回调地址 notifyurl: http://guli.shop/api/order/weixinPay/weixinNotify
二、添加依赖
添加微信支付开发依赖
<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>
三、编写代码
调用微信支付接口如下代码
public class PayLogServiceImpl implements PayLogService { @Autowired private PayLogMapper payLogMapper; @Autowired private OrderMapper orderMapper; /** * 【生成二维码接口】 * * @author caiweiwei * @date 2021/6/9 9:47 */ public Map createNative(String orderNo) { try { //根据订单 Order order = orderMapper.getOrderInfoByOrderNo(orderNo); //2 使用map设置生成二维码需要参数 Map m = new HashMap(); m.put("appid", "wx74862e0dfcf69954"); 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"); m.put("notify_url", "http://guli.shop/api/order/weixinPay/weixinNotify\n"); m.put("trade_type", "NATIVE"); //3 发送httpclient请求,传递参数xml格式,微信支付提供的固定的地址 HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder"); //设置xml格式的参数 client.setXmlParam(WXPayUtil.generateSignedXml(m, "T6m9iK73b0kn9g5v426MKfHQH7X8rKwb")); client.setHttps(true); //执行post请求发送 client.post(); //4 得到发送请求返回结果 //返回内容,是使用xml格式返回 String xml = client.getContent(); //把xml格式转换map集合,把map集合返回 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")); //二维码地址 return map; } catch (Exception e) { throw new GuliException(20001, "生成二维码失败"); } }
当生成二维码之后需要需要调用接口进行查询是否支付成功,代码如下
controller代码
/** * 【查询订单支付状态】 * * @author caiweiwei * @date 2021/6/13 15:03 */ @GetMapping("queryPayStatus/{orderNo}") public R queryPayStatus(@PathVariable String orderNo) { Map<String,String> map = payLogService.queryPayStatus(orderNo); System.out.println("*****查询订单状态map集合:"+map); if(map == null) { return R.error().message("支付出错了"); } //如果返回map里面不为空,通过map获取订单状态 if(map.get("trade_state").equals("SUCCESS")) {//支付成功 //添加记录到支付表,更新订单表订单状态 payLogService.updateOrdersStatus(map); return R.ok().message("支付成功"); } return R.ok().code(25000).message("支付中"); }
service层代码
/** * 【查询订单是否支付成功】 * * @author caiweiwei * @date 2021/6/13 16:21 */ @Override public Map<String, String> queryPayStatus(String orderNo) { try { //1、封装参数 Map m = new HashMap<>(); m.put("appid", "wx74862e0dfcf69954"); m.put("mch_id", "1558950191"); m.put("out_trade_no", orderNo); m.put("nonce_str", WXPayUtil.generateNonceStr()); //2 发送httpclient HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery"); client.setXmlParam(WXPayUtil.generateSignedXml(m, "T6m9iK73b0kn9g5v426MKfHQH7X8rKwb")); client.setHttps(true); client.post(); //3 得到请求返回内容 String xml = client.getContent(); Map<String, String> resultMap = WXPayUtil.xmlToMap(xml); //6、转成Map再返回 return resultMap; } catch (Exception e) { return null; } } /** * 【 添加支付记录和更新订单状态】 * * @author caiweiwei * @date 2021/6/13 16:25 */ @Override public void updateOrdersStatus(Map<String, String> map) { //从map获取订单号 String orderNo = map.get("out_trade_no"); Order order = orderMapper.getOrderInfoByOrderNo(orderNo); //更新订单表订单状态 if(order.getStatus().intValue() == 1) { return; } order.setStatus(1);//1代表已经支付 orderMapper.updateById(order); //向支付表添加支付记录 PayLog payLog = new PayLog(); payLog.setOrderNo(orderNo); //订单号 payLog.setPayTime(new Date()); //订单完成时间 payLog.setPayType(1);//支付类型 1微信 payLog.setTotalFee(order.getTotalFee());//总金额(分) payLog.setTradeState(map.get("trade_state"));//支付状态 payLog.setTransactionId(map.get("transaction_id")); //流水号 payLog.setAttr(JSONObject.toJSONString(map)); payLogMapper.savePayLog(payLog); }
在查看是否支付成功时,前端可以写定时器进行查询,代码如下
<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><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> <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="weixin://wxpay/bizpayurl?pr=R7tnDpZ" :size="338"/> --> <qriously :value="payObj.code_url" :size="338"/> <div class="saosao"> <p>请使用微信扫一扫</p> <p>扫描二维码支付</p> </div> </div> </div> <div class="clearfix"></div> <!-- <p><a href="pay.html" target="_blank">> 其他支付方式</a></p> --> </div> </div> </div> </template> <script> import ordersApi from '@/api/orders' export default { asyncData({ params, error }) { return ordersApi.createNatvie(params.pid) .then(response => { return { payObj: response.data.data } }) }, data() { return { timer1:'' } }, //每隔三秒调用一次查询订单状态的方法 mounted() {//页面渲染之后执行 this.timer1 = setInterval(() => { this.queryOrderStatus(this.payObj.out_trade_no) },3000); }, methods:{ queryOrderStatus(orderNo) { ordersApi.queryPayStatus(orderNo) .then(response => { if (response.data.success) { //支付成功,清除定时器 clearInterval(this.timer1) //提示 this.$message({ type: 'success', message: '支付成功!' }) //跳转回到课程详情页面 this.$router.push({path: '/course/' + this.payObj.course_id}) } }) } } } </script>
使用的HttpClient工具类代码如下:
package com.caiweiwei.eduorder.utils; import org.apache.http.Consts; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.*; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLContextBuilder; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import javax.net.ssl.SSLContext; import java.io.IOException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.text.ParseException; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; /** * http请求客户端 * * @author qy * */ public class HttpClient { private String url; private Map<String, String> param; private int statusCode; private String content; private String xmlParam; private boolean isHttps; public boolean isHttps() { return isHttps; } public void setHttps(boolean isHttps) { this.isHttps = isHttps; } public String getXmlParam() { return xmlParam; } public void setXmlParam(String xmlParam) { this.xmlParam = xmlParam; } public HttpClient(String url, Map<String, String> param) { this.url = url; this.param = param; } public HttpClient(String url) { this.url = url; } public void setParameter(Map<String, String> map) { param = map; } public void addParameter(String key, String value) { if (param == null) param = new HashMap<String, String>(); param.put(key, value); } public void post() throws ClientProtocolException, IOException { HttpPost http = new HttpPost(url); setEntity(http); execute(http); } public void put() throws ClientProtocolException, IOException { HttpPut http = new HttpPut(url); setEntity(http); execute(http); } public void get() throws ClientProtocolException, IOException { if (param != null) { StringBuilder url = new StringBuilder(this.url); boolean isFirst = true; for (String key : param.keySet()) { if (isFirst) url.append("?"); else url.append("&"); url.append(key).append("=").append(param.get(key)); } this.url = url.toString(); } HttpGet http = new HttpGet(url); execute(http); } /** * set http post,put param */ private void setEntity(HttpEntityEnclosingRequestBase http) { if (param != null) { List<NameValuePair> nvps = new LinkedList<NameValuePair>(); for (String key : param.keySet()) nvps.add(new BasicNameValuePair(key, param.get(key))); // 参数 http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 设置参数 } if (xmlParam != null) { http.setEntity(new StringEntity(xmlParam, Consts.UTF_8)); } } private void execute(HttpUriRequest http) throws ClientProtocolException, IOException { CloseableHttpClient httpClient = null; try { if (isHttps) { SSLContext sslContext = new SSLContextBuilder() .loadTrustMaterial(null, new TrustStrategy() { // 信任所有 public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { return true; } }).build(); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslContext); httpClient = HttpClients.custom().setSSLSocketFactory(sslsf) .build(); } else { httpClient = HttpClients.createDefault(); } CloseableHttpResponse response = httpClient.execute(http); try { if (response != null) { if (response.getStatusLine() != null) statusCode = response.getStatusLine().getStatusCode(); HttpEntity entity = response.getEntity(); // 响应内容 content = EntityUtils.toString(entity, Consts.UTF_8); } } finally { response.close(); } } catch (Exception e) { e.printStackTrace(); } finally { httpClient.close(); } } public int getStatusCode() { return statusCode; } public String getContent() throws ParseException, IOException { return content; } }