隨着微信支付的普及,越來越的APP要求支持微信支付。相信大多數開發者也碰到了這樣的需求。百度了一下,大家用到最多的是微信支付中個人對商戶的支付業務,而很少有人用到微信中商戶對個人付款的業務。我最近就碰到了這樣的需求,因為從來沒有做過,所以只能查資料,可是百度到的資料很少,並且是過時的東西。又問了圈子里的高手,可是大家都沒有做過。沒辦法只有硬着頭皮自己拱吧!還好還好,功夫不負有心人啊!終於被我整明白了,現在得空,拿出來跟大家一起分享。
首先給大家吃顆定心丸,所有的東西在你沒有用過之前,它都是神秘的,當你用過之后,就會發現,也就那么回事。呵呵,開始正題吧!
這是企業付款的文檔地址,大家需要先仔細看兩遍。https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1 (就算有我的指導,也建議大家先看文檔,看文檔能便於加深大家的理解)
總體思路: 1、准備數據;2、把所有的參數連接成一個字符串,然后進行MD5,把MD5得到的一個字符串做為最后一個參;3、把微信提供的安全證,封裝到要提交的數據;(商戶證書獲取方法:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=4_3 4、通過JAVA程序向微信提供的接口POST數據。微信接口返回處理結果。
1、准備數據:所謂的數據就是請求參數,有9個參數是必須的,詳細說明見文檔(https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2)。下面我給大家提供我的示例代碼。
//配置接口參數,以下是9個必須的參數。 signParams.put("mch_appid", appid); // 微信分配的公眾賬號ID(企業號corpid即為此appId) signParams.put("mchid", mchid);// 微信支付分配的商戶號 signParams.put("nonce_str", uuid); // 隨機字符串,不長於32位 signParams.put("partner_trade_no", partner_trade_no); // 商戶訂單號,需保持唯一性 signParams.put("openid", openid); // 商戶appid下,某用戶的openid signParams.put("check_name", "NO_CHECK"); // NO_CHECK:不校驗真實姓名 // FORCE_CHECK:強校驗真實姓名(未實名認證的用戶會校驗失敗,無法轉賬) // OPTION_CHECK:針對已實名認證的用戶才校驗真實姓名(未實名認證用戶不校驗,可以轉賬成功) signParams.put("amount", amount); // 企業付款金額,單位為分 signParams.put("desc", desc); // 企業付款操作說明信息。必填。 signParams.put("spbill_create_ip", ip); // 調用接口的機器Ip地址
注意map.put()中的key是死的寫法,不能改。
2、把所有的參數拼接成一個字符串,然后進行MD5運算,把得到的運算結果,做為簽名參數,一起POST給接口。詳細做法參考文檔(https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=4_3)
3、為了提高程序的可用性,我把一些受微信影響,會變動的參數寫到了配置文件里。配置文件和JAVA文件放在同一目錄里就可以了。
安全證書這一步是關鍵,微信為了提高接口的安全性,所以增加了安全證書,以保證資金的安全。JAVA里用到的證書是pkcs12格式,大家按照文檔里的提示,去下載相關證書,然后放到自己指定的目錄里就可以了。下面是獲取證書,並發起POST請求的代碼示例。
// 獲取證書,發送POST請求; KeyStore keyStore = KeyStore.getInstance("PKCS12"); FileInputStream instream = new FileInputStream(new File(config.elementTextTrim("cert_path"))); // 從配置文件里讀取證書的路徑信息 keyStore.load(instream, mchid.toCharArray());// 證書密碼是商戶ID instream.close(); SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchid.toCharArray()).build(); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); HttpPost httpost = new HttpPost(url); //發起POST請求
4、向接口POST數據 ,獲得返回結果。下面是我的示例代碼。
CloseableHttpResponse response = httpclient.execute(httpost); HttpEntity entity = response.getEntity(); String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8"); EntityUtils.consume(entity); // 把返回的字符串解釋成DOM節點 Document dom = DocumentHelper.parseText(jsonStr); Element root = dom.getRootElement(); String returnCode = root.element("result_code").getText(); // 獲取返回代碼 if (StringUtils.equals(returnCode, "SUCCESS")) { // 判斷返回碼為成功還是失敗 String payment_no = root.element("payment_no").getText(); // 獲取支付流水號 String payment_time = root.element("payment_time").getText(); // 獲取支付時間 map.put("state", returnCode); map.put("payment_no", payment_no); map.put("payment_time", payment_time); return map; } else { String err_code = root.element("err_code").getText(); // 獲取錯誤代碼 String err_code_des = root.element("err_code_des").getText();// 獲取錯誤描述 map.put("state", returnCode);// state map.put("err_code", err_code);// err_code map.put("err_code_des", err_code_des);// err_code_des return map; }
以上4步,就完成了微信企業付款的業務。
需要用到的jar包和我的程序示例代碼。喜歡拿來就用的伙伴只需要寫寫配置文件,下載了安全證書,我的程序就可以直接拿來用了。源碼地址:http://pan.baidu.com/s/1gfqbVJt
有問題可以跟帖咨詢。
歡迎大家共同學習,共同進步。