官方API文檔https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5
1.使用jar包
1 <!--微信支付 --> 2 <dependency> 3 <groupId>com.github.wxpay</groupId> 4 <artifactId>wxpay-sdk</artifactId> 5 <version>3.0.9</version> 6 </dependency> 7 8 <!--httpclient--> 9 <dependency> 10 <groupId>org.apache.httpcomponents</groupId> 11 <artifactId>httpclient</artifactId> 12 </dependency>
2.統一下單接口
serviceImpl類
1 public Map createNative(String out_trade_no, String total_fee) { 2 // TODO 自動生成的方法存根 3 Map<String,String> param=new HashMap<>(); 4 param.put("appid", appid); //小程序id 5 param.put("mch_id", partner);//商戶號 6 param.put("nonce_str", WXPayUtil.generateNonceStr());//隨機字符串 7 param.put("body", "測試數據");//商品描述 8 param.put("out_trade_no", out_trade_no);//商戶訂單號 9 param.put("total_fee",total_fee);//總金額(分) 10 param.put("spbill_create_ip", "127.0.0.1");//IP 11 param.put("notify_url", notifyurl);//回調地址 12 param.put("trade_type", "NATIVE");//交易類型 13 param.put("product_id",out_trade_no);//訂單 14 try { 15 //2.生成要發送的xml 16 String xmlParam = WXPayUtil.generateSignedXml(param, partnerkey); 17 HttpClient client=new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder"); 18 client.setHttps(true); 19 client.setXmlParam(xmlParam); 20 client.post(); 21 //3.獲得結果 22 String result = client.getContent(); 23 System.out.println(result); 24 Map<String, String> resultMap = WXPayUtil.xmlToMap(result); 25 Map<String, String> map=new HashMap<>(); 26 map.put("code_url", resultMap.get("code_url"));//二維碼支付地址 27 map.put("total_fee", total_fee);//總金額 28 map.put("out_trade_no",out_trade_no);//訂單號 29 return map; 30 } catch (Exception e) { 31 e.printStackTrace(); 32 return new HashMap<>(); 33 } 34 }
controller
1 @RequestMapping("/createNative") 2 public AjaxJson createNativePay(){ 3 //雪花算法類 隨機生成號碼 4 IdWorker idworker=new IdWorker(); 5 long oid=idworker.nextId(); 6 //訂單實體類 7 SfOrders sfOrders=new SfOrders(); 8 //set訂單id 9 sfOrders.setOid(oid); 10 //支付狀態 11 sfOrders.setPay_id(2); 12 //添加到數據庫 13 int x=ordersMapper.add(sfOrders); 14 //判斷是否添加成功 15 if(x>=1) { 16 //獲取插入的id 17 Long keyid=publicMapper.getPrimarykey(); 18 //轉換keyid類型 19 int k=keyid.intValue(); 20 //根據id查詢這一條數據 21 SfOrders orders=ordersMapper.getById(k); 22 //根據訂單id,支付金額生成二維碼 23 Map map=weixinPayService.createNative(orders.getOid()+"","1"); 24 return AjaxJson.getSuccessData(map); 25 } 26 return AjaxJson.getSuccess(); 27 }
頁面寫法,有想要測試是否能支付的朋友可以試試
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 <!-- 所有的 css & js 資源 --> 7 <link rel="stylesheet" href="https://unpkg.com/element-ui@2.13.0/lib/theme-chalk/index.css"> 8 <link rel="stylesheet" href="../../static/sa.css"> 9 <script src="https://unpkg.com/vue@2.6.10/dist/vue.min.js"></script> 10 <script src="https://unpkg.com/element-ui@2.13.0/lib/index.js"></script> 11 <script src="https://unpkg.com/jquery@3.4.1/dist/jquery.min.js"></script> 12 <script src="https://www.layuicdn.com/layer-v3.1.1/layer.js"></script> 13 <script src="../../static/sa.js"></script> 14 <script src="../../static/qrcode/qrcode.js"></script> 15 <style> 16 </style> 17 </head> 18 <body> 19 <div class="vue-box"> 20 <div class="c-item" style="min-width: 0px;"> 21 <el-button @click="queryCode()">點擊事件二維碼</el-button> 22 </div> 23 </div> 24 25 <div id="code"></div> 26 27 <script> 28 var app = new Vue({ 29 el: '.vue-box', 30 data: { 31 code_url: '', 32 out_trade_no: '' 33 }, 34 35 methods: { 36 queryCode: function() { 37 // 統一下單 38 // ajax返回 下單的數據 39 sa.ajax('/pay/createNative', function(res) { 40 console.log(res); 41 new QRCode(document.getElementById('code'), res.data.code_url); // 創建二維碼 42 this.out_trade_no = res.data.out_trade_no; // 賦值 res里獲取的賦值給data里面的 43 console.log(res.data.out_trade_no + "----------訂單id") 44 }.bind(this), {}); 45 }, 46 }, 47 created: function() { 48 49 } 50 }) 51 </script> 52 </body> 53 </html>
寫到這里了是可以去頁面測試掃碼支付的。
3.支付回調
1 @RequestMapping("/wxnotify") 2 public void wxnotify(HttpServletRequest request, HttpServletResponse response) { 3 String resXml = ""; 4 InputStream inStream; 5 try { 6 inStream = request.getInputStream(); 7 ByteArrayOutputStream outSteam = new ByteArrayOutputStream(); 8 byte[] buffer = new byte[1024]; 9 int len = 0; 10 while ((len = inStream.read(buffer)) != -1) { 11 outSteam.write(buffer, 0, len); 12 } 13 14 WXPayUtil.getLogger().info("wxnotify:微信支付----start----"); 15 16 // 獲取微信調用我們notify_url的返回信息 17 String result = new String(outSteam.toByteArray(), "utf-8"); 18 WXPayUtil.getLogger().info("wxnotify:微信支付----result----=" + result); 19 20 // 關閉流 21 outSteam.close(); 22 inStream.close(); 23 24 // xml轉換為map 25 Map<String, String> resultMap = WXPayUtil.xmlToMap(result); 26 //判斷狀態 驗證簽名是否正確 27 boolean isSuccess = false; 28 29 if (WXPayConstants.SUCCESS.equalsIgnoreCase(resultMap.get(WXPayConstants.RESULT_CODE))) { 30 31 WXPayUtil.getLogger().info("wxnotify:微信支付----返回成功"); 32 33 if (WXPayUtil.isSignatureValid(resultMap, WXPayConstants.API_KEY)) { 34 35 WXPayUtil.getLogger().info("wxnotify:微信支付----驗證簽名成功"); 36 37 resXml = resSuccessXml; 38 isSuccess = true; 39 40 } else { 41 WXPayUtil.getLogger().error("wxnotify:微信支付----判斷簽名錯誤"); 42 } 43 44 } else { 45 WXPayUtil.getLogger().error("wxnotify:支付失敗,錯誤信息:" + resultMap.get(WXPayConstants.ERR_CODE_DES)); 46 resXml = resFailXml; 47 } 48 // 回調方法,處理業務 - 修改訂單狀態 49 WXPayUtil.getLogger().info("wxnotify:微信支付回調:修改的訂單===>" + resultMap.get("out_trade_no")); 50 int x=ordersService.updateByOid(resultMap.get("out_trade_no")); 51 if (x>=1) { 52 WXPayUtil.getLogger().info("wxnotify:微信支付回調:修改訂單支付狀態成功"); 53 } else { 54 WXPayUtil.getLogger().error("wxnotify:微信支付回調:修改訂單支付狀態失敗"); 55 } 56 57 } catch (Exception e) { 58 WXPayUtil.getLogger().error("wxnotify:支付回調發布異常:", e); 59 } finally { 60 try { 61 // 處理業務完畢 62 BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream()); 63 out.write(resXml.getBytes()); 64 out.flush(); 65 out.close(); 66 } catch (IOException e) { 67 WXPayUtil.getLogger().error("wxnotify:支付回調發布異常:out:", e); 68 } 69 } 70 71 }
上面定義的WXPayConstants這個類是自己封裝的類,有朋友寫到這個地方時,可以直接把這個變量的值等於它的小寫字母。例如:
public static final String RESULT_CODE = "result_code";