package com.zsElectric.boot.business.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zsElectric.boot.business.mapper.*;
import com.zsElectric.boot.business.model.entity.*;
import com.zsElectric.boot.business.model.form.applet.AppLevelOrderForm;
import com.zsElectric.boot.business.model.form.applet.AppUserPayForm;
import com.zsElectric.boot.common.constant.SystemConstants;
import com.zsElectric.boot.core.exception.BusinessException;
import com.zsElectric.boot.core.pay.swiftpass.config.SwiftpassConfig;
import com.zsElectric.boot.core.pay.swiftpass.util.PayUtill;
import com.zsElectric.boot.core.pay.swiftpass.util.SignUtil;
import com.zsElectric.boot.core.pay.swiftpass.util.SignUtils;
import com.zsElectric.boot.core.pay.swiftpass.util.XmlUtils;
import com.zsElectric.boot.security.util.SecurityUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 威富通支付服务
 * 用于处理威富通JSAPI支付接口
 *
 * @author zsElectric
 * @since 2025-12-29
 */
@Slf4j
@Service
public class WFTOrderService {

    @Resource
    private UserOrderInfoMapper userOrderInfoMapper;

    @Resource
    private UserInfoMapper userInfoMapper;

    @Resource
    private RechargeLevelMapper rechargeLevelMapper;

    @Resource
    protected SwiftpassConfig swiftpassConfig;

    @Resource
    private UserAccountService userAccountService;

    @Resource
    private ChargeOrderInfoMapper chargeOrderInfoMapper;

    @Resource
    private UserRefundsOrderInfoMapper userRefundsOrderInfoMapper;


    /**
     * 创建商户订单号
     * 要求 32个字符内，只能是数字、大小写字母_-|*且在同一个商户号下唯一
     * 组成 两位前缀 + 17位时间戳 + 9位id补零 + 4位随机数 合计32位
     *
     * @param head 例如 商品-SP 退款-TK 等等
     * @param id   用户id
     * @return
     */
    public String createOrderNo(String head, Long id) {
        StringBuilder uid = new StringBuilder(id.toString());
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        int length = uid.length();
        for (int i = 0; i < 9 - length; i++) {
            uid.insert(0, "0");
        }
        return head + sdf.format(date) + uid + (int) ((Math.random() * 9 + 1) * 1000);
    }

    /**
     * 金额元转分字符串
     *
     * @param cny 元
     * @return
     */
    public String amount_fee(BigDecimal cny) {
        BigDecimal b2 = new BigDecimal("100");
        return cny.multiply(b2).setScale(0, RoundingMode.DOWN).toString();
    }

    /**
     * 金额分转元
     *
     * @param fen 分
     * @return 元(保留两位小数)
     */
    public BigDecimal fee_amount(Integer fen) {
        if (fen == null) {
            return BigDecimal.ZERO;
        }
        return new BigDecimal(fen).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
    }


    public AppUserPayForm createOrder(@Valid AppLevelOrderForm appLevelOrderForm) {
        Long userId = SecurityUtils.getUserId();
        String userOpenId = userInfoMapper.getAppletUserInfo(userId).getOpenid();
        String orderNo = createOrderNo("SP", userId);

        //查询档位
        RechargeLevel level = rechargeLevelMapper.selectById(appLevelOrderForm.getLevelId());

        //创建订单
        UserOrderInfo orderInfo = new UserOrderInfo();
        orderInfo.setUserId(userId);
        orderInfo.setOrderNo(orderNo);
        orderInfo.setLevelId(appLevelOrderForm.getLevelId());
        orderInfo.setOpenid(userOpenId);
        orderInfo.setOrderMoney(level.getMoney());

        userOrderInfoMapper.insert(orderInfo);

        //构建支付表单返回给前端支撑JsApi支付调用
        AppUserPayForm payForm = new AppUserPayForm();
        payForm.setOrderId(orderInfo.getId()).setOrderNo(orderNo);

        PayUtill wx = new PayUtill();

        /**
         * 小程序支付
         */
        String payWay = "1";

        /**
         * 请求支付
         */
        try {
            log.debug("通知第三开始支付：");
            // 通知第三方支付----------------------------------------------------------

            SortedMap<String, String> map = new TreeMap<String, String>();
            // 订单编号
            map.put("out_trade_no", orderNo);
            // 商品描述
            map.put("body", "购买充电抵扣券");
            // 附加信息
            map.put("attach", "支付人" + userId);

            // pifList.get(0).setHydOrderPayMoney(new BigDecimal("0.01"));
            // 总金额（分）

            map.put("total_fee", amount_fee(level.getMoney()));
            // 终端ip
            map.put("mch_create_ip", appLevelOrderForm.getIp());
            // 签名方式
            map.put("sign_type", "RSA_1_256");
            // 回调地址
            map.put("notify_url", swiftpassConfig.getNotify_url());
            // 公众账号或小程序ID
            map.put("sub_appid", "wx9894a01b9e92c368");
            if (payWay.equals("1")) {// 支付渠道（1 微信 2支付宝支付 4建行支付 6微信小程序支付）
                // 是否小程序支付--值为1，表示小程序支付；不传或值不为1，表示公众账号内支付
                map.put("is_minipg", "1");
                map.put("sub_appid", "wx9894a01b9e92c368");
            } else if (payWay.equals("2")) {
                map.put("is_minipg", "2");
            }

            // --------微信支付请求
            Map<String, Object> wxMap = wx.pay(map, userOpenId, swiftpassConfig);
            log.info("威富通支付返回结果: {}", wxMap);
            if (wxMap.get("status").toString().equals("200")) {
                payForm.setParams(wxMap);
                return payForm;
            } else {
                String errorMsg = wxMap.get("msg") != null ? wxMap.get("msg").toString() : "未知错误";
                log.error("请求支付失败，返回结果: {}", wxMap);
                throw new RuntimeException("请求支付失败：" + errorMsg);
            }
        } catch (Exception e) {
            log.error("创建订单异常，用户ID: {}, 订单号: {}", userId, orderNo, e);
            throw new RuntimeException("请求支付失败：" + e.getMessage(), e);
        }
    }

    public AppUserPayForm payOrder(String orderId, String ip) {
        UserOrderInfo orderInfo = userOrderInfoMapper.selectById(orderId);
        //构建支付表单
        AppUserPayForm payForm = new AppUserPayForm();
        payForm.setOrderId(orderInfo.getId()).setOrderNo(orderInfo.getOrderNo());

        //查询档位
        RechargeLevel level = rechargeLevelMapper.selectById(orderInfo.getLevelId());

        PayUtill wx = new PayUtill();

        /**
         * 小程序支付
         */
        String payWay = "1";

        try {
            log.debug("通知第三开始支付：");
            // 通知第三方支付----------------------------------------------------------

            SortedMap<String, String> map = new TreeMap<String, String>();
            // 订单编号
            map.put("out_trade_no", orderInfo.getOrderNo());
            // 商品描述
            map.put("body", "购买充电抵扣券");
            // 附加信息
            map.put("attach", "支付人" + orderInfo.getUserId());

            // pifList.get(0).setHydOrderPayMoney(new BigDecimal("0.01"));
            // 总金额（分）

            map.put("total_fee", amount_fee(level.getMoney()));
            // 终端ip
            map.put("mch_create_ip", ip);
            // 签名方式
            map.put("sign_type", "RSA_1_256");
            // 回调地址
            map.put("notify_url", swiftpassConfig.getNotify_url());
            // 公众账号或小程序ID
            map.put("sub_appid", "wx9894a01b9e92c368");
            if (payWay.equals("1")) {// 支付渠道（1 微信 2支付宝支付 4建行支付 6微信小程序支付）
                // 是否小程序支付--值为1，表示小程序支付；不传或值不为1，表示公众账号内支付
                map.put("is_minipg", "1");
                map.put("sub_appid", "wx9894a01b9e92c368");
            } else if (payWay.equals("2")) {
                map.put("is_minipg", "2");
            }

            // --------微信支付请求
            Map<String, Object> wxMap = wx.pay(map, orderInfo.getOpenid(), swiftpassConfig);
            log.info("威富通支付返回结果: {}", wxMap);
            if (wxMap.get("status").toString().equals("200")) {
                payForm.setParams(wxMap);
                return payForm;
            } else {
                String errorMsg = wxMap.get("msg") != null ? wxMap.get("msg").toString() : "未知错误";
                log.error("支付订单失败，返回结果: {}", wxMap);
                throw new RuntimeException("支付失败：" + errorMsg);
            }
        } catch (Exception e) {
            log.error("支付订单异常，订单ID: {}", orderId, e);
            throw new RuntimeException("支付失败：" + e.getMessage(), e);
        }
    }

    public Boolean closeOrder(String orderNo) {
        UserOrderInfo userOrderInfo = userOrderInfoMapper.selectOne(Wrappers.lambdaQuery(UserOrderInfo.class).eq(UserOrderInfo::getOrderNo, orderNo).last("limit 1"));
        if (ObjectUtil.isNull(userOrderInfo)) {
            throw new BusinessException("订单不存在");
        }
        userOrderInfo.setOrderStatus(SystemConstants.STATUS_THREE);
        int i = userOrderInfoMapper.updateById(userOrderInfo);
        if (i > 0) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    /**
     * 处理威富通支付通知回调
     * <p>
     * 重要说明：
     * 1. 接收威富通POST的XML数据流
     * 2. 验证签名（支持RSA_1_256、RSA_1_1、MD5）
     * 3. 校验订单号和金额
     * 4. 幂等性处理，防止重复通知
     * 5. 使用数据库锁避免并发问题
     * 6. 更新订单状态
     * 7. 必须返回纯字符串"success"或"fail"
     * <p>
     * 通知重试机制：0/15/15/30/180/1800/1800/1800/1800/3600秒
     *
     * @param request HTTP请求对象
     * @return "success" 表示处理成功，"fail" 表示处理失败
     */
    @Transactional(rollbackFor = Exception.class)
    public String handlePayNotify(HttpServletRequest request) {
        log.info("========== 开始处理威富通支付通知 ==========");

        try {
            // 1. 读取POST的XML数据
            String xmlData = XmlUtils.parseRequst(request);
            log.info("接收到的XML通知数据: {}", xmlData);

            if (xmlData == null || xmlData.trim().isEmpty()) {
                log.error("通知数据为空");
                return "fail";
            }

            // 2. 解析XML为Map
            Map<String, String> notifyData = XmlUtils.toMap(xmlData.getBytes("UTF-8"), "UTF-8");
            log.info("解析后的通知参数: {}", notifyData);

            // 3. 验证基本参数
            String status = notifyData.get("status");
            String resultCode = notifyData.get("result_code");
            String signType = notifyData.get("sign_type");
            String sign = notifyData.get("sign");

            if (status == null || resultCode == null || signType == null || sign == null) {
                log.error("通知参数缺失: status={}, result_code={}, sign_type={}, sign={}",
                        status, resultCode, signType, sign);
                return "fail";
            }

            // 4. 验证签名
            boolean signValid = SignUtil.verifySign(sign, signType, notifyData, swiftpassConfig);
            if (!signValid) {
                log.error("签名验证失败");
                return "fail";
            }
            log.info("签名验证成功");

            // 5. 检查通信状态和业务结果
            if (!"0".equals(status)) {
                log.error("通信状态失败: status={}, message={}", status, notifyData.get("message"));
                return "fail";
            }

            if (!"0".equals(resultCode)) {
                log.error("业务结果失败: result_code={}, err_code={}, err_msg={}",
                        resultCode, notifyData.get("err_code"), notifyData.get("err_msg"));
                return "fail";
            }

            // 6. 提取支付结果参数
            String payResult = notifyData.get("pay_result");
            if (!"0".equals(payResult)) {
                log.error("支付结果失败: pay_result={}, pay_info={}",
                        payResult, notifyData.get("pay_info"));
                return "fail";
            }

            // 7. 提取订单相关信息
            String orderNo = notifyData.get("out_trade_no"); //商户订单号
            String outTradeNo = notifyData.get("out_transaction_id");        // 第三方订单号
            String transactionId = notifyData.get("transaction_id");    // 平台订单号
            String totalFeeStr = notifyData.get("total_fee");           // 总金额（分）
            BigDecimal payMoney = fee_amount(Integer.parseInt(totalFeeStr));
            String timeEnd = notifyData.get("time_end");                // 支付完成时间
            //转localDateTime
            LocalDateTime payTime = LocalDateTime.parse(timeEnd, DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
            String openid = notifyData.get("openid");                   // 用户标识
            String attach = notifyData.get("attach");                   // 附加信息

            if (outTradeNo == null || transactionId == null || totalFeeStr == null) {
                log.error("订单关键参数缺失: out_trade_no={}, transaction_id={}, total_fee={}",
                        outTradeNo, transactionId, totalFeeStr);
                return "fail";
            }

            log.info("订单信息: out_trade_no={}, transaction_id={}, total_fee={}, time_end={}",
                    outTradeNo, transactionId, totalFeeStr, timeEnd);

            // 8. 查询订单并加锁（防止并发）
            UserOrderInfo orderInfo = userOrderInfoMapper.selectOne(
                    Wrappers.lambdaQuery(UserOrderInfo.class)
                            .eq(UserOrderInfo::getOrderNo, orderNo)
                            .last("FOR UPDATE")  // 数据库行锁
            );

            if (orderInfo == null) {
                log.error("订单不存在: out_trade_no={}", orderNo);
                return "fail";
            }

            // 9. 幂等性检查 - 如果订单已支付，直接返回成功
            if (SystemConstants.STATUS_TWO.equals(orderInfo.getOrderStatus())) {
                log.info("订单已支付，幂等性处理: out_trade_no={}, transaction_id={}",
                        outTradeNo, orderInfo.getTransactionId());
                return "success";
            }

            // 10. 验证订单金额
            String expectedFee = amount_fee(orderInfo.getOrderMoney());
            if (!expectedFee.equals(totalFeeStr)) {
                log.error("订单金额不匹配: expected={}, actual={}", expectedFee, totalFeeStr);
                return "fail";
            }

            // 11. 更新订单状态
            orderInfo.setOrderStatus(SystemConstants.STATUS_TWO);  // 已支付
            orderInfo.setTransactionId(transactionId);              // 平台订单号
            orderInfo.setPayMoney(payMoney); // 支付金额
            orderInfo.setOutTradeNo(outTradeNo);                 // 第三方订单号
            orderInfo.setPayTime(payTime);
            // 解析支付时间
            if (timeEnd != null && timeEnd.length() == 14) {
                try {
                    java.time.format.DateTimeFormatter formatter =
                            java.time.format.DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
                    orderInfo.setPayTime(java.time.LocalDateTime.parse(timeEnd, formatter));
                } catch (Exception e) {
                    log.warn("解析支付时间失败: time_end={}", timeEnd, e);
                }
            }

            int updateCount = userOrderInfoMapper.updateById(orderInfo);
            if (updateCount <= 0) {
                log.error("更新订单状态失败: out_trade_no={}", outTradeNo);
                return "fail";
            }

            log.info("订单支付成功: out_trade_no={}, transaction_id={}, total_fee={}",
                    outTradeNo, transactionId, totalFeeStr);

            //支付成功业务处理
            successPayOrder(orderInfo, transactionId, payTime, payMoney);

            return "success";

        } catch (Exception e) {
            log.error("处理支付通知异常", e);
            return "fail";
        } finally {
            log.info("========== 威富通支付通知处理完成 ==========");
        }
    }

    /**
     * 支付成功业务处理
     *
     * @param orderInfo
     * @param transactionId
     * @param payTime
     * @param orderMoney
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    protected void successPayOrder(UserOrderInfo orderInfo, String transactionId, LocalDateTime payTime, BigDecimal orderMoney) throws Exception {
        //修改订单状态为已支付
        orderInfo.setOrderStatus(SystemConstants.STATUS_TWO);
        orderInfo.setPayTime(payTime);
        orderInfo.setTransactionId(transactionId);
        orderInfo.setPayMoney(orderMoney);
        userOrderInfoMapper.updateById(orderInfo);

        //账户变动及日志记录
        Long userId = orderInfo.getUserId();
        UserAccount userAccount = userAccountService.updateAccountBalanceAndLog(
                userId,
                orderMoney,
                SystemConstants.CHANGE_TYPE_ADD,
                SystemConstants.ACCOUNT_LOG_PAY_NOTE,
                orderInfo.getId()
        );

        //平订单超充金额（使用更新后的账户信息）
        orderBackTax(userId, userAccount);
    }

    private void orderBackTax(Long userId, UserAccount userAccount) {
        //查询超充订单
        List<ChargeOrderInfo> chargeOrderInfoList = chargeOrderInfoMapper.selectList(Wrappers.<ChargeOrderInfo>lambdaQuery()
                .eq(ChargeOrderInfo::getUserId, userId)
                .eq(ChargeOrderInfo::getMaspStatus, SystemConstants.STATUS_ONE)
                .orderByAsc(ChargeOrderInfo::getCreateTime)
        );
        if (CollUtil.isNotEmpty(chargeOrderInfoList)) {
            //余额减去超充金额（使用更新后的余额）
            BigDecimal balance = userAccount.getBalance();
            for (ChargeOrderInfo chargeOrderInfo : chargeOrderInfoList) {

                if (balance.compareTo(BigDecimal.ZERO) > 0) {
                    BigDecimal deductAmount; // 本次扣除金额

                    if (balance.compareTo(chargeOrderInfo.getTotalMaspMoney()) < 0) {
                        //余额不足，部分补缴
                        deductAmount = balance;
                        chargeOrderInfo.setAlreadyMaspMoney(deductAmount);
                        chargeOrderInfo.setMaspDesc("部分补缴");
                        chargeOrderInfo.setMaspStatus(SystemConstants.STATUS_TWO);
                        chargeOrderInfoMapper.updateById(chargeOrderInfo);

                        //账户变动及日志记录
                        userAccountService.updateAccountBalanceAndLog(
                                userId,
                                deductAmount.negate(),
                                SystemConstants.CHANGE_TYPE_REDUCE,
                                SystemConstants.ACCOUNT_LOG_BACK_TAX_NOTE,
                                chargeOrderInfo.getId()
                        );

                        balance = BigDecimal.ZERO;
                        continue;
                    }
                    //余额足够，完成补缴
                    deductAmount = chargeOrderInfo.getTotalMaspMoney();
                    balance = balance.subtract(deductAmount);
                    chargeOrderInfo.setAlreadyMaspMoney(deductAmount);
                    chargeOrderInfo.setMaspDesc("完成补缴");
                    chargeOrderInfo.setMaspStatus(SystemConstants.STATUS_TWO);
                    chargeOrderInfoMapper.updateById(chargeOrderInfo);

                    //账户变动及日志记录
                    userAccountService.updateAccountBalanceAndLog(
                            userId,
                            deductAmount.negate(),
                            SystemConstants.CHANGE_TYPE_REDUCE,
                            SystemConstants.ACCOUNT_LOG_BACK_TAX_NOTE,
                            chargeOrderInfo.getId()
                    );
                }
            }
        }

    }

    /**
     * 订单是否支付成功查询
     * <p>
     * 应用场景：
     * 1. 用户支付后前端轮询查询订单状态
     * 2. 后台定时任务查询未支付订单
     * 3. 支付通知未收到时的补偿查询
     * <p>
     * 查询策略建议：
     * - 方案一：以订单创建时间为基准，间隔5秒/30秒/1分钟/3分钟/5分钟/10分钟/30分钟查询
     * - 方案二：定时任务每30秒查询最近10分钟内未支付订单，最多查询10次
     *
     * @param orderNo 商户订单号
     * @return true-已支付成功，false-未支付或查询失败
     */
    public Boolean queryOrder(String orderNo) {
        log.info("========== 开始查询订单支付状态 ==========");
        log.info("查询订单号: {}", orderNo);

        try {
            // 1. 查询本地订单信息
            UserOrderInfo orderInfo = userOrderInfoMapper.selectOne(
                    Wrappers.lambdaQuery(UserOrderInfo.class)
                            .eq(UserOrderInfo::getOrderNo, orderNo)
            );

            if (orderInfo == null) {
                log.error("订单不存在: orderNo={}", orderNo);
                return false;
            }

            // 2. 如果订单已经是已支付状态，直接返回true
            if (SystemConstants.STATUS_TWO.equals(orderInfo.getOrderStatus())) {
                log.info("订单已支付: orderNo={}, transactionId={}", orderNo, orderInfo.getTransactionId());
                return true;
            }

            // 3. 如果订单已取消，返回false
            if (SystemConstants.STATUS_THREE.equals(orderInfo.getOrderStatus())) {
                log.info("订单已取消: orderNo={}", orderNo);
                return false;
            }

            // 4. 构建查询请求参数
            SortedMap<String, String> queryParams = new TreeMap<>();
            queryParams.put("out_trade_no", orderNo);  // 商户订单号
            queryParams.put("sign_type", "RSA_1_256"); // 签名方式

            // 5. 调用威富通订单查询API
            Map<String, String> queryResult = queryOrderFromWFT(queryParams);

            if (!"200".equals(queryResult.get("status"))) {
                log.error("查询订单失败: orderNo={}, result={}", orderNo, queryResult);
                return false;
            }

            // 6. 解析查询结果
            String tradeState = queryResult.get("trade_state");
            String payResult = queryResult.get("pay_result");

            log.info("订单查询结果: orderNo={}, trade_state={}, pay_result={}",
                    orderNo, tradeState, payResult);

            // 7. 判断支付状态
            // trade_state: SUCCESS-支付成功, NOTPAY-未支付, CLOSED-已关闭, REFUND-转入退款
            // pay_result: 0-成功
            boolean isPaid = "SUCCESS".equals(tradeState) || "0".equals(payResult);

            // 8. 如果支付成功但本地订单状态未更新，同步更新订单状态
            if (isPaid && !SystemConstants.STATUS_TWO.equals(orderInfo.getOrderStatus())) {
                log.info("同步更新订单支付状态: orderNo={}", orderNo);
                String transactionId = queryResult.get("transaction_id");    // 平台订单号
                String totalFeeStr = queryResult.get("total_fee");           // 总金额（分）
                BigDecimal payMoney = fee_amount(Integer.parseInt(totalFeeStr));
                String timeEnd = queryResult.get("time_end");                // 支付完成时间
                //转localDateTime
                LocalDateTime payTime = LocalDateTime.parse(timeEnd, DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
                //支付成功业务处理
                successPayOrder(orderInfo, transactionId, payTime, payMoney);
            }
            return isPaid;

        } catch (Exception e) {
            log.error("查询订单支付状态异常: orderNo={}", orderNo, e);
            return false;
        } finally {
            log.info("========== 订单支付状态查询完成 ==========");
        }
    }

    /**
     * 调用威富通订单查询API
     *
     * @param queryParams 查询参数
     * @return 查询结果
     */
    private Map<String, String> queryOrderFromWFT(SortedMap<String, String> queryParams) {
        log.info("调用威富通订单查询API: params={}", queryParams);

        try {
            // 设置公共参数
            queryParams.put("service", "unified.trade.query");
            queryParams.put("version", "2.0");
            queryParams.put("charset", "UTF-8");
            queryParams.put("mch_id", swiftpassConfig.getMch_id());
            queryParams.put("nonce_str", String.valueOf(new Date().getTime()));

            // 生成签名
            Map<String, String> params = SignUtils.paraFilter(queryParams);
            StringBuilder buf = new StringBuilder((params.size() + 1) * 10);
            SignUtils.buildPayParams(buf, params, false);
            String preStr = buf.toString();
            String signType = queryParams.get("sign_type");
            String sign = SignUtil.getSign(signType, preStr, swiftpassConfig);
            queryParams.put("sign", sign);

            log.info("查询请求XML: {}", XmlUtils.toXml(queryParams));

            // 发送HTTP请求
            String reqUrl = swiftpassConfig.getReq_url();
            org.apache.http.client.methods.HttpPost httpPost =
                    new org.apache.http.client.methods.HttpPost(reqUrl);
            org.apache.http.entity.StringEntity entityParams =
                    new org.apache.http.entity.StringEntity(XmlUtils.parseXML(queryParams), "utf-8");
            httpPost.setEntity(entityParams);
            httpPost.setHeader("Content-Type", "text/xml;utf-8");

            org.apache.http.impl.client.CloseableHttpClient client =
                    org.apache.http.impl.client.HttpClients.createDefault();
            org.apache.http.client.methods.CloseableHttpResponse response = client.execute(httpPost);

            try {
                if (response != null && response.getEntity() != null) {
                    // 解析响应
                    Map<String, String> resultMap = XmlUtils.toMap(
                            org.apache.http.util.EntityUtils.toByteArray(response.getEntity()),
                            "utf-8");

                    log.info("查询响应结果: {}", resultMap);

                    // 验证签名
                    String reSign = resultMap.get("sign");
                    String reSignType = resultMap.get("sign_type");

                    if (resultMap.containsKey("sign")) {
                        boolean signValid = SignUtil.verifySign(reSign, reSignType, resultMap, swiftpassConfig);
                        if (!signValid) {
                            log.error("查询结果签名验证失败");
                            resultMap.put("status", "500");
                            resultMap.put("msg", "签名验证失败");
                            return resultMap;
                        }
                    }

                    // 检查通信状态和业务结果
                    if ("0".equals(resultMap.get("status")) &&
                            "0".equals(resultMap.get("result_code"))) {
                        resultMap.put("status", "200");
                        return resultMap;
                    } else {
                        log.error("查询失败: status={}, result_code={}, err_code={}, err_msg={}",
                                resultMap.get("status"), resultMap.get("result_code"),
                                resultMap.get("err_code"), resultMap.get("err_msg"));
                        resultMap.put("status", "500");
                        return resultMap;
                    }
                } else {
                    log.error("查询响应为空");
                    Map<String, String> errorResult = new HashMap<>();
                    errorResult.put("status", "500");
                    errorResult.put("msg", "查询响应为空");
                    return errorResult;
                }
            } finally {
                response.close();
                client.close();
            }

        } catch (Exception e) {
            log.error("调用威富通查询API异常", e);
            Map<String, String> errorResult = new HashMap<>();
            errorResult.put("status", "500");
            errorResult.put("msg", "系统异常: " + e.getMessage());
            return errorResult;
        }
    }

    /**
     * 同步订单支付状态
     * 当查询到订单已支付但本地状态未更新时，同步更新本地订单状态
     *
     * @param orderInfo   订单信息
     * @param queryResult 查询结果
     */
    @Transactional(rollbackFor = Exception.class)
    public void syncOrderStatus(UserOrderInfo orderInfo, Map<String, String> queryResult) {
        log.info("同步订单状态: orderNo={}", orderInfo.getOrderNo());

        try {
            // 提取支付信息
            String transactionId = queryResult.get("transaction_id");
            String totalFeeStr = queryResult.get("total_fee");
            String timeEnd = queryResult.get("time_end");

            // 查询档位信息验证金额
            RechargeLevel level = rechargeLevelMapper.selectById(orderInfo.getLevelId());
            if (level != null) {
                String expectedFee = amount_fee(level.getMoney());
                if (expectedFee.equals(totalFeeStr)) {
                    // 更新订单状态
                    orderInfo.setOrderStatus(SystemConstants.STATUS_TWO);
                    orderInfo.setTransactionId(transactionId);
                    orderInfo.setPayMoney(level.getMoney());
                    orderInfo.setOutTradeNo(transactionId);

                    // 解析支付时间
                    if (timeEnd != null && timeEnd.length() == 14) {
                        try {
                            java.time.format.DateTimeFormatter formatter =
                                    java.time.format.DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
                            orderInfo.setPayTime(java.time.LocalDateTime.parse(timeEnd, formatter));
                        } catch (Exception e) {
                            log.warn("解析支付时间失败: time_end={}", timeEnd, e);
                        }
                    }

                    int updateCount = userOrderInfoMapper.updateById(orderInfo);
                    if (updateCount > 0) {
                        log.info("订单状态同步成功: orderNo={}, transactionId={}",
                                orderInfo.getOrderNo(), transactionId);
                    } else {
                        log.error("订单状态同步失败: orderNo={}", orderInfo.getOrderNo());
                    }
                } else {
                    log.error("订单金额不匹配，不同步状态: expected={}, actual={}",
                            expectedFee, totalFeeStr);
                }
            }
        } catch (Exception e) {
            log.error("同步订单状态异常: orderNo={}", orderInfo.getOrderNo(), e);
            throw e;
        }
    }

    /**
     * 账户退款
     *
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public String refundOrder(Long userId, Integer type) throws Exception {

        //查询账户余额
        UserAccount userAccount =
                userAccountService.getOne(Wrappers.<UserAccount>lambdaQuery().eq(UserAccount::getUserId, userId).last("limit 1"));
        if (userAccount.getBalance().compareTo(BigDecimal.ZERO) == 0) {
            return "账户余额为 0";
        }
        BigDecimal refundMoney = userAccount.getBalance();

        //查询一年内已支付且可退款的所有券订单（已支付和部分退款状态）
        List<UserOrderInfo> userOrderInfoList = userOrderInfoMapper.selectList(Wrappers.<UserOrderInfo>lambdaQuery()
                .eq(UserOrderInfo::getUserId, userId)
                .in(UserOrderInfo::getOrderStatus, SystemConstants.STATUS_TWO, SystemConstants.STATUS_FIVE)
                .between(UserOrderInfo::getCreateTime, LocalDateTime.now().minusYears(1), LocalDateTime.now())
                .orderByAsc(UserOrderInfo::getCreateTime) // 按创建时间升序，优先退早期订单
        );

        if (CollUtil.isEmpty(userOrderInfoList)) {
            log.info("当前用户一年内未支付任何券订单,无法进行退款操作!");
            throw new BusinessException("无法进行退款操作,请联系客服处理！");
        }
        for (UserOrderInfo userOrderInfo : userOrderInfoList) {
            if (refundMoney.compareTo(BigDecimal.ZERO) == 0) {
                break;
            }
            // 处理退款金额为null的情况，默认为0
            BigDecimal alreadyRefundMoney = userOrderInfo.getRefundMoney() == null ? BigDecimal.ZERO : userOrderInfo.getRefundMoney();
            BigDecimal canRefundMoney = userOrderInfo.getOrderMoney().subtract(alreadyRefundMoney);

            if (canRefundMoney.compareTo(refundMoney) >= 0) {
                //可退款金额大于等于待退款金额，则直接退全部待退款金额
                refundOrder(userOrderInfo, refundMoney, "账户退款", type);

                //计算本次退款后的累计退款金额
                BigDecimal totalRefundMoney = alreadyRefundMoney.add(refundMoney);
                boolean isFullRefund = totalRefundMoney.compareTo(userOrderInfo.getOrderMoney()) >= 0;

                //账户变动及日志记录
                userAccountService.updateAccountBalanceAndLog(
                        userId,
                        refundMoney,
                        SystemConstants.CHANGE_TYPE_REDUCE,
                        SystemConstants.ACCOUNT_LOG_REFUND_NOTE,
                        userOrderInfo.getId()
                );

                //修改订单状态（判断是全额退款还是部分退款）
                if (isFullRefund) {
                    // 退款金额等于或大于订单金额，全额退款
                    userOrderInfo.setOrderStatus(SystemConstants.STATUS_FOUR);
                } else {
                    // 退款金额小于订单金额，部分退款
                    userOrderInfo.setOrderStatus(SystemConstants.STATUS_FIVE);
                }
                userOrderInfoMapper.updateById(userOrderInfo);
                refundMoney = BigDecimal.ZERO;
                break;
            }
            if (canRefundMoney.compareTo(refundMoney) < 0) {
                //退款金额小于订单金额，则先退订单金额
                refundOrder(userOrderInfo, canRefundMoney, "账户退款", type);
                //账户变动及日志记录（减少账户余额）
                userAccountService.updateAccountBalanceAndLog(
                        userId,
                        canRefundMoney,
                        SystemConstants.CHANGE_TYPE_REDUCE,
                        SystemConstants.ACCOUNT_LOG_REFUND_NOTE,
                        userOrderInfo.getId()
                );
                //修改订单状态（判断是全额退款还是部分退款）
                BigDecimal totalRefundMoney = alreadyRefundMoney.add(canRefundMoney);
                if (totalRefundMoney.compareTo(userOrderInfo.getOrderMoney()) >= 0) {
                    // 退款金额等于订单金额，全额退款
                    userOrderInfo.setOrderStatus(SystemConstants.STATUS_FOUR);
                } else {
                    // 退款金额小于订单金额，部分退款
                    userOrderInfo.setOrderStatus(SystemConstants.STATUS_FIVE);
                }
                userOrderInfoMapper.updateById(userOrderInfo);
                refundMoney = refundMoney.subtract(canRefundMoney);
            }
        }
        return "账户退款，预计3个工作日内分一笔或多笔退还！到期如未收到，请联系客服处理！";
    }

    public void refundOrder(UserOrderInfo userOrderInfo, BigDecimal refundAmount, String reason, Integer type) throws Exception {
        log.info("进入退款接口------>");
        log.info("执行操作的 原支付交易对应的商户订单号：{}", userOrderInfo.getOrderNo());

        //退款单号
        String out_refund_no = createOrderNo("TK", userOrderInfo.getId());
        // 创建退款订单
        UserRefundsOrderInfo userRefundsOrderInfo = new UserRefundsOrderInfo();
        userRefundsOrderInfo.setOrderId(userOrderInfo.getId());
        userRefundsOrderInfo.setOrderNo(userOrderInfo.getOrderNo());
        userRefundsOrderInfo.setUserId(userOrderInfo.getUserId());
        userRefundsOrderInfo.setOutRefundNo(out_refund_no);
        userRefundsOrderInfo.setReason(reason);
        userRefundsOrderInfo.setAmount(refundAmount);
        userRefundsOrderInfo.setType(type);
        userRefundsOrderInfo.setCreateTime(LocalDateTime.now());

        SortedMap<String, String> params = new TreeMap<>();

        params.put("out_trade_no", userOrderInfo.getOrderNo());//商户订单号
        params.put("out_refund_no", out_refund_no);//商户退款单号
        params.put("attach", reason);//退款原因
        params.put("total_fee", amount_fee(userOrderInfo.getOrderMoney()));//原订单金额
        params.put("refund_fee", amount_fee(refundAmount));//退款金额
        params.put("sign_type", "RSA_1_256");
        PayUtill payUtill = new PayUtill();

        Map<String, String> refund = payUtill.refund(params, swiftpassConfig);

        log.info("最终拿到的微信支付通知数据：" + refund);
        if (Objects.equals(refund.get("status"), "0")) {

            log.info("退款调用成功！");
            if (Objects.equals(refund.get("result_code"), "0")) {
                log.info("退款成功！");
                log.info("订单：{},退款成功！原因：{}", userOrderInfo.getOrderNo(), reason);
                //计算累计退款金额
                BigDecimal currentRefundMoney = userOrderInfo.getRefundMoney() == null ? BigDecimal.ZERO : userOrderInfo.getRefundMoney();
                BigDecimal totalRefundMoney = currentRefundMoney.add(refundAmount);

                //修改订单状态（判断是全额退款还是部分退款）
                if (totalRefundMoney.compareTo(userOrderInfo.getOrderMoney()) >= 0) {
                    // 退款金额等于或大于订单金额，全额退款
                    userOrderInfo.setOrderStatus(SystemConstants.STATUS_FOUR);
                } else {
                    // 退款金额小于订单金额，部分退款
                    userOrderInfo.setOrderStatus(SystemConstants.STATUS_FIVE);
                }
                userOrderInfo.setRefundMoney(totalRefundMoney);
                userOrderInfo.setRefundTime(LocalDateTime.now());
                userOrderInfoMapper.updateById(userOrderInfo);
            } else {
                log.info("退款处理中");
                //修改订单状态
                BigDecimal currentRefundMoney = userOrderInfo.getRefundMoney() == null ? BigDecimal.ZERO : userOrderInfo.getRefundMoney();
                userOrderInfo.setRefundMoney(currentRefundMoney.add(refundAmount));
                userOrderInfoMapper.updateById(userOrderInfo);
            }
            //退款信息补充
            userRefundsOrderInfo.setRefundId(refund.get("refund_id"));
            userRefundsOrderInfo.setNotifyRequest(refund.toString());
            userRefundsOrderInfo.setTransactionId(userOrderInfo.getTransactionId());
            userRefundsOrderInfo.setAcceptedTime(LocalDateTime.now());
            userRefundsOrderInfoMapper.insert(userRefundsOrderInfo);
        }

    }

    /**
     * 退款查询
     * <p>
     * 应用场景：
     * 1. 提交退款申请后，通过调用该接口查询退款状态
     * 2. 退款有一定延时，请在3个工作日后重新查询退款状态
     * <p>
     * 参数优先级：
     * refund_id > out_refund_no > transaction_id > out_trade_no
     * <p>
     * 退款状态：
     * - SUCCESS：退款成功
     * - FAIL：退款失败
     * - PROCESSING：退款处理中
     * - CHANGE：转入代发，退款到银行发现用户的卡作废或者冻结了，
     * 导致原路退款银行卡失败，资金回流到商户的现金帐号，
     * 需要商户人工干预，通过线下或者平台转账的方式进行退款
     *
     * @param outTradeNo    商户订单号（四选一）
     * @param transactionId 平台订单号（四选一）
     * @param outRefundNo   商户退款单号（四选一）
     * @param refundId      平台退款单号（四选一，优先级最高）
     * @return 退款查询结果
     */
    public Map<String, Object> queryRefund(String outTradeNo, String transactionId,
                                           String outRefundNo, String refundId) {
        log.info("========== 开始查询退款状态 ==========");
        log.info("查询参数: outTradeNo={}, transactionId={}, outRefundNo={}, refundId={}",
                outTradeNo, transactionId, outRefundNo, refundId);

        try {
            // 1. 参数校验 - 四个参数至少需要一个
            if (outTradeNo == null && transactionId == null &&
                    outRefundNo == null && refundId == null) {
                log.error("退款查询参数不能全为空");
                Map<String, Object> errorResult = new HashMap<>();
                errorResult.put("status", "500");
                errorResult.put("msg", "查询参数不能全为空，请提供 outTradeNo/transactionId/outRefundNo/refundId 中的任意一个");
                return errorResult;
            }

            // 2. 构建查询请求参数
            SortedMap<String, String> queryParams = new TreeMap<>();

            // 按优先级添加参数：refund_id > out_refund_no > transaction_id > out_trade_no
            if (refundId != null && !refundId.trim().isEmpty()) {
                queryParams.put("refund_id", refundId);
            } else if (outRefundNo != null && !outRefundNo.trim().isEmpty()) {
                queryParams.put("out_refund_no", outRefundNo);
            } else if (transactionId != null && !transactionId.trim().isEmpty()) {
                queryParams.put("transaction_id", transactionId);
            } else if (outTradeNo != null && !outTradeNo.trim().isEmpty()) {
                queryParams.put("out_trade_no", outTradeNo);
            }

            queryParams.put("sign_type", "RSA_1_256"); // 签名方式

            // 3. 调用威富通退款查询API
            PayUtill payUtill = new PayUtill();
            Map<String, Object> queryResult = payUtill.refundQuery(queryParams, swiftpassConfig);

            log.info("威富通退款查询返回结果: {}", queryResult);

            // 4. 解析查询结果
            if ("200".equals(queryResult.get("status"))) {
                @SuppressWarnings("unchecked")
                Map<String, String> dataMap = (Map<String, String>) queryResult.get("data");

                if (dataMap == null) {
                    log.error("退款查询结果数据为空");
                    queryResult.put("status", "500");
                    queryResult.put("msg", "查询结果数据为空");
                    return queryResult;
                }

                // 5. 检查业务结果
                String status = dataMap.get("status");
                String resultCode = dataMap.get("result_code");

                if (!"0".equals(status) || !"0".equals(resultCode)) {
                    log.error("退款查询失败: status={}, result_code={}, err_code={}, err_msg={}",
                            status, resultCode, dataMap.get("err_code"), dataMap.get("err_msg"));
                    queryResult.put("status", "500");
                    queryResult.put("msg", dataMap.get("err_msg"));
                    return queryResult;
                }

                // 6. 解析退款记录信息
                Integer refundCount = Integer.parseInt(dataMap.getOrDefault("refund_count", "0"));
                log.info("退款笔数: {}", refundCount);

                // 7. 构造返回结果
                Map<String, Object> result = new HashMap<>();
                result.put("status", "200");
                result.put("mch_id", dataMap.get("mch_id"));
                result.put("trade_type", dataMap.get("trade_type"));
                result.put("out_transaction_id", dataMap.get("out_transaction_id"));
                result.put("transaction_id", dataMap.get("transaction_id"));
                result.put("out_trade_no", dataMap.get("out_trade_no"));
                result.put("refund_count", refundCount);

                // 8. 解析退款记录列表（支持多笔退款）
                if (refundCount > 0) {
                    java.util.List<Map<String, Object>> refundList = new java.util.ArrayList<>();

                    for (int i = 0; i < refundCount; i++) {
                        Map<String, Object> refundRecord = new HashMap<>();
                        String suffix = "_" + i;

                        // 提取每笔退款的详细信息
                        refundRecord.put("out_refund_id", dataMap.get("out_refund_id" + suffix));
                        refundRecord.put("out_refund_no", dataMap.get("out_refund_no" + suffix));
                        refundRecord.put("refund_id", dataMap.get("refund_id" + suffix));
                        refundRecord.put("refund_channel", dataMap.get("refund_channel" + suffix));
                        refundRecord.put("refund_fee", dataMap.get("refund_fee" + suffix));
                        refundRecord.put("coupon_refund_fee", dataMap.get("coupon_refund_fee" + suffix));
                        refundRecord.put("refund_time", dataMap.get("refund_time" + suffix));
                        refundRecord.put("refund_status", dataMap.get("refund_status" + suffix));
                        refundRecord.put("refund_status_info", dataMap.get("refund_status_info" + suffix));

                        refundList.add(refundRecord);

                        log.info("退款记录[{}]: refund_id={}, refund_status={}, refund_fee={}",
                                i, refundRecord.get("refund_id"),
                                refundRecord.get("refund_status"),
                                refundRecord.get("refund_fee"));
                    }

                    result.put("refund_list", refundList);
                }

                log.info("退款查询成功");
                return result;
            } else {
                log.error("退款查询调用失败: {}", queryResult);
                return queryResult;
            }

        } catch (Exception e) {
            log.error("查询退款状态异常", e);
            Map<String, Object> errorResult = new HashMap<>();
            errorResult.put("status", "500");
            errorResult.put("msg", "系统异常: " + e.getMessage());
            return errorResult;
        } finally {
            log.info("========== 退款状态查询完成 ==========");
        }
    }

    public static void main(String[] args) throws IOException {
        SortedMap<String, String> params = new TreeMap<>();
        SwiftpassConfig swiftpassConfig = new SwiftpassConfig();
        params.put("transaction_id", "2301202601052012511795");//商户订单号
        params.put("out_refund_no", "TK2301202601052012511795");//商户退款单号
        params.put("attach", "");//退款原因
        params.put("total_fee", "3000");//原订单金额
        params.put("refund_fee", "2970");//退款金额
        params.put("sign_type", "RSA_1_256");
        PayUtill payUtill = new PayUtill();
        swiftpassConfig.setKey("f5131b3f07acb965a59041b690a29911");
        swiftpassConfig.setMchPrivateKey("MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDeFB5G2OYT762PpUytCw7Du40i6WnzcmbvEE9IXPXi+QirPwMvW9mBqNDIUk5hQS3ZnHjj80YQRWG6yksjE6kHAYIWahCDiaPlBqYvYSJ8ePzbT61THZJbzqFaIG3svW7xq9nsUmzVBub0ATIzC1DQRu9ZTdrj/iuMUEhJyJ8IHrTP09eTwNYdoagHQlKWRVoNE3LuU4GXG3VCbkQ2ixbMo8dXBisDIi3GYOSFWzota6H+OCp9Mta1jTqdwALKAU9PNlRkQwOMLk2OmMqGUhImVVpl+eGrIYn3iARce0alNFg8hghFMJ8MKpSxJDM6YHNOJQ06S25YYhTpd+C2/VOBAgMBAAECggEBAM/W9ksJ/bJU0xOn+W3N9oB7C+jLmMwtmmZM1lZ8IefNeC6Ep59wD81ISDXiydY9YQLTbVSxPjZGKOPfJZjrcnrLD4uYsmHYtFnI8klPWC40MTmzhRxPhcWESgAGb7prw+RMGIUS0yY/8nAUmn2pLnXunVzv/1b3bpxAGpdrOmMmU28GBt9AlXiIpVmnxnkhp66c4zFj5gvvVoDrz9m/6Acyn6n7yccCHD2iYw0D78GPItEWky38tH/FV0lRcCCYAf5fc2nFnicrdgj1RYjqTWxM7A92UecviTAbiuPO6CQQl7+sMtGU2d6UeKj0Xrrl2gly+lOS97P/NcLtZf5vklECgYEA8SMlCg5AToSkIwal7dXYgM2VlNFwSRDuO3hEVoWe7bM/LkEp8dqSpV025ZtngTY/qziXsGP/7l8bcS1th19cX/+/MFFOWsoxtqvOam2Elp+Qg1johEfnWI+Bo4WiQ5CHYNQRN3cuiWTc5HHuI0KQAEPx/aYogD057X2FIsiu6S0CgYEA68RAFsupZ6R8BhJbfY2CK07XLNvXu5DAYBmU3trmQFnaxXeQFfhQ8hi9m5Awu14YCnRmHzc8+QXFD/GqTAbxtImc6AZQKWdLuUntkitPWmJK6dtJC8Is3U9Yqz5+CkSmgZSfqW0DvEt7jagoNfpKgy29Qq4r35b6JsDXtnTQICUCgYEAjmwnkEzihn2pRFbE4jiP62OBmagqHb22N8HM+x1oxRQ9mOA8GfDy9GCd7/ddpt+Xs1V1omUt4GikGLCwJGiacsjm727WTKFnw3CuNgYBbcVI4Ys9qgOeDJyWATMIp8dRbktS7+OgxN2h6fuwn3rM+psm7p2ZBkUjVbXxUJ4fUPECgYEAw1wmAv2VjRUF0/4oI5w7bWlx8XDljT1/uuHXsuZN/qq2FgRht2LAqCsKCjprtwZcA2W6LUmXU32Ncg29ICxs4j1ZcAWzLOu0GoAAxKrwoSNrkeYr2/t1M5kJDzTEOfvywNMHjduQSdl+Mr5RO5D/Zz1iYztxjV9MPwpydHTM9KUCgYAHuT98NkBilMxQNNmUB13E10MYQvZuiGVFZtT3up69Elpmtm7Z5cEW7QNG0g1LPPfkzfWPsq+6I98FmozLickqvjntdpul4czTITn8SNHqoxvdbcVnDipF1KwlHcnXhjO1KjSZg3a/iv554OR3/rbD9SWDzDAT7Zy6zX9n8OwGRA==");
        swiftpassConfig.setPlatPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2HOacYJOO9zsWPVmauV/YCeR78RsRDtusdLEngi/JkPkZVSE0X47z2RpJncGyV1QfdHv0udVEND4bvjXku4qUJp5DYAulm6pDXdcwWPcdI77V7dqoDvYm9Cc8kGj9s+/0xeuxX4qJmwzFTf7XjRfTT7+OVSvFnnButAkgMuD3cW1rtcQYeY9S9puQneN1i1+Lek5GCpW5PFsezK6QMgrpB1TFVSF5tloUODfc4fBDY5quGxn29Fo9gzJXO8ehoRft/JEaS4rNqmlfbvaJfEROXALlKoUX8Iki050ss7WwIBS6xuV08JnHTUHzHmAzOscwyYmT3RZChPgluWuyYW30wIDAQAB");
        swiftpassConfig.setMch_id("105520131602");
        swiftpassConfig.setAppid("wx9894a01b9e92c368");
        swiftpassConfig.setSecret("b1e83dbcf83af310c38c0a138739ddcf");
        swiftpassConfig.setReq_url("https://eoap.cebbank.com/uiap/bcac/pay/pay/gateway");
        swiftpassConfig.setNotify_url("https://4ad6a4a6.r28.cpolar.top/applet/v1/wft/order/notify");
        Map<String, String> refund = payUtill.refund(params, swiftpassConfig);

        log.info("最终拿到的微信支付通知数据：" + refund);
        if (Objects.equals(refund.get("status"), "0")) {

            log.info("退款调用成功！");
            if (Objects.equals(refund.get("result_code"), "0")) {
                log.info("退款成功！");
                log.info("订单：{},退款成功！原因：{}");

        }
    }
}
}
