微信支付之退款--原路退回


1.場景

  當交易發生之后一段時間內,由於買家或者賣家的原因需要退款時,賣家可以通過退款接口將支付款退還給買家,微信支付將在收到退款請求並且驗證成功之后,按照退款規則將支付款按原路退到買家帳號上。

       注意:

  1、交易時間超過一年的訂單無法提交退款

  2、微信支付退款支持單筆交易分多次退款,多次退款需要提交原支付訂單的商戶訂單號和設置不同的退款單號。申請退款總金額不能超過訂單金額。 一筆退款失敗后重新提交,請不要更換退款單號,請使用原商戶退款單號

  3、請求頻率限制:150qps,即每秒鍾正常的申請退款請求次數不超過150次

     錯誤或無效請求頻率限制:6qps,即每秒鍾異常或錯誤的退款申請請求不超過6次

  4、每個支付訂單的部分退款次數不能超過50次

  5、如果同一個用戶有多筆退款,建議分不同批次進行退款,避免並發退款導致退款失敗

2.返回的接口地址

  https://api.mch.weixin.qq.com/secapi/pay/refund

3.需要證書

  如果證書不是自己配置的,在微信支付平台管理的地方是下載不了的。也可以換一種方法去找你的經理要一份就好了。

4.請求參數  (以下截圖是必填的參數,如有不明白請參考官方文檔:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_4

  

5.代碼部分

 ①.service方法

1      /**
2         *
3         * @param mchId 商戶ID
4         * @param url 請求URL
5         * @param data 退款參數
6         * @return
7         * @throws Exception
8       */
9     String doRefund(String mchId, String url, String data) throws Exception;

  ②.impl 此方法內要讀取證書的位置

 1  /**
 2     *
 3     * @param mchId 商戶ID
 4     * @param url 請求URL
 5     * @param data 退款參數
 6     * @return
 7     * @throws Exception
 8     */
 9    public String doRefund(String mchId, String url, String data) throws Exception {
10        /**
11         * 注意PKCS12證書 是從微信商戶平台-》賬戶設置-》 API安全 中下載的
12         */
13        KeyStore keyStore = KeyStore.getInstance("PKCS12");
14        
15        //這里讀取.p12的文件是放在服務器中 使用nginx配置時指向的后端項目路徑
16        FileInputStream inputStream = new FileInputStream(new File("apiclient_cert.p12"));//P12文件目錄       
17        try {
18            //這里寫密碼..默認是你的MCHID
19            keyStore.load(inputStream, mchId.toCharArray());
20        } finally {
21            inputStream.close();
22        } 
23         SSLContext sslcontext = SSLContexts.custom()
24                //這里也是寫密碼的
25                .loadKeyMaterial(keyStore, mchId.toCharArray())
26                .build(); 
27        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
28                sslcontext,
29                SSLConnectionSocketFactory.getDefaultHostnameVerifier());
30        CloseableHttpClient httpclient = HttpClients.custom()
31                .setSSLSocketFactory(sslsf)
32                .build();
33        try {
34            HttpPost httpost = new HttpPost(url);  
35            httpost.setEntity(new StringEntity(data, "UTF-8"));
36            CloseableHttpResponse response = httpclient.execute(httpost);
37            try {
38                HttpEntity entity = response.getEntity(); 
39                //接受到返回信息
40                String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
41                System.out.println(jsonStr+"-====接收到返回的信息");
42                EntityUtils.consume(entity);
43                return jsonStr;
44            } finally {
45                response.close();
46            }
47        } finally {
48            httpclient.close();
49        }
50    }
51         
52         

    ③.controller

 1    @RequestMapping("/refund")
 2    public String refund() throws Exception {
 3         System.out.println("進入退款----");
 4            try {
 5             //構建參數
 6             Map<String, String> dataMap = new HashMap<>();
 7             dataMap.put("appid","公眾賬號ID");
 8             dataMap.put("mch_id","商戶號");
 9             //自行實現該隨機串
10             dataMap.put("nonce_str",WXPayUtil.generateNonceStr());
11             //商戶訂單號
12             dataMap.put("out_trade_no","訂單號");
13             //商戶退款單號
14             dataMap.put("out_refund_no","訂單號");
15             //訂單金額
16             dataMap.put("total_fee","1");
17             //退款金額
18             dataMap.put("refund_fee","1");
19             //退款原因 (可寫可不寫)
20             dataMap.put("refund_desc","退款");
21             //生成簽名
22             String sign = WXPayUtil.generateSignature(dataMap, "商戶密鑰");
23             dataMap.put("sign", sign);
24             System.out.println(dataMap+"=========dataMap");
25             
26             //map數據轉xml
27             String xmlString = XMLBeanUtil.map2XmlString(dataMap);
28             System.out.println("--------------map-->xml轉換------------"+xmlString);
29            
30             //發起退款
31             String result= weixinPayService.doRefund("商戶號", "https://api.mch.weixin.qq.com/secapi/pay/refund", xmlString);
32             System.out.println(result.toString()+"----結果");
33             System.out.println("================退款===========");
34             
35             //這里需要將發起退款的xml格式轉換為map
36             Map<String, String> returnMap = WXPayUtil.xmlToMap(result);
37             System.out.println("--------------xml-->map轉換"+result);
38             //用map取值返回的狀態碼來判斷是否退款成功
39             //判斷是否退款成功 
40             if (returnMap.get("return_code").equals("SUCCESS")) {
41                  return  "微信已成功退款";
42             }
43             return "微信退款失敗";
44         } catch (Exception e) {
45       e.printStackTrace();
46     }
47     return "失敗";
48    }
49 
50     

6.結語

  第一次寫博客,寫的不太好,還希望大家多多包涵。同時也希望這篇博客可以幫助到正在做退款這一塊的碼友們。有不懂的可以評論哦看到必回。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM