|
@@ -0,0 +1,667 @@
|
|
|
+package com.fdkankan.pay.util.wx;
|
|
|
+
|
|
|
+import javax.net.ssl.HttpsURLConnection;
|
|
|
+import javax.net.ssl.KeyManagerFactory;
|
|
|
+import javax.net.ssl.SSLContext;
|
|
|
+import java.io.*;
|
|
|
+import java.net.HttpURLConnection;
|
|
|
+import java.net.URL;
|
|
|
+import java.security.KeyStore;
|
|
|
+import java.security.SecureRandom;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+public class WXPay {
|
|
|
+
|
|
|
+ private static WXPayConstants.SignType signType = WXPayConstants.SignType.MD5;
|
|
|
+ private static Boolean useSandbox = false;
|
|
|
+ public static InputStream cerStream;
|
|
|
+ public static Integer httpConnectTimeoutMs = 8000;
|
|
|
+ public static Integer httpReadTimeoutMs = 10000;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 向 Map 中添加 appid、mch_id、nonce_str、sign_type、sign <br>
|
|
|
+ * 该函数适用于商户适用于统一下单等接口,不适用于红包、代金券接口
|
|
|
+ *
|
|
|
+ * @param reqData
|
|
|
+ * @return
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public static Map<String, String> fillRequestData(Map<String, String> reqData,
|
|
|
+ String appId,String mchId,String mchKey) throws Exception {
|
|
|
+ reqData.put("appid", appId);
|
|
|
+ reqData.put("mch_id", mchId);
|
|
|
+ reqData.put("nonce_str", WXPayUtil.generateNonceStr());
|
|
|
+ if (WXPayConstants.SignType.MD5.equals(signType)) {
|
|
|
+ reqData.put("sign_type", WXPayConstants.MD5);
|
|
|
+ }
|
|
|
+ else if (WXPayConstants.SignType.HMACSHA256.equals(signType)) {
|
|
|
+ reqData.put("sign_type", WXPayConstants.HMACSHA256);
|
|
|
+ }
|
|
|
+ reqData.put("sign", WXPayUtil.generateSignature(reqData, mchKey, signType));
|
|
|
+ return reqData;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断xml数据的sign是否有效,必须包含sign字段,否则返回false。
|
|
|
+ *
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @return 签名是否有效
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public static boolean isResponseSignatureValid(Map<String, String> reqData,String mchKey) throws Exception {
|
|
|
+ // 返回数据的签名方式和请求中给定的签名方式是一致的
|
|
|
+ return WXPayUtil.isSignatureValid(reqData, mchKey, signType);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断支付结果通知中的sign是否有效
|
|
|
+ *
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @return 签名是否有效
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public static boolean isPayResultNotifySignatureValid(Map<String, String> reqData,String mchKey) throws Exception {
|
|
|
+ String signTypeInData = reqData.get(WXPayConstants.FIELD_SIGN_TYPE);
|
|
|
+ WXPayConstants.SignType signType;
|
|
|
+ if (signTypeInData == null) {
|
|
|
+ signType = WXPayConstants.SignType.MD5;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ signTypeInData = signTypeInData.trim();
|
|
|
+ if (signTypeInData.length() == 0) {
|
|
|
+ signType = WXPayConstants.SignType.MD5;
|
|
|
+ }
|
|
|
+ else if (WXPayConstants.MD5.equals(signTypeInData)) {
|
|
|
+ signType = WXPayConstants.SignType.MD5;
|
|
|
+ }
|
|
|
+ else if (WXPayConstants.HMACSHA256.equals(signTypeInData)) {
|
|
|
+ signType = WXPayConstants.SignType.HMACSHA256;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ throw new Exception(String.format("Unsupported sign_type: %s", signTypeInData));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return WXPayUtil.isSignatureValid(reqData, mchKey, signType);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 不需要证书的请求
|
|
|
+ * @param strUrl String
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @param connectTimeoutMs 超时时间,单位是毫秒
|
|
|
+ * @param readTimeoutMs 超时时间,单位是毫秒
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public static String requestWithoutCert(String strUrl, Map<String, String> reqData,
|
|
|
+ int connectTimeoutMs, int readTimeoutMs) throws Exception {
|
|
|
+ String UTF8 = "UTF-8";
|
|
|
+ String reqBody = WXPayUtil.mapToXml(reqData);
|
|
|
+ URL httpUrl = new URL(strUrl);
|
|
|
+ HttpURLConnection httpURLConnection = (HttpURLConnection) httpUrl.openConnection();
|
|
|
+ httpURLConnection.setDoOutput(true);
|
|
|
+ httpURLConnection.setRequestMethod("POST");
|
|
|
+ httpURLConnection.setConnectTimeout(connectTimeoutMs);
|
|
|
+ httpURLConnection.setReadTimeout(readTimeoutMs);
|
|
|
+ httpURLConnection.connect();
|
|
|
+ OutputStream outputStream = httpURLConnection.getOutputStream();
|
|
|
+ outputStream.write(reqBody.getBytes(UTF8));
|
|
|
+
|
|
|
+ // if (httpURLConnection.getResponseCode()!= 200) {
|
|
|
+ // throw new Exception(String.format("HTTP response code is %d, not 200", httpURLConnection.getResponseCode()));
|
|
|
+ // }
|
|
|
+
|
|
|
+ //获取内容
|
|
|
+ InputStream inputStream = httpURLConnection.getInputStream();
|
|
|
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, UTF8));
|
|
|
+ final StringBuffer stringBuffer = new StringBuffer();
|
|
|
+ String line = null;
|
|
|
+ while ((line = bufferedReader.readLine()) != null) {
|
|
|
+ stringBuffer.append(line).append("\n");
|
|
|
+ }
|
|
|
+ String resp = stringBuffer.toString();
|
|
|
+ if (stringBuffer!=null) {
|
|
|
+ try {
|
|
|
+ bufferedReader.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (inputStream!=null) {
|
|
|
+ try {
|
|
|
+ inputStream.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (outputStream!=null) {
|
|
|
+ try {
|
|
|
+ outputStream.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // if (httpURLConnection!=null) {
|
|
|
+ // httpURLConnection.disconnect();
|
|
|
+ // }
|
|
|
+
|
|
|
+ return resp;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 需要证书的请求
|
|
|
+ * @param strUrl String
|
|
|
+ * @param reqData 向wxpay post的请求数据 Map
|
|
|
+ * @param connectTimeoutMs 超时时间,单位是毫秒
|
|
|
+ * @param readTimeoutMs 超时时间,单位是毫秒
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public static String requestWithCert(String strUrl, Map<String, String> reqData,String mchId,
|
|
|
+ int connectTimeoutMs, int readTimeoutMs) throws Exception {
|
|
|
+ String UTF8 = "UTF-8";
|
|
|
+ String reqBody = WXPayUtil.mapToXml(reqData);
|
|
|
+ URL httpUrl = new URL(strUrl);
|
|
|
+ char[] password = mchId.toCharArray();
|
|
|
+ InputStream certStream = cerStream;
|
|
|
+ KeyStore ks = KeyStore.getInstance("PKCS12");
|
|
|
+ ks.load(certStream, password);
|
|
|
+
|
|
|
+ // 实例化密钥库 & 初始化密钥工厂
|
|
|
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
|
|
+ kmf.init(ks, password);
|
|
|
+
|
|
|
+ // 创建SSLContext
|
|
|
+ SSLContext sslContext = SSLContext.getInstance("TLS");
|
|
|
+ sslContext.init(kmf.getKeyManagers(), null, new SecureRandom());
|
|
|
+ HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
|
|
|
+
|
|
|
+ HttpURLConnection httpURLConnection = (HttpURLConnection) httpUrl.openConnection();
|
|
|
+
|
|
|
+ httpURLConnection.setDoOutput(true);
|
|
|
+ httpURLConnection.setRequestMethod("POST");
|
|
|
+ httpURLConnection.setConnectTimeout(connectTimeoutMs);
|
|
|
+ httpURLConnection.setReadTimeout(readTimeoutMs);
|
|
|
+ httpURLConnection.connect();
|
|
|
+ OutputStream outputStream = httpURLConnection.getOutputStream();
|
|
|
+ outputStream.write(reqBody.getBytes(UTF8));
|
|
|
+
|
|
|
+ // if (httpURLConnection.getResponseCode()!= 200) {
|
|
|
+ // throw new Exception(String.format("HTTP response code is %d, not 200", httpURLConnection.getResponseCode()));
|
|
|
+ // }
|
|
|
+
|
|
|
+ //获取内容
|
|
|
+ InputStream inputStream = httpURLConnection.getInputStream();
|
|
|
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, UTF8));
|
|
|
+ final StringBuffer stringBuffer = new StringBuffer();
|
|
|
+ String line = null;
|
|
|
+ while ((line = bufferedReader.readLine()) != null) {
|
|
|
+ stringBuffer.append(line);
|
|
|
+ }
|
|
|
+ String resp = stringBuffer.toString();
|
|
|
+ if (stringBuffer!=null) {
|
|
|
+ try {
|
|
|
+ bufferedReader.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ // e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (inputStream!=null) {
|
|
|
+ try {
|
|
|
+ inputStream.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ // e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (outputStream!=null) {
|
|
|
+ try {
|
|
|
+ outputStream.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ // e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (certStream!=null) {
|
|
|
+ try {
|
|
|
+ certStream.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ // e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // if (httpURLConnection!=null) {
|
|
|
+ // httpURLConnection.disconnect();
|
|
|
+ // }
|
|
|
+
|
|
|
+ return resp;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理 HTTPS API返回数据,转换成Map对象。return_code为SUCCESS时,验证签名。
|
|
|
+ * @param xmlStr API返回的XML格式数据
|
|
|
+ * @return Map类型数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public static Map<String, String> processResponseXml(String xmlStr,String mchKey) throws Exception {
|
|
|
+ String RETURN_CODE = "return_code";
|
|
|
+ String return_code;
|
|
|
+ Map<String, String> respData = WXPayUtil.xmlToMap(xmlStr);
|
|
|
+ if (respData.containsKey(RETURN_CODE)) {
|
|
|
+ return_code = respData.get(RETURN_CODE);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ throw new Exception(String.format("No `return_code` in XML: %s", xmlStr));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (return_code.equals(WXPayConstants.FAIL)) {
|
|
|
+ return respData;
|
|
|
+ }
|
|
|
+ else if (return_code.equals(WXPayConstants.SUCCESS)) {
|
|
|
+ if (isResponseSignatureValid(respData,mchKey)) {
|
|
|
+ return respData;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ throw new Exception(String.format("Invalid sign value in XML: %s", xmlStr));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ throw new Exception(String.format("return_code value %s is invalid in XML: %s", return_code, xmlStr));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:提交刷卡支付<br>
|
|
|
+ * 场景:刷卡支付
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public static Map<String, String> microPay(Map<String, String> reqData, String appId,String mchId,String mchKey) throws Exception {
|
|
|
+ return microPay(reqData,appId,mchId,mchKey, httpConnectTimeoutMs, httpReadTimeoutMs);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:提交刷卡支付<br>
|
|
|
+ * 场景:刷卡支付
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @param connectTimeoutMs 连接超时时间,单位是毫秒
|
|
|
+ * @param readTimeoutMs 读超时时间,单位是毫秒
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public static Map<String, String> microPay(Map<String, String> reqData, String appId,String mchId,String mchKey,
|
|
|
+ int connectTimeoutMs, int readTimeoutMs) throws Exception {
|
|
|
+ String url;
|
|
|
+ if (useSandbox) {
|
|
|
+ url = WXPayConstants.SANDBOX_MICROPAY_URL;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ url = WXPayConstants.MICROPAY_URL;
|
|
|
+ }
|
|
|
+ String respXml = requestWithoutCert(url, fillRequestData(reqData,appId,mchId,mchKey), connectTimeoutMs, readTimeoutMs);
|
|
|
+ return processResponseXml(respXml,mchKey);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:统一下单<br>
|
|
|
+ * 场景:公共号支付、扫码支付、APP支付
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public static Map<String, String> unifiedOrder(Map<String, String> reqData, String appId,String mchId,String mchKey) throws Exception {
|
|
|
+ return unifiedOrder(reqData, appId,mchId,mchKey,httpConnectTimeoutMs, httpReadTimeoutMs);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:统一下单<br>
|
|
|
+ * 场景:公共号支付、扫码支付、APP支付
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @param connectTimeoutMs 连接超时时间,单位是毫秒
|
|
|
+ * @param readTimeoutMs 读超时时间,单位是毫秒
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public static Map<String, String> unifiedOrder(Map<String, String> reqData, String appId,String mchId,String mchKey,
|
|
|
+ int connectTimeoutMs, int readTimeoutMs) throws Exception {
|
|
|
+ String url;
|
|
|
+ if (useSandbox) {
|
|
|
+ url = WXPayConstants.SANDBOX_UNIFIEDORDER_URL;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ url = WXPayConstants.UNIFIEDORDER_URL;
|
|
|
+ }
|
|
|
+ String respXml = requestWithoutCert(url, fillRequestData(reqData,appId,mchId,mchKey), connectTimeoutMs, readTimeoutMs);
|
|
|
+ return processResponseXml(respXml,mchKey);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:查询订单<br>
|
|
|
+ * 场景:刷卡支付、公共号支付、扫码支付、APP支付
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public Map<String, String> orderQuery(Map<String, String> reqData, String appId,String mchId,String mchKey) throws Exception {
|
|
|
+ return orderQuery(reqData,appId,mchId,mchKey, httpConnectTimeoutMs, httpReadTimeoutMs);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:查询订单<br>
|
|
|
+ * 场景:刷卡支付、公共号支付、扫码支付、APP支付
|
|
|
+ * @param reqData 向wxpay post的请求数据 int
|
|
|
+ * @param connectTimeoutMs 连接超时时间,单位是毫秒
|
|
|
+ * @param readTimeoutMs 读超时时间,单位是毫秒
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public Map<String, String> orderQuery(Map<String, String> reqData, String appId,String mchId,String mchKey,
|
|
|
+ int connectTimeoutMs, int readTimeoutMs) throws Exception {
|
|
|
+ String url;
|
|
|
+ if (useSandbox) {
|
|
|
+ url = WXPayConstants.SANDBOX_ORDERQUERY_URL;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ url = WXPayConstants.ORDERQUERY_URL;
|
|
|
+ }
|
|
|
+ String respXml = requestWithoutCert(url, fillRequestData(reqData,appId,mchId,mchKey), connectTimeoutMs, readTimeoutMs);
|
|
|
+ return processResponseXml(respXml,mchKey);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:撤销订单<br>
|
|
|
+ * 场景:刷卡支付
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public Map<String, String> reverse(Map<String, String> reqData, String appId,String mchId,String mchKey) throws Exception {
|
|
|
+ return reverse(reqData,appId,mchId,mchKey, httpConnectTimeoutMs, httpReadTimeoutMs);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:撤销订单<br>
|
|
|
+ * 场景:刷卡支付<br>
|
|
|
+ * 其他:需要证书
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @param connectTimeoutMs 连接超时时间,单位是毫秒
|
|
|
+ * @param readTimeoutMs 读超时时间,单位是毫秒
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public Map<String, String> reverse(Map<String, String> reqData, String appId,String mchId,String mchKey,
|
|
|
+ int connectTimeoutMs, int readTimeoutMs) throws Exception {
|
|
|
+ String url;
|
|
|
+ if (useSandbox) {
|
|
|
+ url = WXPayConstants.SANDBOX_REVERSE_URL;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ url = WXPayConstants.REVERSE_URL;
|
|
|
+ }
|
|
|
+ String respXml = requestWithCert(url, fillRequestData(reqData,appId,mchId,mchKey), mchId,connectTimeoutMs, readTimeoutMs);
|
|
|
+ return processResponseXml(respXml,mchKey);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:关闭订单<br>
|
|
|
+ * 场景:公共号支付、扫码支付、APP支付
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public Map<String, String> closeOrder(Map<String, String> reqData, String appId,String mchId,String mchKey) throws Exception {
|
|
|
+ return closeOrder(reqData,appId,mchId,mchKey, httpConnectTimeoutMs, httpReadTimeoutMs);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:关闭订单<br>
|
|
|
+ * 场景:公共号支付、扫码支付、APP支付
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @param connectTimeoutMs 连接超时时间,单位是毫秒
|
|
|
+ * @param readTimeoutMs 读超时时间,单位是毫秒
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public Map<String, String> closeOrder(Map<String, String> reqData, String appId,String mchId,String mchKey,
|
|
|
+ int connectTimeoutMs, int readTimeoutMs) throws Exception {
|
|
|
+ String url;
|
|
|
+ if (useSandbox) {
|
|
|
+ url = WXPayConstants.SANDBOX_CLOSEORDER_URL;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ url = WXPayConstants.CLOSEORDER_URL;
|
|
|
+ }
|
|
|
+ String respXml = requestWithoutCert(url, fillRequestData(reqData,appId,mchId,mchKey), connectTimeoutMs, readTimeoutMs);
|
|
|
+ return processResponseXml(respXml,mchKey);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:申请退款<br>
|
|
|
+ * 场景:刷卡支付、公共号支付、扫码支付、APP支付
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public Map<String, String> refund(Map<String, String> reqData, String appId,String mchId,String mchKey) throws Exception {
|
|
|
+ return refund(reqData, appId,mchId,mchKey,httpConnectTimeoutMs, httpReadTimeoutMs);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:申请退款<br>
|
|
|
+ * 场景:刷卡支付、公共号支付、扫码支付、APP支付<br>
|
|
|
+ * 其他:需要证书
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @param connectTimeoutMs 连接超时时间,单位是毫秒
|
|
|
+ * @param readTimeoutMs 读超时时间,单位是毫秒
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public Map<String, String> refund(Map<String, String> reqData, String appId,String mchId,String mchKey,int connectTimeoutMs, int readTimeoutMs) throws Exception {
|
|
|
+ String url;
|
|
|
+ if (useSandbox) {
|
|
|
+ url = WXPayConstants.SANDBOX_REFUND_URL;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ url = WXPayConstants.REFUND_URL;
|
|
|
+ }
|
|
|
+ String respXml = requestWithCert(url, fillRequestData(reqData,appId,mchId,mchKey),mchId, connectTimeoutMs, readTimeoutMs);
|
|
|
+ return processResponseXml(respXml,mchKey);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:退款查询<br>
|
|
|
+ * 场景:刷卡支付、公共号支付、扫码支付、APP支付
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public Map<String, String> refundQuery(Map<String, String> reqData, String appId,String mchId,String mchKey) throws Exception {
|
|
|
+ return refundQuery(reqData,appId,mchId,mchKey, httpConnectTimeoutMs, httpReadTimeoutMs);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:退款查询<br>
|
|
|
+ * 场景:刷卡支付、公共号支付、扫码支付、APP支付
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @param connectTimeoutMs 连接超时时间,单位是毫秒
|
|
|
+ * @param readTimeoutMs 读超时时间,单位是毫秒
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public Map<String, String> refundQuery(Map<String, String> reqData, String appId,String mchId,String mchKey,
|
|
|
+ int connectTimeoutMs, int readTimeoutMs) throws Exception {
|
|
|
+ String url;
|
|
|
+ if (useSandbox) {
|
|
|
+ url = WXPayConstants.SANDBOX_REFUNDQUERY_URL;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ url = WXPayConstants.REFUNDQUERY_URL;
|
|
|
+ }
|
|
|
+ String respXml = requestWithoutCert(url, fillRequestData(reqData,appId,mchId,mchKey), connectTimeoutMs, readTimeoutMs);
|
|
|
+ return processResponseXml(respXml,mchKey);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:对账单下载(成功时返回对账单数据,失败时返回XML格式数据)<br>
|
|
|
+ * 场景:刷卡支付、公共号支付、扫码支付、APP支付
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public Map<String, String> downloadBill(Map<String, String> reqData, String appId,String mchId,String mchKey) throws Exception {
|
|
|
+ return downloadBill(reqData, appId,mchId,mchKey,httpConnectTimeoutMs, httpReadTimeoutMs);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:对账单下载<br>
|
|
|
+ * 场景:刷卡支付、公共号支付、扫码支付、APP支付<br>
|
|
|
+ * 其他:无论是否成功都返回Map。若成功,返回的Map中含有return_code、return_msg、data,
|
|
|
+ * 其中return_code为`SUCCESS`,data为对账单数据。
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @param connectTimeoutMs 连接超时时间,单位是毫秒
|
|
|
+ * @param readTimeoutMs 读超时时间,单位是毫秒
|
|
|
+ * @return 经过封装的API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public Map<String, String> downloadBill(Map<String, String> reqData, String appId,String mchId,String mchKey, int connectTimeoutMs, int readTimeoutMs) throws Exception {
|
|
|
+ String url;
|
|
|
+ if (useSandbox) {
|
|
|
+ url = WXPayConstants.SANDBOX_DOWNLOADBILL_URL;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ url = WXPayConstants.DOWNLOADBILL_URL;
|
|
|
+ }
|
|
|
+ String respStr = requestWithoutCert(url, fillRequestData(reqData,appId,mchId,mchKey), connectTimeoutMs, readTimeoutMs).trim();
|
|
|
+ Map<String, String> ret;
|
|
|
+ // 出现错误,返回XML数据
|
|
|
+ if (respStr.indexOf("<") == 0) {
|
|
|
+ ret = WXPayUtil.xmlToMap(respStr);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // 正常返回csv数据
|
|
|
+ ret = new HashMap<String, String>();
|
|
|
+ ret.put("return_code", WXPayConstants.SUCCESS);
|
|
|
+ ret.put("return_msg", "sdk");
|
|
|
+ ret.put("data", respStr);
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:交易保障<br>
|
|
|
+ * 场景:刷卡支付、公共号支付、扫码支付、APP支付
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public Map<String, String> report(Map<String, String> reqData, String appId,String mchId,String mchKey) throws Exception {
|
|
|
+ return report(reqData, appId,mchId,mchKey,httpConnectTimeoutMs, httpReadTimeoutMs);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:交易保障<br>
|
|
|
+ * 场景:刷卡支付、公共号支付、扫码支付、APP支付
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @param connectTimeoutMs 连接超时时间,单位是毫秒
|
|
|
+ * @param readTimeoutMs 读超时时间,单位是毫秒
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public Map<String, String> report(Map<String, String> reqData, String appId,String mchId,String mchKey, int connectTimeoutMs, int readTimeoutMs) throws Exception {
|
|
|
+ String url;
|
|
|
+ if (useSandbox) {
|
|
|
+ url = WXPayConstants.SANDBOX_REPORT_URL;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ url = WXPayConstants.REPORT_URL;
|
|
|
+ }
|
|
|
+ String respXml = requestWithoutCert(url, fillRequestData(reqData,appId,mchId,mchKey), connectTimeoutMs, readTimeoutMs);
|
|
|
+ return WXPayUtil.xmlToMap(respXml);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:转换短链接<br>
|
|
|
+ * 场景:刷卡支付、扫码支付
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public Map<String, String> shortUrl(Map<String, String> reqData, String appId,String mchId,String mchKey) throws Exception {
|
|
|
+ return shortUrl(reqData, appId,mchId,mchKey,httpConnectTimeoutMs, httpReadTimeoutMs);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:转换短链接<br>
|
|
|
+ * 场景:刷卡支付、扫码支付
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public Map<String, String> shortUrl(Map<String, String> reqData, String appId,String mchId,String mchKey, int connectTimeoutMs, int readTimeoutMs) throws Exception {
|
|
|
+ String url;
|
|
|
+ if (useSandbox) {
|
|
|
+ url = WXPayConstants.SANDBOX_SHORTURL_URL;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ url = WXPayConstants.SHORTURL_URL;
|
|
|
+ }
|
|
|
+ String respXml = requestWithoutCert(url, fillRequestData(reqData,appId,mchId,mchKey), connectTimeoutMs, readTimeoutMs);
|
|
|
+ return processResponseXml(respXml,mchKey);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:授权码查询OPENID接口<br>
|
|
|
+ * 场景:刷卡支付
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public Map<String, String> authCodeToOpenid(Map<String, String> reqData, String appId,String mchId,String mchKey) throws Exception {
|
|
|
+ return authCodeToOpenid(reqData,appId,mchId,mchKey, httpConnectTimeoutMs, httpReadTimeoutMs);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 作用:授权码查询OPENID接口<br>
|
|
|
+ * 场景:刷卡支付
|
|
|
+ * @param reqData 向wxpay post的请求数据
|
|
|
+ * @param connectTimeoutMs 连接超时时间,单位是毫秒
|
|
|
+ * @param readTimeoutMs 读超时时间,单位是毫秒
|
|
|
+ * @return API返回数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public Map<String, String> authCodeToOpenid(Map<String, String> reqData, String appId,String mchId,String mchKey, int connectTimeoutMs, int readTimeoutMs) throws Exception {
|
|
|
+ String url;
|
|
|
+ if (useSandbox) {
|
|
|
+ url = WXPayConstants.SANDBOX_AUTHCODETOOPENID_URL;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ url = WXPayConstants.AUTHCODETOOPENID_URL;
|
|
|
+ }
|
|
|
+ String respXml = requestWithoutCert(url, fillRequestData(reqData,appId,mchId,mchKey), connectTimeoutMs, readTimeoutMs);
|
|
|
+ return processResponseXml(respXml,mchKey);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+} // end class
|