1. 程式人生 > 實用技巧 >微信掃碼支付Native方式二以及支付回撥

微信掃碼支付Native方式二以及支付回撥

官方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         }

頁面寫法,有想要測試是否能支付的朋友可以試試

點選下載生成二維碼的包qrcode.js

 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/[email protected]/lib/theme-chalk/index.css">
 8         <link rel="stylesheet" href="../../static/sa.css">
 9         <script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
10         <script src="https://unpkg.com/[email protected]/lib/index.js"></script>
11         <script src="https://unpkg.com/[email protected]/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";

寫到這裡就已經完成掃碼支付了,如果有朋友是用這個方法做支付的話可以參考。有不懂的地方可以在下面留言。