diff --git a/app/main/api/internal/logic/admin_order/adminrefundorderlogic.go b/app/main/api/internal/logic/admin_order/adminrefundorderlogic.go index 26953de..e8a1c69 100644 --- a/app/main/api/internal/logic/admin_order/adminrefundorderlogic.go +++ b/app/main/api/internal/logic/admin_order/adminrefundorderlogic.go @@ -81,13 +81,12 @@ func (l *AdminRefundOrderLogic) handleAlipayRefund(order *model.Order, req *type if order.PayTime.Valid { orderPayTime = &order.PayTime.Time } - refundResp, err := l.svcCtx.AlipayService.AliRefund(l.ctx, order.OrderNo, req.RefundAmount, orderPayTime) + refundNo := l.generateRefundNo(order.OrderNo) + refundResp, err := l.svcCtx.AlipayService.AliRefund(l.ctx, order.OrderNo, req.RefundAmount, orderPayTime, refundNo) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "AdminRefundOrder, 支付宝退款失败 err: %v", err) } - refundNo := l.generateRefundNo(order.OrderNo) - if refundResp.IsSuccess() { // 支付宝退款成功,创建成功记录 err = l.createRefundRecordAndUpdateOrder(order, req, refundNo, refundResp.TradeNo, model.OrderStatusRefunded, model.OrderRefundStatusSuccess) @@ -188,9 +187,9 @@ func (l *AdminRefundOrderLogic) createRefundRecordOnly(order *model.Order, req * return nil } -// generateRefundNo 生成退款单号 +// generateRefundNo 生成退款单号(同一订单多次退款需唯一,避免 unique_refund_no 冲突) func (l *AdminRefundOrderLogic) generateRefundNo(orderNo string) string { - return fmt.Sprintf("%s%s", RefundNoPrefix, orderNo) + return fmt.Sprintf("%s%s-%d", RefundNoPrefix, orderNo, time.Now().UnixMilli()) } // createNullString 创建 sql.NullString diff --git a/app/main/api/internal/logic/pay/alipaycallbacklogic.go b/app/main/api/internal/logic/pay/alipaycallbacklogic.go index b504641..bf71d45 100644 --- a/app/main/api/internal/logic/pay/alipaycallbacklogic.go +++ b/app/main/api/internal/logic/pay/alipaycallbacklogic.go @@ -220,7 +220,7 @@ func (l *AlipayCallbackLogic) handleRefund(order *model.AgentMembershipRechargeO } else { // 代理会员订单以创建时间为准,仅 [2026-01-25 16:38:17, 2026-02-02 18:26) 区间内订单走 bak 商户号 orderPayTime := order.CreateTime - refund, refundErr := l.svcCtx.AlipayService.AliRefund(ctx, order.OrderNo, order.Amount, &orderPayTime) + refund, refundErr := l.svcCtx.AlipayService.AliRefund(ctx, order.OrderNo, order.Amount, &orderPayTime, "") if refundErr != nil { return refundErr } diff --git a/app/main/api/internal/logic/pay/wechatpaycallbacklogic.go b/app/main/api/internal/logic/pay/wechatpaycallbacklogic.go index 85b11f5..2f0649d 100644 --- a/app/main/api/internal/logic/pay/wechatpaycallbacklogic.go +++ b/app/main/api/internal/logic/pay/wechatpaycallbacklogic.go @@ -223,7 +223,7 @@ func (l *WechatPayCallbackLogic) handleRefund(order *model.AgentMembershipRechar } else { // 代理会员订单以创建时间为准,仅 [2026-01-25 16:38:17, 2026-02-02 18:26) 区间内订单走 bak 商户号 orderPayTime := order.CreateTime - refund, refundErr := l.svcCtx.AlipayService.AliRefund(ctx, order.OrderNo, order.Amount, &orderPayTime) + refund, refundErr := l.svcCtx.AlipayService.AliRefund(ctx, order.OrderNo, order.Amount, &orderPayTime, "") if refundErr != nil { return refundErr } diff --git a/app/main/api/internal/queue/paySuccessNotify.go b/app/main/api/internal/queue/paySuccessNotify.go index bbeddaf..222dc0c 100644 --- a/app/main/api/internal/queue/paySuccessNotify.go +++ b/app/main/api/internal/queue/paySuccessNotify.go @@ -271,7 +271,7 @@ func (l *PaySuccessNotifyUserHandler) handleError(ctx context.Context, err error if order.PayTime.Valid { orderPayTime = &order.PayTime.Time } - refund, refundErr := l.svcCtx.AlipayService.AliRefund(ctx, order.OrderNo, order.Amount, orderPayTime) + refund, refundErr := l.svcCtx.AlipayService.AliRefund(ctx, order.OrderNo, order.Amount, orderPayTime, "") if refundErr != nil { logx.Error(refundErr) return asynq.SkipRetry diff --git a/app/main/api/internal/service/alipayService.go b/app/main/api/internal/service/alipayService.go index b201920..e00b71b 100644 --- a/app/main/api/internal/service/alipayService.go +++ b/app/main/api/internal/service/alipayService.go @@ -144,17 +144,21 @@ func (a *AliPayService) CreateAlipayOrder(ctx context.Context, amount float64, s } // AliRefund 发起支付宝退款。orderPayTime 为订单支付时间(或创建时间);仅当落在 [2026-01-25 16:38:17, 2026-02-02 18:26) 区间内时使用 bak 商户号,否则使用正式商户号;传 nil 则使用正式商户号。 -func (a *AliPayService) AliRefund(ctx context.Context, outTradeNo string, refundAmount float64, orderPayTime *time.Time) (*alipay.TradeRefundRsp, error) { +// outRequestNo 为商户退款请求号,同一笔退款需唯一;传空则使用 "refund-"+outTradeNo,重试时建议传入唯一号避免支付宝报重复。 +func (a *AliPayService) AliRefund(ctx context.Context, outTradeNo string, refundAmount float64, orderPayTime *time.Time, outRequestNo string) (*alipay.TradeRefundRsp, error) { client := a.AlipayClient if orderPayTime != nil && a.AlipayClientBak != nil && !orderPayTime.Before(AlipayBakRefundStart) && orderPayTime.Before(AlipayBakRefundEnd) { client = a.AlipayClientBak } + if outRequestNo == "" { + outRequestNo = fmt.Sprintf("refund-%s", outTradeNo) + } refund := alipay.TradeRefund{ OutTradeNo: outTradeNo, RefundAmount: lzUtils.ToAlipayAmount(refundAmount), - OutRequestNo: fmt.Sprintf("refund-%s", outTradeNo), + OutRequestNo: outRequestNo, } refundResp, err := client.TradeRefund(ctx, refund)