From 6539b325b5ce95d1fafa864c75a32279c954167f Mon Sep 17 00:00:00 2001
From: KKSU <15274802129@163.com>
Date: Fri, 07 Feb 2025 11:03:31 +0800
Subject: [PATCH] refactor(mall): 重构订单退款流程

---
 src/main/java/cc/mrbird/febs/pay/util/FiuuUtil.java                              |   24 +--
 src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallTeamLeaderServiceImpl.java |   67 +---------
 src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java  |   25 +--
 src/main/java/cc/mrbird/febs/mall/quartz/ProfitJob.java                          |  116 +++++++++++++++++++
 src/main/java/cc/mrbird/febs/pay/controller/FIUUController.java                  |    2 
 src/main/java/cc/mrbird/febs/pay/util/FiuuRefundUtil.java                        |   83 +++++++++++++
 src/main/java/cc/mrbird/febs/mall/entity/MallRefundEntity.java                   |    2 
 src/main/java/cc/mrbird/febs/pay/model/RefundStatus.java                         |   13 ++
 src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java               |    2 
 src/main/java/cc/mrbird/febs/pay/util/HashUtils.java                             |   18 +++
 10 files changed, 260 insertions(+), 92 deletions(-)

diff --git a/src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java b/src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java
index 96ce4ef..90674f2 100644
--- a/src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java
+++ b/src/main/java/cc/mrbird/febs/common/configure/WebMvcConfigure.java
@@ -33,7 +33,7 @@
         registration.excludePathPatterns("/api/xcxPay/wxpayCallback");
         registration.excludePathPatterns("/api/xcxPay/rechargeCallBack");
         registration.excludePathPatterns("/api/xcxPay/fapiaoCallBack");
-//        registration.excludePathPatterns("/api/fuPay/callback");
+        registration.excludePathPatterns("/api/fuPay/callback");
         registration.excludePathPatterns("/api/fuPay/notify");
 
         // 添加Swagger UI相关路径
diff --git a/src/main/java/cc/mrbird/febs/mall/entity/MallRefundEntity.java b/src/main/java/cc/mrbird/febs/mall/entity/MallRefundEntity.java
index dae67f7..7858ec4 100644
--- a/src/main/java/cc/mrbird/febs/mall/entity/MallRefundEntity.java
+++ b/src/main/java/cc/mrbird/febs/mall/entity/MallRefundEntity.java
@@ -21,7 +21,7 @@
     private Long orderId;
     //退款订单详情ID
     private Long itemId;
-    //退款方式 1:微信 2:支付宝 3:其他
+    //退款方式 1:FIUU 2:支付宝 3:其他
     private Integer type;
     //退款状态 1:成功 2:失败 3:退款中
     private Integer state;
diff --git a/src/main/java/cc/mrbird/febs/mall/quartz/ProfitJob.java b/src/main/java/cc/mrbird/febs/mall/quartz/ProfitJob.java
index 0ca11c7..eb3e796 100644
--- a/src/main/java/cc/mrbird/febs/mall/quartz/ProfitJob.java
+++ b/src/main/java/cc/mrbird/febs/mall/quartz/ProfitJob.java
@@ -1,8 +1,13 @@
 package cc.mrbird.febs.mall.quartz;
 
+import cc.mrbird.febs.common.enumerates.FlowTypeEnum;
+import cc.mrbird.febs.common.enumerates.MoneyFlowTypeEnum;
 import cc.mrbird.febs.common.enumerates.YesOrNoOrIngEnum;
-import cc.mrbird.febs.mall.entity.MallActivity;
-import cc.mrbird.febs.mall.mapper.MallActivityMapper;
+import cc.mrbird.febs.mall.entity.*;
+import cc.mrbird.febs.mall.mapper.*;
+import cc.mrbird.febs.mall.service.IMallMoneyFlowService;
+import cc.mrbird.febs.pay.model.RefundStatus;
+import cc.mrbird.febs.pay.util.FiuuRefundUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
@@ -26,6 +31,27 @@
 
     @Autowired
     private MallActivityMapper mallActivityMapper;
+
+    @Autowired
+    private MallRefundMapper mallRefundMapper;
+
+    @Autowired
+    private MallOrderInfoMapper mallOrderInfoMapper;
+
+    @Autowired
+    private MallOrderItemMapper mallOrderItemMapper;
+
+    @Autowired
+    private MallGoodsSkuMapper mallGoodsSkuMapper;
+
+    @Autowired
+    private MallGoodsMapper mallGoodsMapper;
+
+    @Autowired
+    private FiuuRefundUtil fiuuRefundUtil;
+
+    @Autowired
+    private IMallMoneyFlowService mallMoneyFlowService;
 
     /**
      * 一分钟运行一次
@@ -74,4 +100,90 @@
         });
     }
 
+
+
+    /**
+     * 一分钟运行一次
+     *      查询退款记录,去验证是否已经退款成功
+     */
+    @Scheduled(cron = "0 0/1 * * * ? ")
+    public void refundJob() {
+        LambdaQueryWrapper<MallRefundEntity> mallOrderRefundLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        mallOrderRefundLambdaQueryWrapper.eq(MallRefundEntity::getStatus, 3);
+        mallOrderRefundLambdaQueryWrapper.eq(MallRefundEntity::getType, 1);
+        List<MallRefundEntity> mallRefundEntities = mallRefundMapper.selectList(mallOrderRefundLambdaQueryWrapper);
+        if(CollUtil.isEmpty(mallRefundEntities)){
+            return;
+        }
+        mallRefundEntities.forEach(mallRefundEntity -> {
+            processRefund(mallRefundEntity);
+        });
+    }
+
+    private void processRefund(MallRefundEntity mallRefundEntity) {
+        try {
+            MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectById(mallRefundEntity.getOrderId());
+            MallOrderItem mallOrderItem = mallOrderItemMapper.selectById(mallRefundEntity.getItemId());
+            MallGoodsSku mallGoodsSku = mallGoodsSkuMapper.selectById(mallOrderItem.getSkuId());
+
+            String txnId = mallOrderInfo.getPayOrderNo();
+            RefundStatus status = fiuuRefundUtil.pollRefundStatus(txnId);
+
+            switch (status.getStatus()) {
+                case "success":
+                    updateOnSuccess(mallRefundEntity, mallOrderInfo, mallOrderItem, mallGoodsSku);
+                    break;
+                case "rejected":
+                    updateOnRejected(mallRefundEntity, mallOrderItem);
+                    break;
+                default:
+                    log.warn("未知状态:{}", status.getStatus());
+            }
+        } catch (Exception e) {
+            log.error("处理退款失败: {}", e.getMessage(), e);
+        }
+    }
+
+    private void updateOnSuccess(MallRefundEntity mallRefundEntity, MallOrderInfo mallOrderInfo, MallOrderItem mallOrderItem, MallGoodsSku mallGoodsSku) {
+        mallOrderItem.setState(3);
+        mallOrderItemMapper.updateById(mallOrderItem);
+
+        MallGoods mallGoods = mallGoodsMapper.selectById(mallOrderItem.getGoodsId());
+        mallGoods.setStock(mallGoods.getStock() + mallOrderItem.getCnt());
+        mallGoods.setVolume(mallGoods.getVolume() - mallOrderItem.getCnt());
+        mallGoodsMapper.updateById(mallGoods);
+
+        mallGoodsSku.setStock(mallGoodsSku.getStock() + mallOrderItem.getCnt());
+        mallGoodsSku.setSkuVolume(mallGoodsSku.getSkuVolume() - mallOrderItem.getCnt());
+        mallGoodsSkuMapper.updateById(mallGoodsSku);
+
+        mallRefundEntity.setState(1);
+        mallRefundEntity.setUpdatedTime(DateUtil.date());
+        mallRefundMapper.updateById(mallRefundEntity);
+
+        mallMoneyFlowService.addMoneyFlow(
+                mallOrderInfo.getMemberId(),
+                mallRefundEntity.getAmount(),
+                MoneyFlowTypeEnum.WECHAT_REFUND.getValue(),
+                mallOrderInfo.getOrderNo(),
+                FlowTypeEnum.WECHAT.getValue(),
+                "FIUU退款",
+                2);
+
+        List<MallOrderItem> mallOrderItemList = mallOrderItemMapper.selectListByNotInStateAndOrderId(3, mallRefundEntity.getOrderId());
+        if (CollUtil.isEmpty(mallOrderItemList)) {
+            MallOrderInfo mallOrderRefund = mallOrderInfoMapper.selectById(mallRefundEntity.getOrderId());
+            mallOrderRefund.setStatus(6);
+            mallOrderInfoMapper.updateById(mallOrderRefund);
+        }
+    }
+
+    private void updateOnRejected(MallRefundEntity mallRefundEntity, MallOrderItem mallOrderItem) {
+        mallOrderItem.setState(1);
+        mallOrderItemMapper.updateById(mallOrderItem);
+
+        mallRefundEntity.setState(2);
+        mallRefundMapper.updateById(mallRefundEntity);
+    }
+
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java
index 534d61d..c1e9602 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java
@@ -900,23 +900,16 @@
     @Transactional
     public FebsResponse refundOrder(Long id) {
         MallMember member = LoginUserUtil.getLoginUser();
-        MallOrderInfo mallOrderInfo = this.baseMapper.selectById(id);
-        if(ObjectUtil.isEmpty(mallOrderInfo)){
-            return new FebsResponse().fail().message("订单不存在");
-        }
+        MallOrderInfo mallOrderInfo = ValidateEntityUtils
+                .ensureColumnReturnEntity(id, MallOrderInfo::getId, this.baseMapper::selectOne, "订单不存在");
         Integer status = mallOrderInfo.getStatus();
-        if(OrderStatusEnum.WAIT_SHIPPING.getValue() != status){
-            return new FebsResponse().fail().message("订单不是待发货状态");
-        }
         Integer deliveryState = mallOrderInfo.getDeliveryState();
-        if(1 != deliveryState){
-            return new FebsResponse().fail().message("订单不是待配送状态");
-        }
+
+        ValidateEntityUtils.ensureEqual(OrderStatusEnum.WAIT_SHIPPING.getValue(),status,"订单不是待发货状态");
+        ValidateEntityUtils.ensureEqual(1,deliveryState,"订单不是待配送状态");
         //根据子订单生成退款记录
-        List<MallOrderItem> mallOrderItemList = mallOrderItemMapper.selectListByOrderId(id);
-        if(CollUtil.isEmpty(mallOrderItemList)){
-            return new FebsResponse().fail().message("订单不存在");
-        }
+        List<MallOrderItem> mallOrderItemList = ValidateEntityUtils
+                .ensureColumnReturnEntityList(id, MallOrderItem::getOrderId, mallOrderItemMapper::selectList, "订单不存在");
         for(MallOrderItem mallOrderItem : mallOrderItemList){
             QueryWrapper<MallRefundEntity> objectQueryWrapper = new QueryWrapper<>();
             objectQueryWrapper.eq("member_id",member.getId());
@@ -940,9 +933,7 @@
                 mallRefundEntity.setAmount(mallOrderItem.getAmount());
                 mallRefundMapper.insert(mallRefundEntity);
             }else{
-                if(mallRefund.getState() == 1){
-                    return new FebsResponse().fail().message("订单已退款");
-                }
+                ValidateEntityUtils.ensureNotEqual(1,mallRefund.getState(),"订单已退款");
                 if(mallRefund.getState() == 2 || mallRefund.getState() == 3){
                     mallRefundEntity.setId(mallRefund.getId());
                     mallRefundEntity.setRefundNo(mallRefund.getRefundNo());
diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallTeamLeaderServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallTeamLeaderServiceImpl.java
index d1257d8..c4ce447 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallTeamLeaderServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallTeamLeaderServiceImpl.java
@@ -5,6 +5,7 @@
 import cc.mrbird.febs.common.properties.XcxProperties;
 import cc.mrbird.febs.common.utils.LoginUserUtil;
 import cc.mrbird.febs.common.utils.SpringContextHolder;
+import cc.mrbird.febs.common.utils.ValidateEntityUtils;
 import cc.mrbird.febs.mall.conversion.MallLeaderAchieveConversion;
 import cc.mrbird.febs.mall.conversion.MallOrderInfoConversion;
 import cc.mrbird.febs.mall.conversion.MallTeamLeaderConversion;
@@ -395,13 +396,12 @@
         if(!(1 == agreeType || 2 == agreeType)){
             return new FebsResponse().fail().message("退款失败,请联系客服人员");
         }
-
-        MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectById(orderId);
-        MallOrderItem mallOrderItem = mallOrderItemMapper.selectById(itemId);
-        MallGoodsSku mallGoodsSku = mallGoodsSkuMapper.selectById(mallOrderItem.getSkuId());
-        if(ObjectUtil.isEmpty(mallGoodsSku)){
-            return new FebsResponse().fail().message("退款失败,请联系客服人员");
-        }
+        MallOrderInfo mallOrderInfo = ValidateEntityUtils
+                .ensureColumnReturnEntity(orderId, MallOrderInfo::getId, mallOrderInfoMapper::selectOne, "订单不存在");
+        MallOrderItem mallOrderItem = ValidateEntityUtils
+                .ensureColumnReturnEntity(itemId, MallOrderItem::getId, mallOrderItemMapper::selectOne, "订单不存在");
+        MallGoodsSku mallGoodsSku = ValidateEntityUtils
+                .ensureColumnReturnEntity(mallOrderItem.getSkuId(), MallGoodsSku::getId, mallGoodsSkuMapper::selectOne, "订单不存在,退款失败,请联系客服人员");
         List<MallRefundEntity> mallRefundEntities = mallRefundMapper.selectByItemIdAndOrderIdAndState(itemId, orderId, 3);
         if(CollUtil.isEmpty(mallRefundEntities)){
             return new FebsResponse().fail().message("退款失败,请联系客服人员");
@@ -453,7 +453,6 @@
                     }
                 }
             }
-//            refundAmount = refundAmount.add(mallOrderInfo.getCarriage());
             BigDecimal bb = new BigDecimal(100);
             int refundMoney = refundAmount.multiply(bb).intValue();
 
@@ -486,55 +485,9 @@
                 return new FebsResponse().success().message("退款成功");
             }
 
-            Boolean flag = false;
-            Boolean debug = xcxProperties.getDebug();
-            if (debug) {
-                boolean b = fiuuUtil.comRefund(mallOrderInfo.getPayOrderNo(), refundNo, "1");
-                flag = b;
-            } else {
-                log.info("开始调用退款接口。。。退款编号为{}", refundNo);
-                boolean b = fiuuUtil.comRefund(mallOrderInfo.getPayOrderNo(), refundNo, orderAmount.toString());
-                flag = b;
-            }
-
-            if(flag){
-                //更新订单详情
-                mallOrderItem.setState(3);
-                mallOrderItemMapper.updateById(mallOrderItem);
-                //更新库存信息
-                MallGoods mallGoods = mallGoodsMapper.selectById(mallOrderItem.getGoodsId());
-                mallGoods.setStock(mallGoods.getStock() + mallOrderItem.getCnt());
-                mallGoods.setVolume(mallGoods.getVolume() - mallOrderItem.getCnt());
-                mallGoodsMapper.updateById(mallGoods);
-
-//                MallGoodsSku mallGoodsSku = mallGoodsSkuMapper.selectById(mallOrderItem.getSkuId());
-                mallGoodsSku.setStock(mallGoodsSku.getStock() + mallOrderItem.getCnt());
-                mallGoodsSku.setSkuVolume(mallGoodsSku.getSkuVolume() - mallOrderItem.getCnt());
-                mallGoodsSkuMapper.updateById(mallGoodsSku);
-
-                //更新退款订单
-                mallRefundEntity.setState(1);
-                mallRefundEntity.setUpdatedTime(DateUtil.date());
-                mallRefundMapper.updateById(mallRefundEntity);
-                mallMoneyFlowService.addMoneyFlow(mallOrderInfo.getMemberId(), refundAmount, MoneyFlowTypeEnum.WECHAT_REFUND.getValue(), mallOrderInfo.getOrderNo(), FlowTypeEnum.WECHAT.getValue(),"微信退款",2);
-
-                List<MallOrderItem> mallOrderItemList = mallOrderItemMapper.selectListByNotInStateAndOrderId(3,orderId);
-                if(CollUtil.isEmpty(mallOrderItemList)){
-                    MallOrderInfo mallOrderRefund = mallOrderInfoMapper.selectById(orderId);
-                    mallOrderRefund.setStatus(6);
-                    mallOrderInfoMapper.updateById(mallOrderRefund);
-                }
-            }else{
-
-                //更新订单详情
-                mallOrderItem.setState(1);
-                mallOrderItemMapper.updateById(mallOrderItem);
-
-                mallRefundEntity.setState(2);
-                mallRefundMapper.updateById(mallRefundEntity);
-                return new FebsResponse().fail().message("退款失败,请联系客服人员");
-            }
-            return new FebsResponse().success().message("退款成功");
+            log.info("开始调用退款接口。。。退款编号为{}", refundNo);
+            fiuuUtil.comRefund(mallOrderInfo.getPayOrderNo(), refundNo, orderAmount.toString());
+            return new FebsResponse().success().message("已申请退款");
         }
     }
 
diff --git a/src/main/java/cc/mrbird/febs/pay/controller/FIUUController.java b/src/main/java/cc/mrbird/febs/pay/controller/FIUUController.java
index e419e3e..59620cb 100644
--- a/src/main/java/cc/mrbird/febs/pay/controller/FIUUController.java
+++ b/src/main/java/cc/mrbird/febs/pay/controller/FIUUController.java
@@ -64,7 +64,7 @@
             params.put("bill_desc", productNames);
             params.put("currency", "MYR"); // 默认 MYR
             params.put("vcode", vcode);
-//            params.put("returnurl", returnUrl);
+            params.put("returnurl", returnUrl);
 
             return new FebsResponse().success().data(params);
         } catch (Exception e) {
diff --git a/src/main/java/cc/mrbird/febs/pay/model/RefundStatus.java b/src/main/java/cc/mrbird/febs/pay/model/RefundStatus.java
new file mode 100644
index 0000000..0e59e32
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/pay/model/RefundStatus.java
@@ -0,0 +1,13 @@
+package cc.mrbird.febs.pay.model;
+
+import lombok.Data;
+
+@Data
+public class RefundStatus {
+    private String TxnID;
+    private String RefID;
+    private String RefundID;
+    private String Status;
+    private String LastUpdate;
+    private String FPXTxnID;
+}
diff --git a/src/main/java/cc/mrbird/febs/pay/util/FiuuRefundUtil.java b/src/main/java/cc/mrbird/febs/pay/util/FiuuRefundUtil.java
new file mode 100644
index 0000000..6071945
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/pay/util/FiuuRefundUtil.java
@@ -0,0 +1,83 @@
+package cc.mrbird.febs.pay.util;
+
+import cc.mrbird.febs.pay.model.RefundStatus;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.http.client.methods.HttpGet;
+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 java.util.concurrent.*;
+
+@Service(value="FiuuRefundUtil")
+public class FiuuRefundUtil {
+
+    private static final String API_BASE_URL = "https://api.fiuu.com/RMS/API/refundAPI/";
+    private static final String MERCHANT_ID = "e2umart01";
+    private static final String VERIFY_KEY = "4e3a4ed58e62ddbfacf41f6d5ec56bf2";
+    private static final int MAX_RETRIES = 3;
+    private static final int POLL_INTERVAL = 1000; // 5秒
+    private static final int TIMEOUT = 60000; // 60秒超时
+
+    private final ObjectMapper objectMapper = new ObjectMapper();
+
+    // 退款状态查询(根据TxnID)
+    public RefundStatus queryByTxnId(String txnId) throws Exception {
+        String signature = HashUtils.md5(txnId + MERCHANT_ID + VERIFY_KEY);
+        String url = API_BASE_URL + "q_by_txn.php?TxnID=" + txnId
+                + "&MerchantID=" + MERCHANT_ID
+                + "&Signature=" + signature;
+
+        return executeQuery(url);
+    }
+
+    // 退款状态查询(根据RefID)
+    public RefundStatus queryByRefId(String refId) throws Exception {
+        String signature = HashUtils.md5(refId + MERCHANT_ID + VERIFY_KEY);
+        String url = API_BASE_URL + "q_by_refID.php?RefID=" + refId
+                + "&MerchantID=" + MERCHANT_ID
+                + "&Signature=" + signature;
+
+        return executeQuery(url);
+    }
+
+    private RefundStatus executeQuery(String url) throws Exception {
+        HttpGet request = new HttpGet(url);
+        try (CloseableHttpClient client = HttpClients.createDefault()) {
+            String response = EntityUtils.toString(client.execute(request).getEntity());
+            return objectMapper.readValue(response, RefundStatus.class);
+        }
+    }
+
+    // 异步轮询退款状态
+    public RefundStatus pollRefundStatus(String txnId) throws Exception {
+        ExecutorService executor = Executors.newSingleThreadExecutor();
+        Future<RefundStatus> future = executor.submit(() -> {
+            int retryCount = 0;
+            while (retryCount < MAX_RETRIES) {
+                try {
+                    RefundStatus status = queryByTxnId(txnId);
+                    if (!"pending".equals(status.getStatus())) {
+                        return status;
+                    }
+                    Thread.sleep(POLL_INTERVAL);
+                    retryCount++;
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                    throw new RuntimeException("Polling interrupted", e);
+                }
+            }
+            throw new TimeoutException("Max retries reached");
+        });
+
+        try {
+            return future.get(TIMEOUT, TimeUnit.MILLISECONDS);
+        } catch (TimeoutException e) {
+            future.cancel(true);
+            throw new RuntimeException("Refund status check timeout");
+        } finally {
+            executor.shutdown();
+        }
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/pay/util/FiuuUtil.java b/src/main/java/cc/mrbird/febs/pay/util/FiuuUtil.java
index 9b96b62..b7c1ede 100644
--- a/src/main/java/cc/mrbird/febs/pay/util/FiuuUtil.java
+++ b/src/main/java/cc/mrbird/febs/pay/util/FiuuUtil.java
@@ -1,7 +1,5 @@
 package cc.mrbird.febs.pay.util;
 
-import cn.hutool.json.JSONObject;
-import cn.hutool.json.JSONUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.http.HttpEntity;
 import org.apache.http.client.methods.CloseableHttpResponse;
@@ -25,7 +23,7 @@
 	private static final String SECRET_KEY = "59c709fc18978a6a83b87f05d37cecbf";
 
 	@Transactional
-	public boolean comRefund(String outTradeNo, String outRefundNo,String amount){
+	public void comRefund(String outTradeNo, String outRefundNo,String amount){
 			// 退款请求参数
 			Map<String, String> params = new LinkedHashMap<>();
 			params.put("RefundType", "P"); // P: Partial Refund, F: Full Refund
@@ -52,14 +50,14 @@
 		}
 		System.out.println("退款响应: " + response);
 
-		JSONObject jsonObject = JSONUtil.parseObj(response);
-
-		String status = jsonObject.getStr("status");
-		if ("00".equals(status)) {
-			return true;
-		}else{
-			return false;
-		}
+//		JSONObject jsonObject = JSONUtil.parseObj(response);
+//
+//		String status = jsonObject.getStr("status");
+//		if ("00".equals(status)) {
+//			return true;
+//		}else{
+//			return false;
+//		}
 
 	}
 	public static void main(String[] args) {
@@ -68,8 +66,8 @@
 			Map<String, String> params = new LinkedHashMap<>();
 			params.put("RefundType", "P"); // P: Partial Refund, F: Full Refund
 			params.put("MerchantID", MERCHANT_ID);
-			params.put("RefID", "2025020614313541756_RITEM426"); // 商户唯一退款ID
-			params.put("TxnID", "2685173864"); // Fiuu原始交易ID
+			params.put("RefID", "2025020611124868512_RITEM42432121"); // 商户唯一退款ID
+			params.put("TxnID", "2685352601"); // Fiuu原始交易ID
 			params.put("Amount", "1.00"); // 退款金额
 
 			// 生成签名
diff --git a/src/main/java/cc/mrbird/febs/pay/util/HashUtils.java b/src/main/java/cc/mrbird/febs/pay/util/HashUtils.java
new file mode 100644
index 0000000..db3a203
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/pay/util/HashUtils.java
@@ -0,0 +1,18 @@
+package cc.mrbird.febs.pay.util;
+
+public class HashUtils {
+
+    public static String md5(String input) {
+        try {
+            java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
+            byte[] array = md.digest(input.getBytes());
+            StringBuilder sb = new StringBuilder();
+            for (byte b : array) {
+                sb.append(String.format("%02x", b));
+            }
+            return sb.toString();
+        } catch (java.security.NoSuchAlgorithmException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

--
Gitblit v1.9.1