package com.ruoyi.other.util.withdraw;
|
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONObject;
|
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
import com.ruoyi.common.core.utils.StringUtils;
|
import com.ruoyi.other.api.domain.ShopWithdraw;
|
import com.ruoyi.other.util.BankCode;
|
import com.ruoyi.other.util.pay.HttpRequester;
|
import com.ruoyi.other.util.pay.HttpRespons;
|
import org.apache.http.HttpResponse;
|
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.config.RequestConfig;
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpPost;
|
import org.apache.http.conn.ClientConnectionManager;
|
import org.apache.http.conn.scheme.Scheme;
|
import org.apache.http.conn.scheme.SchemeRegistry;
|
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
|
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
import org.apache.http.conn.ssl.SSLSocketFactory;
|
import org.apache.http.entity.StringEntity;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.DefaultHttpClient;
|
import org.apache.http.impl.client.HttpClients;
|
|
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.TrustManager;
|
import javax.net.ssl.X509TrustManager;
|
import java.io.*;
|
import java.net.URLEncoder;
|
import java.nio.charset.StandardCharsets;
|
import java.security.KeyManagementException;
|
import java.security.MessageDigest;
|
import java.security.NoSuchAlgorithmException;
|
import java.security.cert.X509Certificate;
|
import java.util.ArrayList;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.regex.Matcher;
|
import java.util.regex.Pattern;
|
|
/**
|
* 三方提现工具类
|
*/
|
public class HttpUtilWithdraw {
|
|
//设置请求和传输超时时间
|
private static RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();
|
//初始化需要用到的参数
|
private static final String CLIENT_TYPE = "1";
|
private static final String CLIENT_VERSION = "1.0.0";
|
private static final String APP_CONFIG_ID = "8597918391594056444";
|
private static final String API_KEY = "jo_pay_S4UIWYjWmy46d9yX9N2QWZffD";
|
private static final String API_SECRET = "cad03aaf2019530090d642aa9b2f0cbb";
|
|
private static final String STRING_KEY = "pay_open_api_vwHXa2ay1Dv7E${clientType}${clientVersion}${apiKey}${apiSecret}${timestamp}";
|
private static final String URL = "https://pay.new.jieoukeji.cn/jo-pay-open-api";
|
private static final String PATH = "/v1/safe/withdraw";//示例接口:获取银行卡信息
|
private static final Pattern VALUE_PATTERN = Pattern.compile("\\$\\{([^}]*)\\}");
|
|
public static void main(String[] args) throws IOException {
|
long timestamp = System.currentTimeMillis();
|
Map<String,String> headers = new HashMap<>(6);
|
headers.put("client-type",CLIENT_TYPE);
|
headers.put("client-version",CLIENT_VERSION);
|
headers.put("api-secret",API_SECRET);
|
headers.put("api-key",API_KEY);
|
headers.put("access-timestamp",String.valueOf(timestamp));
|
headers.put("Content-Type","application/json");
|
//拼接字符串,签名开头保留,${} 全替换为header参数
|
headers.put("access-sign",getSign(STRING_KEY,timestamp));
|
//开始请求API接口
|
Map<String, Object> param = new HashMap<>();
|
param.put("orderCode", "09127389681694");
|
param.put("cardNo", "6228480469852935177");
|
param.put("name", "周帅");
|
param.put("withdrawType", "1");
|
param.put("accountType", "00");
|
param.put("bankName", "中国农业银行");
|
// param.put("brachBankCode", "123546345674573457");
|
param.put("money", "0.1");
|
param.put("appConfigId", APP_CONFIG_ID);
|
try {
|
String results = post(URL+PATH,headers, param);
|
//返回结果JSON字符串
|
System.out.println(results);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
|
|
// String url = "https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&" +
|
// "cardNo=" + "6228480469852935177" + "&cardBinCheck=true";
|
// HashMap<String, String> hashMap = new HashMap<>();
|
// HttpRequester hr = new HttpRequester();
|
// HttpRespons HP = hr.sendPost(url, hashMap);
|
// System.out.println("接收返回参数:" + HP.getContent());
|
// JSONObject resPay = JSONObject.parseObject(HP.getContent());
|
// System.err.println(resPay);
|
// if (resPay.getString("validated") == null) {
|
// System.err.println("不合法的银行卡号");
|
// }
|
// String bankName = BankCode.getBankNameByCode("ABC"); // 返回ABC枚举实例
|
// System.err.println(bankName);
|
}
|
|
public static String withdraw(ShopWithdraw shopWithdraw, String bankName) {
|
long timestamp = System.currentTimeMillis();
|
Map<String, String> headers = new HashMap<>(6);
|
headers.put("client-type", CLIENT_TYPE);
|
headers.put("client-version", CLIENT_VERSION);
|
headers.put("api-secret", API_SECRET);
|
headers.put("api-key", API_KEY);
|
headers.put("access-timestamp", String.valueOf(timestamp));
|
headers.put("Content-Type", "application/json");
|
//拼接字符串,签名开头保留,${} 全替换为header参数
|
headers.put("access-sign", getSign(STRING_KEY, timestamp));
|
//开始请求API接口
|
Map<String, Object> param = new HashMap<>();
|
param.put("orderCode", shopWithdraw.getCode());
|
param.put("cardNo", shopWithdraw.getReceiverAccountNoEnc());
|
param.put("name", shopWithdraw.getReceiverNameEnc());
|
param.put("withdrawType", "1");
|
if (shopWithdraw.getReceiverAccountType().equals(204)) {
|
param.put("accountType", "01");
|
param.put("bankName", bankName);
|
param.put("brachBankCode", shopWithdraw.getReceiverBankChannelNo());
|
} else {
|
param.put("accountType", "00");
|
}
|
param.put("money", shopWithdraw.getMoney());
|
param.put("appConfigId", APP_CONFIG_ID);
|
try {
|
String results = post(URL + PATH, headers, param);
|
//返回结果JSON字符串
|
System.out.println(results);
|
JSONObject jsonObject = JSONObject.parseObject(results);
|
if (jsonObject.getString("result").equals("true")){
|
return "success";
|
}else{
|
return jsonObject.getString("message");
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
return "打款失败";
|
}
|
|
/**
|
* 发起post请求,请求参数以Map集合形式传入
|
*
|
* @param httpUrl
|
* @param body
|
* @return
|
* @throws Exception
|
*/
|
public static String post(String httpUrl, Map<String, String> headers, Map<String, Object> body) {
|
CloseableHttpClient httpclient = createSSLClientDefault();
|
BufferedReader in;
|
HttpPost httpPost = new HttpPost(httpUrl);
|
try {
|
httpPost.setHeader("Accept", "application/json");
|
for (Map.Entry<String, String> headerMap : headers.entrySet()) {
|
httpPost.addHeader(headerMap.getKey(), headerMap.getValue());
|
}
|
httpPost.setConfig(requestConfig);
|
StringEntity entity = new StringEntity(JSON.toJSONString(body), StandardCharsets.UTF_8);
|
entity.setContentType("application/json");
|
httpPost.setEntity(entity);
|
|
CloseableHttpResponse response = httpclient.execute(httpPost);
|
InputStream content = response.getEntity().getContent();
|
in = new BufferedReader(new InputStreamReader(content, StandardCharsets.UTF_8));
|
StringBuilder sb = new StringBuilder();
|
String line;
|
while ((line = in.readLine()) != null) {
|
sb.append(line);
|
}
|
return sb.toString();
|
} catch (Exception e) {
|
e.printStackTrace();
|
} finally {
|
try {
|
httpclient.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
return null;
|
}
|
|
/**
|
* 发起get请求,请求参数以Map集合形式传入
|
*
|
* @param httpUrl
|
* @param params
|
* @return
|
* @throws Exception
|
*/
|
public static String get(String httpUrl, Map<String, String> headers, Map<String, String> params) {
|
CloseableHttpClient httpclient = createSSLClientDefault();
|
BufferedReader in;
|
List<String> paramList = new ArrayList<>();
|
for (Map.Entry<String, String> param : params.entrySet()) {
|
paramList.add(param.getKey() + "=" + param.getValue());
|
}
|
HttpGet httpGet = new HttpGet(httpUrl + "?" + String.join("&", paramList));
|
try {
|
httpGet.setHeader("Accept", "application/json");
|
for (Map.Entry<String, String> headerMap : headers.entrySet()) {
|
httpGet.addHeader(headerMap.getKey(), headerMap.getValue());
|
}
|
httpGet.setConfig(requestConfig);
|
|
CloseableHttpResponse response = httpclient.execute(httpGet);
|
InputStream content = response.getEntity().getContent();
|
in = new BufferedReader(new InputStreamReader(content, StandardCharsets.UTF_8));
|
StringBuilder sb = new StringBuilder();
|
String line;
|
while ((line = in.readLine()) != null) {
|
sb.append(line);
|
}
|
return sb.toString();
|
} catch (Exception e) {
|
e.printStackTrace();
|
} finally {
|
try {
|
httpclient.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
return null;
|
}
|
|
public static CloseableHttpClient createSSLClientDefault() {
|
try {
|
// SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
|
// 在JSSE中,证书信任管理器类就是实现了接口X509TrustManager的类。我们可以自己实现该接口,让它信任我们指定的证书。
|
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
|
// 信任所有
|
X509TrustManager x509mgr = new X509TrustManager() {
|
// 该方法检查客户端的证书,若不信任该证书则抛出异常
|
@Override
|
public void checkClientTrusted(X509Certificate[] xcs, String string) {
|
}
|
|
// 该方法检查服务端的证书,若不信任该证书则抛出异常
|
@Override
|
public void checkServerTrusted(X509Certificate[] xcs, String string) {
|
}
|
|
// 返回受信任的X509证书数组。
|
@Override
|
public X509Certificate[] getAcceptedIssuers() {
|
return null;
|
}
|
};
|
SSLContext sslContext = SSLContext.getInstance(SSLConnectionSocketFactory.TLS);
|
sslContext.init(null, new TrustManager[]{x509mgr}, null);
|
// 创建HttpsURLConnection对象,并设置其SSLSocketFactory对象
|
SSLConnectionSocketFactory sslSf = new SSLConnectionSocketFactory(sslContext, new DefaultHostnameVerifier());
|
// HttpsURLConnection对象就可以正常连接HTTPS了,无论其证书是否经权威机构的验证,只要实现了接口X509TrustManager的类MyX509TrustManager信任该证书。
|
return HttpClients.custom().setSSLSocketFactory(sslSf).build();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
// 创建默认的httpClient实例.
|
return HttpClients.createDefault();
|
}
|
|
/**
|
* 获取签名前准备参数
|
*
|
* @param format
|
* @param timestamp
|
* @return
|
*/
|
public static String getSign(String format, long timestamp) {
|
JSONObject dataSign = new JSONObject();
|
dataSign.put("clientType", CLIENT_TYPE);
|
dataSign.put("clientVersion", CLIENT_VERSION);
|
dataSign.put("apiSecret", API_SECRET);
|
dataSign.put("apiKey", API_KEY);
|
dataSign.put("timestamp", timestamp);
|
String formatData = getFormatData(dataSign, format);
|
return md5(formatData);
|
}
|
|
/**
|
* 拼接替换生成签名前字符串
|
*
|
* @return
|
*/
|
public static String getFormatData(JSONObject data, String format) {
|
|
System.err.println(data);
|
System.err.println(format);
|
Matcher matcher = VALUE_PATTERN.matcher(format);
|
while (true) {
|
while (matcher.find()) {
|
String sign = matcher.group();
|
String key = matcher.group(1);
|
if (ObjectUtils.isNotEmpty(key)) {
|
format = format.replace(sign, data.containsKey(key) && ObjectUtils.isNotEmpty(data.getString(key)) && !"null".equalsIgnoreCase(data.getString(key)) ? data.getString(key) : "");
|
} else {
|
format = format.replace(sign, "");
|
}
|
}
|
return format;
|
}
|
}
|
|
/**
|
* 生成md5,小写
|
*
|
* @param message
|
* @return
|
*/
|
public static String md5(String message) {
|
try {
|
// 1 创建一个提供信息摘要算法的对象,初始化为md5算法对象
|
MessageDigest md = MessageDigest.getInstance("MD5");
|
|
// 2 将消息变成byte数组
|
byte[] input = message.getBytes();
|
|
// 3 计算后获得字节数组,这就是那128位了
|
byte[] buff = md.digest(input);
|
|
// 4 把数组每一字节(一个字节占八位)换成16进制连成md5字符串
|
return byte2hex(buff);
|
} catch (Exception e) {
|
throw new RuntimeException(e);
|
}
|
}
|
|
/**
|
* 二进制转十六进制字符串
|
*
|
* @param bytes
|
* @return
|
*/
|
private static String byte2hex(byte[] bytes) {
|
StringBuilder sign = new StringBuilder();
|
for (int i = 0; i < bytes.length; i++) {
|
String hex = Integer.toHexString(bytes[i] & 0xFF);
|
if (hex.length() == 1) {
|
sign.append("0");
|
}
|
sign.append(hex.toLowerCase());
|
}
|
return sign.toString();
|
}
|
|
/**
|
* 调用apiPost方法
|
*
|
* @return
|
*/
|
public static HttpResponse doPost(String host, String path, String method,
|
Map<String, String> headers,
|
Map<String, String> querys,
|
String body)
|
throws Exception {
|
HttpClient httpClient = wrapClient(host);
|
|
HttpPost request = new HttpPost(buildUrl(host, path, querys));
|
for (Map.Entry<String, String> e : headers.entrySet()) {
|
request.addHeader(e.getKey(), e.getValue());
|
}
|
|
if (StringUtils.isNotBlank(body)) {
|
request.setEntity(new StringEntity(body, "utf-8"));
|
}
|
return httpClient.execute(request);
|
}
|
|
public static HttpClient wrapClient(String host) {
|
HttpClient httpClient = new DefaultHttpClient();
|
if (host.startsWith("https://")) {
|
sslClient(httpClient);
|
}
|
|
return httpClient;
|
}
|
|
public static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException {
|
StringBuilder sbUrl = new StringBuilder();
|
sbUrl.append(host);
|
if (!StringUtils.isBlank(path)) {
|
sbUrl.append(path);
|
}
|
if (null != querys) {
|
StringBuilder sbQuery = new StringBuilder();
|
for (Map.Entry<String, String> query : querys.entrySet()) {
|
if (0 < sbQuery.length()) {
|
sbQuery.append("&");
|
}
|
if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) {
|
sbQuery.append(query.getValue());
|
}
|
if (!StringUtils.isBlank(query.getKey())) {
|
sbQuery.append(query.getKey());
|
if (!StringUtils.isBlank(query.getValue())) {
|
sbQuery.append("=");
|
sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8"));
|
}
|
}
|
}
|
if (0 < sbQuery.length()) {
|
sbUrl.append("?").append(sbQuery);
|
}
|
}
|
|
return sbUrl.toString();
|
}
|
|
private static void sslClient(HttpClient httpClient) {
|
try {
|
SSLContext ctx = SSLContext.getInstance("TLS");
|
X509TrustManager tm = new X509TrustManager() {
|
@Override
|
public X509Certificate[] getAcceptedIssuers() {
|
return null;
|
}
|
|
@Override
|
public void checkClientTrusted(X509Certificate[] xcs, String str) {
|
|
}
|
|
@Override
|
public void checkServerTrusted(X509Certificate[] xcs, String str) {
|
|
}
|
};
|
ctx.init(null, new TrustManager[]{tm}, null);
|
SSLSocketFactory ssf = new SSLSocketFactory(ctx);
|
ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
|
ClientConnectionManager ccm = httpClient.getConnectionManager();
|
SchemeRegistry registry = ccm.getSchemeRegistry();
|
registry.register(new Scheme("https", 443, ssf));
|
} catch (KeyManagementException ex) {
|
throw new RuntimeException(ex);
|
} catch (NoSuchAlgorithmException ex) {
|
throw new RuntimeException(ex);
|
}
|
}
|
}
|