package logic import ( "context" "fmt" "strconv" "time" pkgpay "lone-services/pkg/payment" "lone-services/pkg/utils" payment "lone-services/rpc/payment/pb" "lone-services/services/payment/internal/channel" "lone-services/services/payment/internal/dao" "lone-services/services/payment/internal/svc" "github.com/zeromicro/go-zero/core/logx" ) type RefundLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger } func NewRefundLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RefundLogic { return &RefundLogic{ ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx), } } func (l *RefundLogic) Refund(in *payment.RefundReq) (*payment.Response, error) { if in == nil || in.OrderSn == utils.StringEmpty || in.Amount == utils.StringEmpty { return failResponse(utils.ErrorParams), nil } loginUser := utils.GetUserFromCtx(l.ctx) if loginUser.ID < utils.NumberOne { return failResponse(utils.ErrorNoLoginInfo), nil } channelCode := resolveChannel(in.Channel) client := resolveClient(utils.StringEmpty, loginUser.ClientCode) orderInfo, err := getOrderInfo(l.ctx, l.svcCtx.OrderSvcName, loginUser.ID, in.OrderSn, loginUser.Type) if err != nil { l.Errorf("get order info: %v", err) return failResponse(utils.ErrorNotFund), nil } if orderPayStatus(orderInfo) != dao.PayStatusOk { return outResponse(utils.Fail, "订单未支付,无法退款"), nil } refundYuan, err := strconv.ParseFloat(in.Amount, 64) if err != nil || refundYuan <= 0 { return failResponse(utils.ErrorParams), nil } refundFen := yuanToFen(refundYuan) totalFen := yuanToFen(orderInfo.PayPrice) if refundFen > totalFen { return outResponse(utils.Fail, "退款金额不能大于支付金额"), nil } ch, err := channel.Get(channelCode, client) if err != nil { return outResponse(utils.Fail, err.Error()), nil } outTradeNo := orderOutTradeNo(orderInfo) outRefundNo := fmt.Sprintf("RF%s%d", orderInfo.OrderSn, time.Now().UnixNano()) result, err := ch.Refund(l.ctx, &pkgpay.RefundRequest{ OutTradeNo: outTradeNo, OutRefundNo: outRefundNo, Reason: in.Reason, RefundFen: refundFen, TotalFen: totalFen, Currency: "CNY", }) fmt.Println("outTradeNo", outTradeNo, "outRefundNo", outRefundNo) if err != nil { l.Errorf("refund: %v", err) return outResponse(utils.Fail, err.Error()), nil } return okResponse(result), nil }