1,官方文檔的地址
2,在官方文檔中給出了證書使用的鏈接,如下:
[其實只有證書的獲取,選擇。具體的證書怎么在代碼中使用,文檔中並沒有給出說明]
3,第一步准備請求的參數,里面只有五個是參數是有點特殊的
(1)隨機數。官方文檔里面給出了說明【這里】
/** * StringUtils工具類方法 獲取一定長度的隨機字符串,范圍0-9,a-z * * @param length:指定字符串長度 * @return 一定長度的隨機字符串 */ public static String getRandomStringByLength(int length) { String base = "abcdefghijklmnopqrstuvwxyz0123456789"; Random random = new Random(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < length; i++) { int number = random.nextInt(base.length()); sb.append(base.charAt(number)); } return sb.toString(); }
(2)微信訂單號(這個是在支付的時候產生的,需要在支付的回調函數中就將其保存在訂單表中,待退款時使用)
(3)簽名:這個在官方文檔中也給出了說明
String mysign = PayUtil.sign(prestr, WxPayConfig.key, "utf-8").toUpperCase();
/** * 簽名字符串 * * @param text需要簽名的字符串 * @param key 密鑰 * @param input_charset編碼格式 * @return 簽名結果 */ public static String sign(String text, String key, String input_charset) { text = text + "&key=" + key; return DigestUtils.md5Hex(getContentBytes(text, input_charset)); }
public static String md5Hex(final byte[] data) { return Hex.encodeHexString(md5(data)); }
public static String encodeHexString(final byte[] data) { return new String(encodeHex(data)); }
public static char[] encodeHex(final byte[] data) { return encodeHex(data, true); }
public static char[] encodeHex(final byte[] data, final boolean toLowerCase) { return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER); }
protected static char[] encodeHex(final byte[] data, final char[] toDigits) { final int l = data.length; final char[] out = new char[l << 1]; // two characters form the hex value. for (int i = 0, j = 0; i < l; i++) { out[j++] = toDigits[(0xF0 & data[i]) >>> 4]; out[j++] = toDigits[0x0F & data[i]]; } return out; }
(4)兩個整形的參數(一定要注意類型【否則報參數格式錯誤】)
這兩個參數是取得訂單類的屬性,在訂單類中,這兩個參數我是定義的Double的類型,單位:元。傳的參數是以分為單位的整形,因此就需要乘100。
還有一點需要注意的是,舉個例子吧:
在這里我測試的是0.01(一分)直接乘100,他的結果是1.0,這個結果是不對的,需要把后面的".0"去掉,
4,所有參數准備好之后就是發順宏請求了,這里比較特殊的就是他需要證書,然而官方文檔只給了證書的獲取方式,以及不同語言的選擇,並沒有告訴我們怎么用。
下面就是本篇最重要的地方
public static void refund(Order order) throws Exception { try { KeyStore clientStore = KeyStore.getInstance("PKCS12"); // 讀取本機存放的PKCS12證書文件 FileInputStream instream = new FileInputStream("****\\apiclient_cert.p12"); try { // 指定PKCS12的密碼(商戶ID) clientStore.load(instream, "***".toCharArray()); } finally { instream.close(); } SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(clientStore, "***".toCharArray()).build(); // 指定TLS版本 SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier()); // 設置httpclient的SSLSocketFactory CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); try { HttpPost httpost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund"); // 設置響應頭信息 // httpost.addHeader("Connection", "keep-alive"); // httpost.addHeader("Accept", "*/*"); // httpost.addHeader("Content-Type", CONTENT_TYPE_FORM.toString()); // httpost.addHeader("X-Requested-With", "XMLHttpRequest"); // httpost.addHeader("Cache-Control", "max-age=0"); // httpost.addHeader("User-Agent", DEFAULT_USER_AGENT); httpost.setEntity(new StringEntity(getXmlStr(order), "UTF-8")); CloseableHttpResponse response = httpclient.execute(httpost); try { HttpEntity entity = response.getEntity(); String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8"); EntityUtils.consume(entity); System.out.println(jsonStr); } finally { response.close(); } } finally { httpclient.close(); } } catch (Exception e) { throw new RuntimeException(e); } }
測試類
public static void main(String[] args) throws Exception { Order order = new Order(); refund(order); }