Files
lone-services/services/payment/internal/logic/refundLogic.go
T
2026-10-07 10:38:45 +08:00

88 lines
2.3 KiB
Go

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",
})
if err != nil {
l.Errorf("refund: %v", err)
return outResponse(utils.Fail, err.Error()), nil
}
return okResponse(result), nil
}