package com.oying.modules.hwc.service.impl;
|
|
import com.alibaba.fastjson2.JSONObject;
|
import com.google.gson.Gson;
|
import com.oying.exception.BadRequestException;
|
import com.oying.modules.hwc.domain.HwcResponse;
|
import com.oying.modules.hwc.service.SwiftPassService;
|
import com.oying.modules.hwc.utils.SignUtil;
|
import com.oying.modules.hwc.utils.SignUtils;
|
import com.oying.modules.hwc.utils.XmlUtils;
|
import com.oying.modules.security.config.SwiftPassProperties;
|
import com.oying.modules.security.config.WeiXinProperties;
|
import com.oying.utils.CloseUtil;
|
import com.oying.utils.enums.PayTypeEnum;
|
import lombok.RequiredArgsConstructor;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
import org.apache.http.client.methods.HttpPost;
|
import org.apache.http.entity.StringEntity;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.HttpClients;
|
import org.apache.http.util.EntityUtils;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.util.*;
|
|
/**
|
* @author xin
|
* @description
|
* @date 2025/1/23 下午4:01
|
*/
|
@SuppressWarnings({"unchecked", "all"})
|
@Slf4j
|
@Service
|
@RequiredArgsConstructor
|
public class SwiftPassServiceImpl implements SwiftPassService {
|
|
private final static String version = "2.0";
|
private final static String charset = "UTF-8";
|
private final static String service_pay = "pay.weixin.jspay";
|
private final static String service_query = "unified.trade.query";
|
private final static String service_refund = "unified.trade.refund";
|
private final static String service_close = "unified.trade.close";
|
|
private final SwiftPassProperties properties;
|
private final WeiXinProperties weiXinProperties;
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public HwcResponse pay(String ip, String total, String timeExpire, String description, String openId,
|
String orderNum, PayTypeEnum status) {
|
SortedMap<String, String> map = new TreeMap<>();
|
map.put("service", service_pay);
|
map.put("version", version);
|
map.put("charset", charset);
|
map.put("sign_type", properties.getSignType());
|
map.put("is_raw", properties.getIsRaw());
|
map.put("is_minipg", properties.getIsMinipg());
|
map.put("out_trade_no", orderNum);
|
map.put("body", description);
|
map.put("sub_openid", openId);
|
map.put("sub_appid", weiXinProperties.getAppId());
|
map.put("total_fee", total);
|
map.put("mch_create_ip", ip);
|
map.put("notify_url", properties.getNotifyUrl());
|
map.put("time_expire", timeExpire);
|
map.put("nonce_str", String.valueOf(new Date().getTime()));
|
switch (status) {
|
case HWC:
|
map.put("mch_id", properties.getMchId());
|
break;
|
case HWC2:
|
map.put("mch_id", properties.getMchId2());
|
break;
|
default:
|
throw new BadRequestException("汇旺财类型错误");
|
}
|
Map<String, String> params = SignUtils.paraFilter(map);
|
StringBuilder buf = new StringBuilder((params.size() + 1) * 10);
|
SignUtils.buildPayParams(buf, params, false);
|
String preStr = buf.toString();
|
String sign_type = map.get("sign_type");
|
|
map.put("sign", SignUtil.getSign(sign_type, preStr, properties, status));
|
|
String reqUrl = properties.getReqUrl();
|
CloseableHttpResponse response = null;
|
CloseableHttpClient client = null;
|
Map<String, String> resultMap = new HashMap<>();
|
try {
|
HttpPost httpPost = new HttpPost(reqUrl);
|
StringEntity entityParams = new StringEntity(XmlUtils.parseXML(map), "utf-8");
|
httpPost.setEntity(entityParams);
|
httpPost.setHeader("Content-Type", "text/xml;utf-8");
|
client = HttpClients.createDefault();
|
response = client.execute(httpPost);
|
if (response != null && response.getEntity() != null) {
|
resultMap = XmlUtils.toMap(EntityUtils.toByteArray(response.getEntity()), "utf-8");
|
String reSign = resultMap.get("sign");
|
sign_type = resultMap.get("sign_type");
|
if (resultMap.containsKey("sign") && SignUtil.verifySign(reSign, sign_type, resultMap, properties, status)) {
|
throw new BadRequestException("验证签名错误");
|
} else {
|
if ("0".equals(resultMap.get("status")) && "0".equals(resultMap.get("result_code"))) {
|
Gson gson = new Gson();
|
return gson.fromJson(resultMap.get("pay_info"), HwcResponse.class);
|
} else {
|
throw new BadRequestException(resultMap.get("err_code") + " : " + resultMap.get("err_msg") + "\n" +
|
resultMap.get("status") + " : " + resultMap.get("message"));
|
}
|
}
|
} else {
|
throw new BadRequestException("操作失败");
|
}
|
} catch (Exception e) {
|
log.error("汇旺财下单错误请求参数:{}", params);
|
log.error("汇旺财下单错误返回参数:{}", resultMap);
|
throw new BadRequestException("汇旺财下单错误:" + e.getMessage());
|
} finally {
|
if (response != null) {
|
CloseUtil.close(response);
|
}
|
if (client != null) {
|
CloseUtil.close(client);
|
}
|
}
|
}
|
|
@Override
|
public JSONObject query(String orderNum, PayTypeEnum status) {
|
// 参数
|
SortedMap<String, String> map = new TreeMap<>();
|
map.put("service", service_query);
|
map.put("version", version);
|
map.put("charset", charset);
|
map.put("out_trade_no", orderNum);
|
map.put("sign_type", properties.getSignType());
|
switch (status) {
|
case HWC:
|
map.put("mch_id", properties.getMchId());
|
break;
|
case HWC2:
|
map.put("mch_id", properties.getMchId2());
|
break;
|
default:
|
throw new BadRequestException("汇旺财类型错误");
|
}
|
map.put("nonce_str", String.valueOf(new Date().getTime()));
|
// 签名
|
Map<String, String> params = SignUtils.paraFilter(map);
|
StringBuilder buf = new StringBuilder((params.size() + 1) * 10);
|
SignUtils.buildPayParams(buf, params, false);
|
String preStr = buf.toString();
|
String sign_type = map.get("sign_type");
|
map.put("sign", SignUtil.getSign(sign_type, preStr, properties, status));
|
// 请求
|
CloseableHttpResponse response = null;
|
CloseableHttpClient client = null;
|
Map<String, String> resultMap = new HashMap<>();
|
try {
|
HttpPost httpPost = new HttpPost(properties.getReqUrl());
|
StringEntity entityParams = new StringEntity(XmlUtils.parseXML(map), "utf-8");
|
httpPost.setEntity(entityParams);
|
httpPost.setHeader("Content-Type", "text/xml;utf-8");
|
client = HttpClients.createDefault();
|
response = client.execute(httpPost);
|
if (response != null && response.getEntity() != null) {
|
resultMap = XmlUtils.toMap(EntityUtils.toByteArray(response.getEntity()), "utf-8");
|
String reSign = resultMap.get("sign");
|
sign_type = resultMap.get("sign_type");
|
if (resultMap.containsKey("sign") && SignUtil.verifySign(reSign, sign_type, resultMap, properties, status)) {
|
throw new BadRequestException("验证签名错误");
|
} else {
|
if ("0".equals(resultMap.get("status"))) {
|
return JSONObject.parseObject(JSONObject.toJSONString(resultMap));
|
} else {
|
|
throw new BadRequestException(resultMap.get("err_code") + " : " + resultMap.get("err_msg") + "\n" +
|
resultMap.get("status") + " : " + resultMap.get("message"));
|
}
|
}
|
} else {
|
throw new BadRequestException("操作失败!");
|
}
|
} catch (Exception e) {
|
log.error("请求参数:{}", params);
|
log.error("返回参数:{}", resultMap);
|
throw new BadRequestException("操作失败,原因:" + e.getMessage());
|
} finally {
|
if (response != null) {
|
CloseUtil.close(response);
|
}
|
if (client != null) {
|
CloseUtil.close(client);
|
}
|
}
|
}
|
|
@Override
|
public void closeOrder(String outTradeNo, PayTypeEnum status) {
|
// 参数
|
SortedMap<String, String> map = new TreeMap<>();
|
map.put("service", service_close);
|
map.put("version", version);
|
map.put("charset", charset);
|
map.put("out_trade_no", outTradeNo);
|
map.put("sign_type", properties.getSignType());
|
switch (status) {
|
case HWC:
|
map.put("mch_id", properties.getMchId());
|
break;
|
case HWC2:
|
map.put("mch_id", properties.getMchId2());
|
break;
|
default:
|
throw new BadRequestException("汇旺财类型错误");
|
}
|
map.put("nonce_str", String.valueOf(new Date().getTime()));
|
// 签名
|
Map<String, String> params = SignUtils.paraFilter(map);
|
StringBuilder buf = new StringBuilder((params.size() + 1) * 10);
|
SignUtils.buildPayParams(buf, params, false);
|
String preStr = buf.toString();
|
String sign_type = map.get("sign_type");
|
map.put("sign", SignUtil.getSign(sign_type, preStr, properties, status));
|
// 请求
|
CloseableHttpResponse response = null;
|
CloseableHttpClient client = null;
|
Map<String, String> resultMap = new HashMap<>();
|
try {
|
HttpPost httpPost = new HttpPost(properties.getReqUrl());
|
StringEntity entityParams = new StringEntity(XmlUtils.parseXML(map), "utf-8");
|
httpPost.setEntity(entityParams);
|
httpPost.setHeader("Content-Type", "text/xml;utf-8");
|
client = HttpClients.createDefault();
|
response = client.execute(httpPost);
|
if (response != null && response.getEntity() != null) {
|
resultMap = XmlUtils.toMap(EntityUtils.toByteArray(response.getEntity()), "utf-8");
|
String reSign = resultMap.get("sign");
|
sign_type = resultMap.get("sign_type");
|
if (resultMap.containsKey("sign") && SignUtil.verifySign(reSign, sign_type, resultMap, properties, status)) {
|
throw new BadRequestException("验证签名错误");
|
} else {
|
if (!("0".equals(resultMap.get("status")))) {
|
throw new BadRequestException(resultMap.get("err_code") + " : " + resultMap.get("err_msg") + "\n" +
|
resultMap.get("status") + " : " + resultMap.get("message"));
|
}
|
}
|
} else {
|
throw new BadRequestException("操作失败!");
|
}
|
} catch (Exception e) {
|
log.error("请求参数:{}", params);
|
log.error("返回参数:{}", resultMap);
|
throw new BadRequestException("操作失败,原因:" + e.getMessage());
|
} finally {
|
if (response != null) {
|
CloseUtil.close(response);
|
}
|
if (client != null) {
|
CloseUtil.close(client);
|
}
|
}
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Map<String, String> refund(String returnNum, String orderNum, String reason, long refund,
|
long total, PayTypeEnum payType) {
|
// 参数
|
SortedMap<String, String> map = new TreeMap<>();
|
map.put("service", service_refund);
|
map.put("version", version);
|
map.put("charset", charset);
|
map.put("sign_type", properties.getSignType());
|
map.put("out_trade_no", orderNum);
|
map.put("out_refund_no", returnNum);
|
map.put("total_fee", String.valueOf(total));
|
map.put("refund_fee", String.valueOf(refund));
|
map.put("nonce_str", String.valueOf(new Date().getTime()));
|
switch (payType) {
|
case HWC:
|
map.put("mch_id", properties.getMchId());
|
map.put("op_user_id", properties.getMchId());
|
break;
|
case HWC2:
|
map.put("mch_id", properties.getMchId2());
|
map.put("op_user_id", properties.getMchId2());
|
break;
|
default:
|
throw new BadRequestException("汇旺财类型错误");
|
}
|
// 签名
|
Map<String, String> params = SignUtils.paraFilter(map);
|
StringBuilder buf = new StringBuilder((params.size() + 1) * 10);
|
SignUtils.buildPayParams(buf, params, false);
|
String preStr = buf.toString();
|
String sign_type = map.get("sign_type");
|
map.put("sign", SignUtil.getSign(sign_type, preStr, properties, payType));
|
// 参数
|
CloseableHttpResponse response = null;
|
CloseableHttpClient client = null;
|
Map<String, String> resultMap = new HashMap<>();
|
try {
|
HttpPost httpPost = new HttpPost(properties.getReqUrl());
|
StringEntity entityParams = new StringEntity(XmlUtils.parseXML(map), "utf-8");
|
httpPost.setEntity(entityParams);
|
httpPost.setHeader("Content-Type", "text/xml;utf-8");
|
client = HttpClients.createDefault();
|
response = client.execute(httpPost);
|
if (response != null && response.getEntity() != null) {
|
resultMap = XmlUtils.toMap(EntityUtils.toByteArray(response.getEntity()), "utf-8");
|
if (resultMap.containsKey("sign") && SignUtil.verifySign(resultMap.get("sign"), resultMap.get("sign_type"), resultMap, properties, payType)) {
|
throw new BadRequestException("验证签名错误");
|
} else {
|
if ("0".equals(resultMap.get("status"))) {
|
return resultMap;
|
} else {
|
throw new BadRequestException(resultMap.get("err_code") + " : " + resultMap.get("err_msg") + "\n" +
|
resultMap.get("status") + " : " + resultMap.get("message"));
|
}
|
}
|
} else {
|
throw new BadRequestException("操作失败!");
|
}
|
} catch (Exception e) {
|
log.error("请求参数:{}", params);
|
log.error("返回参数:{}", resultMap);
|
throw new BadRequestException("操作失败,原因:" + e);
|
} finally {
|
if (response != null) {
|
CloseUtil.close(response);
|
}
|
if (client != null) {
|
CloseUtil.close(client);
|
}
|
}
|
}
|
|
|
}
|