彭雪彬
2025-07-14 c1d20b425b10e8ba59f102dd1ab413055883eed0
oying-system/src/main/java/com/oying/modules/hwc/service/impl/SwiftPassServiceImpl.java
New file
@@ -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);
            }
        }
    }
}