From c1d20b425b10e8ba59f102dd1ab413055883eed0 Mon Sep 17 00:00:00 2001 From: 彭雪彬 <1724387007@qq.com> Date: Mon, 14 Jul 2025 16:57:11 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/xin' into pxb --- oying-system/src/main/java/com/oying/modules/hwc/service/impl/SwiftPassServiceImpl.java | 340 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 340 insertions(+), 0 deletions(-) diff --git a/oying-system/src/main/java/com/oying/modules/hwc/service/impl/SwiftPassServiceImpl.java b/oying-system/src/main/java/com/oying/modules/hwc/service/impl/SwiftPassServiceImpl.java new file mode 100644 index 0000000..e0a7063 --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/hwc/service/impl/SwiftPassServiceImpl.java @@ -0,0 +1,340 @@ +package com.oying.modules.hwc.service.impl; + +import com.alibaba.fastjson2.JSONObject; +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"))) { + return JSONObject.parseObject(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); + } + } + } + + +} -- Gitblit v1.9.3