package pay import ( "context" "fmt" "qnc-server/app/main/api/internal/svc" "qnc-server/app/main/model" "qnc-server/pkg/lzkit/lzUtils" "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/stores/sqlx" ) // RefundXpayQueryOrder 对 xpay 查询订单发起全额退款并更新本地订单状态 func RefundXpayQueryOrder(ctx context.Context, svcCtx *svc.ServiceContext, order *model.Order) error { if svcCtx.XpayService == nil || !svcCtx.XpayService.Enabled() { return fmt.Errorf("虚拟支付未启用") } openid, err := svcCtx.XpayService.GetWxMiniOpenID(ctx, svcCtx.UserAuthModel, order.UserId) if err != nil { return fmt.Errorf("获取 openid 失败: %w", err) } refundFeeFen := lzUtils.ToWechatAmount(order.Amount) refundOrderID := buildXpayRefundOrderID(order.OrderNo) if refundErr := svcCtx.XpayService.RefundOrder(ctx, openid, order.OrderNo, refundOrderID, refundFeeFen); refundErr != nil { return refundErr } logx.WithContext(ctx).Infof("[xpay] refund local sync order_no=%s", order.OrderNo) return svcCtx.OrderModel.Trans(ctx, func(transCtx context.Context, session sqlx.Session) error { order.Status = model.OrderStatusRefunded if updateErr := svcCtx.OrderModel.UpdateWithVersion(transCtx, session, order); updateErr != nil { return updateErr } return svcCtx.AgentService.ReverseAgentSettlementOnOrderRefund(transCtx, session, order.Id) }) } func buildXpayRefundOrderID(orderNo string) string { const prefix = "RF_" id := prefix + orderNo if len(id) > 32 { id = id[:32] } if len(id) < 8 { id = id + "00000000" id = id[:8] } return id } // TryRefundOnQueryFailure 查询失败时按支付渠道退款 func TryRefundOnQueryFailure(ctx context.Context, svcCtx *svc.ServiceContext, order *model.Order) { var refundErr error switch { case model.IsXpayOrder(order): refundErr = RefundXpayQueryOrder(ctx, svcCtx, order) case order.PaymentPlatform == model.PaymentPlatformWechat: refundErr = svcCtx.WechatPayService.WeChatRefund(ctx, order.OrderNo, order.Amount, order.Amount) default: refund, err := svcCtx.AlipayService.AliRefund(ctx, order.OrderNo, order.Amount) if err != nil { refundErr = err } else if !refund.IsSuccess() { refundErr = fmt.Errorf("支付宝退款失败: %s", refund.Msg) } else { transErr := svcCtx.OrderModel.Trans(ctx, func(transCtx context.Context, session sqlx.Session) error { order.Status = model.OrderStatusRefunded if err := svcCtx.OrderModel.UpdateWithVersion(transCtx, session, order); err != nil { return err } return svcCtx.AgentService.ReverseAgentSettlementOnOrderRefund(transCtx, session, order.Id) }) if transErr != nil { refundErr = transErr } } } if refundErr != nil { logx.WithContext(ctx).Errorf("[refund] 查询失败自动退款未成功 order_no=%s platform=%s err=%v", order.OrderNo, order.PaymentPlatform, refundErr) } }