1. 程式人生 > >[分享] 微信支付中商戶對個人使用者付款案例

[分享] 微信支付中商戶對個人使用者付款案例

  隨著微信支付的普及,越來越的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

  有問題可以跟帖諮詢。

  歡迎大家共同學習,共同進步。