Ver Fonte

add:微信支付流程跑通。

lyx há 1 semana atrás
pai
commit
7b96515710

+ 154 - 0
alien-entity/src/main/java/shop/alien/entity/store/RefundRecord.java

@@ -0,0 +1,154 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 退款记录表
+ * </p>
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@JsonInclude
+@ApiModel(value = "RefundRecord对象", description = "退款记录表")
+@TableName("refund_record")
+public class RefundRecord extends Model<RefundRecord> {
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "用户ID")
+    @TableField("user_id")
+    private Integer userId;
+
+    @ApiModelProperty(value = "商户订单号:商户系统生成的原交易订单唯一标识")
+    @TableField("out_trade_no")
+    private String outTradeNo;
+
+    @ApiModelProperty(value = "第三方支付订单号:微信支付订单号或支付宝交易号")
+    @TableField("transaction_id")
+    private String transactionId;
+
+    @ApiModelProperty(value = "商户退款单号:商户系统生成的退款单号")
+    @TableField("out_refund_no")
+    private String outRefundNo;
+
+    @ApiModelProperty(value = "第三方退款单号:微信退款单号或支付宝退款单号")
+    @TableField("refund_id")
+    private String refundId;
+
+    @ApiModelProperty(value = "支付类型:WECHAT_PAY-微信支付, ALIPAY-支付宝")
+    @TableField("pay_type")
+    private String payType;
+
+    @ApiModelProperty(value = "退款状态:SUCCESS-退款成功, CLOSED-退款关闭, PROCESSING-退款处理中, ABNORMAL-退款异常")
+    @TableField("refund_status")
+    private String refundStatus;
+
+    @ApiModelProperty(value = "订单总金额:单位分")
+    @TableField("total_amount")
+    private Long totalAmount;
+
+    @ApiModelProperty(value = "退款金额:单位分")
+    @TableField("refund_amount")
+    private Long refundAmount;
+
+    @ApiModelProperty(value = "实际退款金额:单位分,最终成功退回给用户的金额")
+    @TableField("actual_refund_amount")
+    private Long actualRefundAmount;
+
+    @ApiModelProperty(value = "退款币种:默认CNY")
+    @TableField("currency")
+    private String currency;
+
+    @ApiModelProperty(value = "退款原因")
+    @TableField("refund_reason")
+    private String refundReason;
+
+    @ApiModelProperty(value = "退款渠道:ORIGINAL-原路退回, BALANCE-退回余额, OTHER_BALANCE-其他余额, OTHER_BANKCARD-其他银行卡")
+    @TableField("refund_channel")
+    private String refundChannel;
+
+    @ApiModelProperty(value = "退款资金来源:AVAILABLE-可用余额, UNSETTLED-未结算资金")
+    @TableField("funds_account")
+    private String fundsAccount;
+
+    @ApiModelProperty(value = "退款创建时间:退款请求创建时间")
+    @TableField("refund_create_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date refundCreateTime;
+
+    @ApiModelProperty(value = "退款成功时间:退款成功完成时间")
+    @TableField("refund_success_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date refundSuccessTime;
+
+    @ApiModelProperty(value = "用户收到退款账户:退款到账的账户信息")
+    @TableField("user_received_account")
+    private String userReceivedAccount;
+
+    @ApiModelProperty(value = "退款详情:退款渠道明细列表(JSON格式)")
+    @TableField("refund_detail")
+    private String refundDetail;
+
+    @ApiModelProperty(value = "错误码:退款失败时的错误码")
+    @TableField("error_code")
+    private String errorCode;
+
+    @ApiModelProperty(value = "错误信息:退款失败时的错误描述")
+    @TableField("error_msg")
+    private String errorMsg;
+
+    @ApiModelProperty(value = "响应数据:第三方支付平台返回的完整响应数据(JSON格式)")
+    @TableField("response_data")
+    private String responseData;
+
+    @ApiModelProperty(value = "业务订单ID:关联的业务订单ID")
+    @TableField("order_id")
+    private String orderId;
+
+    @ApiModelProperty(value = "店铺ID")
+    @TableField("store_id")
+    private Integer storeId;
+
+    @ApiModelProperty(value = "备注")
+    @TableField("remark")
+    private String remark;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+}
+

+ 3 - 0
alien-entity/src/main/java/shop/alien/entity/store/dto/PayStatusRequest.java

@@ -29,5 +29,8 @@ public class PayStatusRequest implements Serializable {
 
     @ApiModelProperty(value = "支付宝或VX的str")
     private String orderStr;
+    
+    @ApiModelProperty
+    private String alipayNo;
 }
 

+ 17 - 0
alien-entity/src/main/java/shop/alien/mapper/RefundRecordMapper.java

@@ -0,0 +1,17 @@
+package shop.alien.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import shop.alien.entity.store.RefundRecord;
+
+/**
+ * <p>
+ * 退款记录表 Mapper 接口
+ * </p>
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+public interface RefundRecordMapper extends BaseMapper<RefundRecord> {
+
+}
+

+ 6 - 3
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/LawyerConsultationOrderServiceImpl.java

@@ -38,10 +38,7 @@ import shop.alien.util.common.constant.LawyerStatusEnum;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-
 import java.text.SimpleDateFormat;
-import java.time.LocalDateTime;
-import java.time.ZoneId;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -545,6 +542,12 @@ public class LawyerConsultationOrderServiceImpl extends ServiceImpl<LawyerConsul
                 request.getOrderNumber(), request.getPaymentStatus(), request.getOrderStatus());
 
         LawyerConsultationOrderDto order = new LawyerConsultationOrderDto();
+        if (null != request.getOrderStr()){
+            order.setOrderStr(request.getOrderStr());
+        }
+        if (null != request.getAlipayNo()){
+            order.setAlipayNo(request.getAlipayNo());
+        }
         order.setOrderNumber(request.getOrderNumber());
         order.setPaymentStatus(request.getPaymentStatus());
         order.setOrderStatus(request.getOrderStatus());

+ 17 - 0
alien-store/src/main/java/shop/alien/store/service/RefundRecordService.java

@@ -0,0 +1,17 @@
+package shop.alien.store.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.store.RefundRecord;
+
+/**
+ * <p>
+ * 退款记录表 服务类
+ * </p>
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+public interface RefundRecordService extends IService<RefundRecord> {
+
+}
+

+ 21 - 0
alien-store/src/main/java/shop/alien/store/service/impl/RefundRecordServiceImpl.java

@@ -0,0 +1,21 @@
+package shop.alien.store.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import shop.alien.entity.store.RefundRecord;
+import shop.alien.mapper.RefundRecordMapper;
+import shop.alien.store.service.RefundRecordService;
+
+/**
+ * <p>
+ * 退款记录表 服务实现类
+ * </p>
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Service
+public class RefundRecordServiceImpl extends ServiceImpl<RefundRecordMapper, RefundRecord> implements RefundRecordService {
+
+}
+

+ 214 - 6
alien-store/src/main/java/shop/alien/store/strategy/payment/impl/AlipayPaymentStrategyImpl.java

@@ -21,7 +21,9 @@ import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 import shop.alien.entity.result.R;
+import shop.alien.entity.store.RefundRecord;
 import shop.alien.entity.store.StoreAliPayRefundLog;
+import shop.alien.store.service.RefundRecordService;
 import shop.alien.store.service.StoreAliPayRefundLogService;
 import shop.alien.store.strategy.payment.PaymentStrategy;
 import shop.alien.util.common.UniqueRandomNumGenerator;
@@ -113,6 +115,8 @@ public class AlipayPaymentStrategyImpl implements PaymentStrategy {
 
     private final StoreAliPayRefundLogService storeAliPayRefundLogService;
 
+    private final RefundRecordService refundRecordService;
+
 
     /**
      * 填写阿里配置
@@ -245,12 +249,12 @@ public class AlipayPaymentStrategyImpl implements PaymentStrategy {
             AlipayTradeRefundRequest request = buildRefundRequest(params);
             AlipayTradeRefundResponse response = refundRun(request);
             String refundReslut = "";
+            JSONObject responseBody = JSONObject.parseObject(response.getBody());
+            JSONObject refundResponse = responseBody.getJSONObject("alipay_trade_refund_response");
+            
             if (response.isSuccess()) {
                 refundReslut = "调用成功";
-                // 保存退款信息进入到退款记录表
-                JSONObject responseBody = JSONObject.parseObject(response.getBody());
-                JSONObject refundResponse = responseBody.getJSONObject("alipay_trade_refund_response");
-
+                // 保存退款信息进入到支付宝退款记录表(保留原有逻辑)
                 StoreAliPayRefundLog refundLog = new StoreAliPayRefundLog();
                 // 响应基本信息
                 refundLog.setResponseCode(refundResponse.getString("code"));
@@ -293,10 +297,48 @@ public class AlipayPaymentStrategyImpl implements PaymentStrategy {
                 refundLog.setDeleteFlag(0);
                 refundLog.setCreatedTime(new Date());
                 storeAliPayRefundLogService.save(refundLog);
+                
+                // 保存到通用退款记录表
+                try {
+                    RefundRecord refundRecord = buildRefundRecordFromAlipayResponse(refundResponse, responseBody, params);
+                    if (refundRecord != null) {
+                        // 检查是否已存在,避免重复插入
+                        long count = refundRecordService.lambdaQuery()
+                                .eq(RefundRecord::getOutRefundNo, refundRecord.getOutRefundNo())
+                                .count();
+                        if (count == 0) {
+                            refundRecordService.save(refundRecord);
+                            log.info("支付宝退款记录已保存到RefundRecord表,商户退款单号:{}", refundRecord.getOutRefundNo());
+                        } else {
+                            log.info("支付宝退款记录已存在,跳过插入,商户退款单号:{}", refundRecord.getOutRefundNo());
+                        }
+                    }
+                } catch (Exception e) {
+                    log.error("保存支付宝退款记录到RefundRecord表失败", e);
+                    // 不抛出异常,避免影响原有逻辑
+                }
             } else {
                 log.warn("AliPayConfig.processRefund ERROR Msg={}", response.getBody());
-                JSONObject jsonObject = JSONObject.parseObject(response.getBody()).getJSONObject("alipay_trade_refund_response");
-                refundReslut =  jsonObject.getString("sub_msg");
+                refundReslut = refundResponse.getString("sub_msg");
+                
+                // 保存失败记录到通用退款记录表
+                try {
+                    RefundRecord refundRecord = buildRefundRecordFromAlipayError(refundResponse, responseBody, params);
+                    if (refundRecord != null) {
+                        // 检查是否已存在,避免重复插入
+                        long count = refundRecordService.lambdaQuery()
+                                .eq(RefundRecord::getOutRefundNo, refundRecord.getOutRefundNo())
+                                .count();
+                        if (count == 0) {
+                            refundRecordService.save(refundRecord);
+                            log.info("支付宝退款失败记录已保存到RefundRecord表,商户退款单号:{}", refundRecord.getOutRefundNo());
+                        } else {
+                            log.info("支付宝退款失败记录已存在,跳过插入,商户退款单号:{}", refundRecord.getOutRefundNo());
+                        }
+                    }
+                } catch (Exception e) {
+                    log.error("保存支付宝退款失败记录到RefundRecord表失败", e);
+                }
             }
             return refundReslut;
         } catch (AlipayApiException e) {
@@ -370,5 +412,171 @@ public class AlipayPaymentStrategyImpl implements PaymentStrategy {
         return response;
     }
 
+    /**
+     * 从支付宝退款响应构建RefundRecord对象(成功情况)
+     */
+    private RefundRecord buildRefundRecordFromAlipayResponse(JSONObject refundResponse, JSONObject responseBody, Map<String, String> params) {
+        try {
+            RefundRecord record = new RefundRecord();
+            
+            // 基本信息
+            record.setPayType(PaymentEnum.ALIPAY.getType());
+            record.setOutTradeNo(refundResponse.getString("out_trade_no"));
+            record.setTransactionId(refundResponse.getString("trade_no"));
+            // 部分退款编号作为商户退款单号,如果没有则生成一个
+            String outRefundNo = params.get("partialRefundCode");
+            if (StringUtils.isBlank(outRefundNo)) {
+                outRefundNo = UniqueRandomNumGenerator.generateUniqueCode(19);
+            }
+            record.setOutRefundNo(outRefundNo);
+            record.setRefundId(null); // 支付宝没有单独的退款单号
+            record.setRefundStatus("SUCCESS");
+            
+            // 金额信息(支付宝返回的是元,需要转换为分)
+            String refundFeeStr = refundResponse.getString("refund_fee");
+            String sendBackFeeStr = refundResponse.getString("send_back_fee");
+            if (StringUtils.isNotBlank(refundFeeStr)) {
+                record.setRefundAmount(new BigDecimal(refundFeeStr).multiply(new BigDecimal(100)).longValue());
+            }
+            if (StringUtils.isNotBlank(sendBackFeeStr)) {
+                record.setActualRefundAmount(new BigDecimal(sendBackFeeStr).multiply(new BigDecimal(100)).longValue());
+            }
+            // 订单总金额从params获取,如果没有则从退款金额推算
+            String totalAmountStr = params.get("totalAmount");
+            if (StringUtils.isNotBlank(totalAmountStr)) {
+                record.setTotalAmount(new BigDecimal(totalAmountStr).multiply(new BigDecimal(100)).longValue());
+            }
+            record.setCurrency("CNY");
+            
+            // 退款原因
+            record.setRefundReason(params.get("refundReason"));
+            
+            // 退款详情
+            if (refundResponse.containsKey("refund_detail_item_list")) {
+                JSONArray refundDetailList = refundResponse.getJSONArray("refund_detail_item_list");
+                if (refundDetailList != null) {
+                    record.setRefundDetail(JSON.toJSONString(refundDetailList));
+                }
+            }
+            
+            // 用户收到退款账户
+            record.setUserReceivedAccount(refundResponse.getString("buyer_logon_id"));
+            
+            // 退款时间
+            String gmtRefundPayStr = refundResponse.getString("gmt_refund_pay");
+            if (StringUtils.isNotBlank(gmtRefundPayStr)) {
+                try {
+                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                    Date refundTime = sdf.parse(gmtRefundPayStr);
+                    record.setRefundSuccessTime(refundTime);
+                    record.setRefundCreateTime(refundTime); // 支付宝没有单独的创建时间
+                } catch (ParseException e) {
+                    log.warn("解析退款时间失败: {}", gmtRefundPayStr, e);
+                }
+            }
+            
+            // 业务信息(从params获取,如果有的话)
+            if (params.containsKey("userId")) {
+                try {
+                    record.setUserId(Integer.parseInt(params.get("userId")));
+                } catch (NumberFormatException e) {
+                    log.warn("解析userId失败: {}", params.get("userId"));
+                }
+            }
+            if (params.containsKey("orderId")) {
+                record.setOrderId(params.get("orderId"));
+            }
+            if (params.containsKey("storeId")) {
+                try {
+                    record.setStoreId(Integer.parseInt(params.get("storeId")));
+                } catch (NumberFormatException e) {
+                    log.warn("解析storeId失败: {}", params.get("storeId"));
+                }
+            }
+            
+            // 响应数据
+            record.setResponseData(responseBody.toJSONString());
+            
+            // 标准字段
+            record.setDeleteFlag(0);
+            record.setCreatedTime(new Date());
+            
+            return record;
+        } catch (Exception e) {
+            log.error("构建RefundRecord对象失败", e);
+            return null;
+        }
+    }
+
+    /**
+     * 从支付宝退款错误响应构建RefundRecord对象(失败情况)
+     */
+    private RefundRecord buildRefundRecordFromAlipayError(JSONObject refundResponse, JSONObject responseBody, Map<String, String> params) {
+        try {
+            RefundRecord record = new RefundRecord();
+            
+            // 基本信息
+            record.setPayType(PaymentEnum.ALIPAY.getType());
+            record.setOutTradeNo(params.get("outTradeNo"));
+            // 部分退款编号作为商户退款单号,如果没有则生成一个
+            String outRefundNo = params.get("partialRefundCode");
+            if (StringUtils.isBlank(outRefundNo)) {
+                outRefundNo = UniqueRandomNumGenerator.generateUniqueCode(19);
+            }
+            record.setOutRefundNo(outRefundNo);
+            record.setRefundStatus("ABNORMAL");
+            
+            // 金额信息
+            String refundAmountStr = params.get("refundAmount");
+            if (StringUtils.isNotBlank(refundAmountStr)) {
+                record.setRefundAmount(new BigDecimal(refundAmountStr).multiply(new BigDecimal(100)).longValue());
+            }
+            String totalAmountStr = params.get("totalAmount");
+            if (StringUtils.isNotBlank(totalAmountStr)) {
+                record.setTotalAmount(new BigDecimal(totalAmountStr).multiply(new BigDecimal(100)).longValue());
+            }
+            record.setCurrency("CNY");
+            
+            // 退款原因
+            record.setRefundReason(params.get("refundReason"));
+            
+            // 错误信息
+            record.setErrorCode(refundResponse.getString("code"));
+            record.setErrorMsg(refundResponse.getString("sub_msg"));
+            
+            // 业务信息
+            if (params.containsKey("userId")) {
+                try {
+                    record.setUserId(Integer.parseInt(params.get("userId")));
+                } catch (NumberFormatException e) {
+                    log.warn("解析userId失败: {}", params.get("userId"));
+                }
+            }
+            if (params.containsKey("orderId")) {
+                record.setOrderId(params.get("orderId"));
+            }
+            if (params.containsKey("storeId")) {
+                try {
+                    record.setStoreId(Integer.parseInt(params.get("storeId")));
+                } catch (NumberFormatException e) {
+                    log.warn("解析storeId失败: {}", params.get("storeId"));
+                }
+            }
+            
+            // 响应数据
+            record.setResponseData(responseBody.toJSONString());
+            
+            // 标准字段
+            record.setDeleteFlag(0);
+            record.setCreatedTime(new Date());
+            record.setRefundCreateTime(new Date());
+            
+            return record;
+        } catch (Exception e) {
+            log.error("构建RefundRecord对象失败", e);
+            return null;
+        }
+    }
+
 }
 

+ 384 - 10
alien-store/src/main/java/shop/alien/store/strategy/payment/impl/WeChatPaymentStrategyImpl.java

@@ -8,6 +8,8 @@ import okhttp3.*;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 import shop.alien.entity.result.R;
+import shop.alien.entity.store.RefundRecord;
+import shop.alien.store.service.RefundRecordService;
 import shop.alien.store.strategy.payment.PaymentStrategy;
 import shop.alien.store.util.WXPayUtility;
 import shop.alien.util.common.UniqueRandomNumGenerator;
@@ -22,7 +24,12 @@ import java.nio.charset.StandardCharsets;
 import java.security.PrivateKey;
 import java.security.PublicKey;
 import java.security.Signature;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.OffsetDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.Base64;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -39,6 +46,8 @@ import java.util.Map;
 @RequiredArgsConstructor
 public class WeChatPaymentStrategyImpl implements PaymentStrategy {
 
+    private final RefundRecordService refundRecordService;
+
     @Value("${payment.wechatPay.host}")
     private String wechatPayApiHost;
 
@@ -202,7 +211,7 @@ public class WeChatPaymentStrategyImpl implements PaymentStrategy {
             result.put("prepayId", response.prepayId);
             result.put("appId", appId);
             result.put("mchId", mchId);
-            result.put("outTradeNo", request.outTradeNo);
+            result.put("orderNo", request.outTradeNo);
             // 生成sign
 //            appId
 
@@ -251,6 +260,7 @@ public class WeChatPaymentStrategyImpl implements PaymentStrategy {
 
     @Override
     public String handleRefund(Map<String,String> params) throws Exception {
+
         CreateRequest request = new CreateRequest();
         // 微信支付订单号和商户订单号必须二选一,不能同时为空,查询的时候使用的是商户订单号
         //request.transactionId = "1217752501201407033233368018";
@@ -265,7 +275,7 @@ public class WeChatPaymentStrategyImpl implements PaymentStrategy {
         //request.fundsAccount = ReqFundsAccount.AVAILABLE;
         // 金额信息
         request.amount = new AmountReq();
-        request.amount.refund = new BigDecimal(params.get("refundAmount")).multiply(new BigDecimal(100)).longValue();
+        request.amount.refund = new BigDecimal(params.get("refundAmount")).longValue();
         // 退款出资账户及金额 目前不需要,需要的时候再看
         /*
         request.amount.from = new ArrayList<>();
@@ -276,7 +286,7 @@ public class WeChatPaymentStrategyImpl implements PaymentStrategy {
             request.amount.from.add(fromItem);
         };*/
         // 订单总金额
-        request.amount.total = new BigDecimal(params.get("totalAmount")).multiply(new BigDecimal(100)).longValue();
+        request.amount.total = new BigDecimal(params.get("totalAmount")).longValue();
         // 退款币种 目前默认人民币 CNY
         request.amount.currency = "CNY";
         // 退款商品信息 目前不需要,需要的时候再看
@@ -292,16 +302,119 @@ public class WeChatPaymentStrategyImpl implements PaymentStrategy {
             goodsDetailItem.refundQuantity = 1L;
             request.goodsDetail.add(goodsDetailItem);
         };*/
+        // 记录退款请求信息
+        log.info("开始处理微信支付退款,商户订单号:{},商户退款单号:{},退款金额:{}分,订单总金额:{}分,退款原因:{}",
+                request.outTradeNo, request.outRefundNo, request.amount.refund, request.amount.total, request.reason);
+        String refundResult = "";
         try {
             Refund response = refundRun(request);
-            String refundReslut = "";
-            // TODO: 请求成功,继续业务逻辑
-            System.out.println(response);
-        } catch (WXPayUtility.ApiException e) {
-            // TODO: 请求失败,根据状态码执行不同的逻辑
-            e.printStackTrace();
+            // 退款状态
+            String status = response.status != null ? response.status.name() : "UNKNOWN";
+            if ("SUCCESS".equals(status) || "PROCESSING".equals(status)) {
+                // refund_id 申请退款受理成功时,该笔退款单在微信支付侧生成的唯一标识。
+                String refundId = response.refundId;
+                // 商户申请退款时传的商户系统内部退款单号。
+                String outRefundNo = response.outRefundNo != null ? response.outRefundNo : request.outRefundNo;
+                // 微信支付订单号
+                String transactionId = response.transactionId;
+
+                // 退款金额信息
+                String refundAmount = response.amount != null && response.amount.refund != null
+                        ? String.valueOf(response.amount.refund) : String.valueOf(request.amount.refund);
+                String totalAmount = response.amount != null && response.amount.total != null
+                        ? String.valueOf(response.amount.total) : String.valueOf(request.amount.total);
+                // 退款成功时间
+                String successTime = response.successTime;
+                // 退款创建时间
+                String createTime = response.createTime;
+                // 退款渠道
+                String channel = response.channel != null ? response.channel.name() : "UNKNOWN";
+
+                // 记录退款成功详细信息
+                log.info("微信支付退款成功 - 商户订单号:{},微信支付订单号:{},商户退款单号:{},微信退款单号:{}," +
+                                "退款状态:{},退款金额:{}分,订单总金额:{}分,退款渠道:{},创建时间:{},成功时间:{}",
+                        request.outTradeNo, transactionId, outRefundNo, refundId, status, refundAmount,
+                        totalAmount, channel, createTime, successTime != null ? successTime : "未完成");
+
+                // 保存到通用退款记录表
+                try {
+                    RefundRecord refundRecord = buildRefundRecordFromWeChatResponse(response, request, params);
+                    if (refundRecord != null) {
+                        // 检查是否已存在,避免重复插入
+                        long count = refundRecordService.lambdaQuery()
+                                .eq(RefundRecord::getOutRefundNo, refundRecord.getOutRefundNo())
+                                .count();
+                        if (count == 0) {
+                            refundRecordService.save(refundRecord);
+                            log.info("微信支付退款记录已保存到RefundRecord表,商户退款单号:{}", refundRecord.getOutRefundNo());
+                        } else {
+                            log.info("微信支付退款记录已存在,跳过插入,商户退款单号:{}", refundRecord.getOutRefundNo());
+                        }
+                    }
+                } catch (Exception e) {
+                    log.error("保存微信支付退款记录到RefundRecord表失败", e);
+                    // 不抛出异常,避免影响原有逻辑
+                }
+
+                refundResult = "调用成功";
+                return refundResult;
+            } else {
+                log.error("微信支付退款失败 - 商户订单号:{},商户退款单号:{},退款金额:{}分,订单总金额:{}分," +
+                                "退款状态:{}",
+                        request.outTradeNo, request.outRefundNo, request.amount.refund,
+                        request.amount.total, status);
+                
+                // 保存失败记录到通用退款记录表
+                try {
+                    RefundRecord refundRecord = buildRefundRecordFromWeChatError(response, request, params, status);
+                    if (refundRecord != null) {
+                        // 检查是否已存在,避免重复插入
+                        long count = refundRecordService.lambdaQuery()
+                                .eq(RefundRecord::getOutRefundNo, refundRecord.getOutRefundNo())
+                                .count();
+                        if (count == 0) {
+                            refundRecordService.save(refundRecord);
+                            log.info("微信支付退款失败记录已保存到RefundRecord表,商户退款单号:{}", refundRecord.getOutRefundNo());
+                        } else {
+                            log.info("微信支付退款失败记录已存在,跳过插入,商户退款单号:{}", refundRecord.getOutRefundNo());
+                        }
+                    }
+                } catch (Exception e) {
+                    log.error("保存微信支付退款失败记录到RefundRecord表失败", e);
+                }
+                
+                return "退款失败";
+            }
+        }
+        catch (Exception e) {
+            // 记录其他异常
+            log.error("微信支付退款异常 - 商户订单号:{},商户退款单号:{},退款金额:{}分,订单总金额:{}分," +
+                    "退款原因:{},异常信息:{}",
+                    request.outTradeNo, request.outRefundNo, request.amount.refund, 
+                    request.amount.total, request.reason, e.getMessage(), e);
+            
+            // 保存异常记录到通用退款记录表
+            try {
+                RefundRecord refundRecord = buildRefundRecordFromWeChatException(request, params, e);
+                if (refundRecord != null) {
+                    // 检查是否已存在,避免重复插入
+                    long count = refundRecordService.lambdaQuery()
+                            .eq(RefundRecord::getOutRefundNo, refundRecord.getOutRefundNo())
+                            .count();
+                    if (count == 0) {
+                        refundRecordService.save(refundRecord);
+                        log.info("微信支付退款异常记录已保存到RefundRecord表,商户退款单号:{}", refundRecord.getOutRefundNo());
+                    } else {
+                        log.info("微信支付退款异常记录已存在,跳过插入,商户退款单号:{}", refundRecord.getOutRefundNo());
+                    }
+                }
+            } catch (Exception ex) {
+                log.error("保存微信支付退款异常记录到RefundRecord表失败", ex);
+            }
+            
+            refundResult = "退款处理异常:" + e.getMessage();
+            return refundResult;
         }
-        return null;
     }
 
 
@@ -864,4 +977,265 @@ public class WeChatPaymentStrategyImpl implements PaymentStrategy {
         @SerializedName("UNAVAILABLE")
         UNAVAILABLE
     }
+
+    /**
+     * 从微信支付退款响应构建RefundRecord对象(成功情况)
+     */
+    private RefundRecord buildRefundRecordFromWeChatResponse(Refund response, CreateRequest request, Map<String, String> params) {
+        try {
+            RefundRecord record = new RefundRecord();
+            
+            // 基本信息
+            record.setPayType(PaymentEnum.WECHAT_PAY.getType());
+            record.setOutTradeNo(response.outTradeNo != null ? response.outTradeNo : request.outTradeNo);
+            record.setTransactionId(response.transactionId);
+            record.setOutRefundNo(response.outRefundNo != null ? response.outRefundNo : request.outRefundNo);
+            record.setRefundId(response.refundId);
+            record.setRefundStatus(response.status != null ? response.status.name() : "UNKNOWN");
+            
+            // 金额信息(微信返回的是分)
+            if (response.amount != null) {
+                record.setTotalAmount(response.amount.total);
+                record.setRefundAmount(response.amount.refund);
+                record.setActualRefundAmount(response.amount.refund); // 微信退款金额就是实际退款金额
+                if (response.amount.currency != null) {
+                    record.setCurrency(response.amount.currency);
+                } else {
+                    record.setCurrency("CNY");
+                }
+            } else {
+                record.setTotalAmount(request.amount.total);
+                record.setRefundAmount(request.amount.refund);
+                record.setActualRefundAmount(request.amount.refund);
+                record.setCurrency(request.amount.currency != null ? request.amount.currency : "CNY");
+            }
+            
+            // 退款原因
+            record.setRefundReason(request.reason);
+            
+            // 退款渠道
+            if (response.channel != null) {
+                record.setRefundChannel(response.channel.name());
+            }
+            
+            // 退款资金来源
+            if (response.fundsAccount != null) {
+                record.setFundsAccount(response.fundsAccount.name());
+            }
+            
+            // 用户收到退款账户
+            record.setUserReceivedAccount(response.userReceivedAccount);
+            
+            // 退款详情(如果有优惠信息)
+            if (response.promotionDetail != null && !response.promotionDetail.isEmpty()) {
+                record.setRefundDetail(WXPayUtility.toJson(response.promotionDetail));
+            }
+            
+            // 退款时间(微信返回的是ISO 8601格式字符串,需要转换为Date)
+            if (response.createTime != null) {
+                Date createTime = parseWeChatTime(response.createTime);
+                if (createTime != null) {
+                    record.setRefundCreateTime(createTime);
+                }
+            }
+            if (response.successTime != null) {
+                Date successTime = parseWeChatTime(response.successTime);
+                if (successTime != null) {
+                    record.setRefundSuccessTime(successTime);
+                }
+            }
+            
+            // 业务信息(从params获取,如果有的话)
+            if (params != null) {
+                if (params.containsKey("userId")) {
+                    try {
+                        record.setUserId(Integer.parseInt(params.get("userId")));
+                    } catch (NumberFormatException e) {
+                        log.warn("解析userId失败: {}", params.get("userId"));
+                    }
+                }
+                if (params.containsKey("orderId")) {
+                    record.setOrderId(params.get("orderId"));
+                }
+                if (params.containsKey("storeId")) {
+                    try {
+                        record.setStoreId(Integer.parseInt(params.get("storeId")));
+                    } catch (NumberFormatException e) {
+                        log.warn("解析storeId失败: {}", params.get("storeId"));
+                    }
+                }
+            }
+            
+            // 响应数据
+            record.setResponseData(WXPayUtility.toJson(response));
+            
+            // 标准字段
+            record.setDeleteFlag(0);
+            record.setCreatedTime(new Date());
+            
+            return record;
+        } catch (Exception e) {
+            log.error("构建RefundRecord对象失败", e);
+            return null;
+        }
+    }
+
+    /**
+     * 从微信支付退款错误响应构建RefundRecord对象(失败情况)
+     */
+    private RefundRecord buildRefundRecordFromWeChatError(Refund response, CreateRequest request, Map<String, String> params, String status) {
+        try {
+            RefundRecord record = new RefundRecord();
+            
+            // 基本信息
+            record.setPayType(PaymentEnum.WECHAT_PAY.getType());
+            record.setOutTradeNo(response.outTradeNo != null ? response.outTradeNo : request.outTradeNo);
+            record.setTransactionId(response.transactionId);
+            record.setOutRefundNo(response.outRefundNo != null ? response.outRefundNo : request.outRefundNo);
+            record.setRefundId(response.refundId);
+            record.setRefundStatus(status);
+            
+            // 金额信息
+            if (response.amount != null) {
+                record.setTotalAmount(response.amount.total);
+                record.setRefundAmount(response.amount.refund);
+                record.setCurrency(response.amount.currency != null ? response.amount.currency : "CNY");
+            } else {
+                record.setTotalAmount(request.amount.total);
+                record.setRefundAmount(request.amount.refund);
+                record.setCurrency(request.amount.currency != null ? request.amount.currency : "CNY");
+            }
+            
+            // 退款原因
+            record.setRefundReason(request.reason);
+            
+            // 退款时间
+            if (response.createTime != null) {
+                Date createTime = parseWeChatTime(response.createTime);
+                if (createTime != null) {
+                    record.setRefundCreateTime(createTime);
+                }
+            }
+            
+            // 业务信息
+            if (params != null) {
+                if (params.containsKey("userId")) {
+                    try {
+                        record.setUserId(Integer.parseInt(params.get("userId")));
+                    } catch (NumberFormatException e) {
+                        log.warn("解析userId失败: {}", params.get("userId"));
+                    }
+                }
+                if (params.containsKey("orderId")) {
+                    record.setOrderId(params.get("orderId"));
+                }
+                if (params.containsKey("storeId")) {
+                    try {
+                        record.setStoreId(Integer.parseInt(params.get("storeId")));
+                    } catch (NumberFormatException e) {
+                        log.warn("解析storeId失败: {}", params.get("storeId"));
+                    }
+                }
+            }
+            
+            // 响应数据
+            record.setResponseData(WXPayUtility.toJson(response));
+            
+            // 标准字段
+            record.setDeleteFlag(0);
+            record.setCreatedTime(new Date());
+            
+            return record;
+        } catch (Exception e) {
+            log.error("构建RefundRecord对象失败", e);
+            return null;
+        }
+    }
+
+    /**
+     * 从微信支付退款异常构建RefundRecord对象(异常情况)
+     */
+    private RefundRecord buildRefundRecordFromWeChatException(CreateRequest request, Map<String, String> params, Exception e) {
+        try {
+            RefundRecord record = new RefundRecord();
+            
+            // 基本信息
+            record.setPayType(PaymentEnum.WECHAT_PAY.getType());
+            record.setOutTradeNo(request.outTradeNo);
+            record.setOutRefundNo(request.outRefundNo);
+            record.setRefundStatus("ABNORMAL");
+            
+            // 金额信息
+            record.setTotalAmount(request.amount.total);
+            record.setRefundAmount(request.amount.refund);
+            record.setCurrency(request.amount.currency != null ? request.amount.currency : "CNY");
+            
+            // 退款原因
+            record.setRefundReason(request.reason);
+            
+            // 错误信息
+            if (e instanceof WXPayUtility.ApiException) {
+                WXPayUtility.ApiException apiException = (WXPayUtility.ApiException) e;
+                record.setErrorCode(String.valueOf(apiException.getErrorCode()));
+                record.setErrorMsg(apiException.getMessage());
+            } else {
+                record.setErrorMsg(e.getMessage());
+            }
+            
+            // 业务信息
+            if (params != null) {
+                if (params.containsKey("userId")) {
+                    try {
+                        record.setUserId(Integer.parseInt(params.get("userId")));
+                    } catch (NumberFormatException ex) {
+                        log.warn("解析userId失败: {}", params.get("userId"));
+                    }
+                }
+                if (params.containsKey("orderId")) {
+                    record.setOrderId(params.get("orderId"));
+                }
+                if (params.containsKey("storeId")) {
+                    try {
+                        record.setStoreId(Integer.parseInt(params.get("storeId")));
+                    } catch (NumberFormatException ex) {
+                        log.warn("解析storeId失败: {}", params.get("storeId"));
+                    }
+                }
+            }
+            
+            // 标准字段
+            record.setDeleteFlag(0);
+            record.setCreatedTime(new Date());
+            record.setRefundCreateTime(new Date());
+            
+            return record;
+        } catch (Exception ex) {
+            log.error("构建RefundRecord对象失败", ex);
+            return null;
+        }
+    }
+
+    /**
+     * 解析微信支付返回的时间字符串(ISO 8601格式)
+     * 例如:2018-06-08T10:34:56+08:00
+     */
+    private Date parseWeChatTime(String timeStr) {
+        if (timeStr == null || timeStr.trim().isEmpty()) {
+            return null;
+        }
+        try {
+            // 尝试解析ISO 8601格式
+            OffsetDateTime dateTime = OffsetDateTime.parse(timeStr, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+            return Date.from(dateTime.toInstant());
+        } catch (Exception e) {
+            // 如果ISO 8601解析失败,尝试其他格式
+            try {
+                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                return sdf.parse(timeStr);
+            } catch (ParseException ex) {
+                log.warn("解析微信支付时间失败: {}", timeStr, ex);
+                return null;
+            }
+        }
+    }
 }