Files
lone-services/services/payment/internal/logic/payLogic.go
T
zzw 851348ed5c
CI / changes (push) Successful in 37s
CI / ad (push) Successful in 1s
CI / admin (push) Successful in 0s
CI / bff (push) Successful in 23s
CI / chore (push) Successful in 0s
CI / equipment (push) Successful in 0s
CI / express (push) Successful in 1s
CI / factory (push) Successful in 0s
CI / message (push) Successful in 0s
CI / order (push) Successful in 1s
CI / payment (push) Successful in 33s
CI / product (push) Successful in 0s
CI / record (push) Successful in 0s
CI / sale (push) Successful in 0s
CI / support (push) Successful in 0s
CI / task (push) Successful in 0s
CI / user (push) Successful in 18s
CI / wecom (push) Successful in 0s
feat: payment
2026-10-05 15:29:19 +08:00

105 lines
2.8 KiB
Go

package logic
import (
"context"
"math"
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 PayLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewPayLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PayLogic {
return &PayLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
func (l *PayLogic) Pay(in *payment.PayReq) (*payment.Response, error) {
if in == nil || in.OrderSn == utils.StringEmpty {
return failResponse(utils.ErrorParams), nil
}
loginUser := utils.GetUserFromCtx(l.ctx)
if loginUser.ID < utils.NumberOne {
return failResponse(utils.ErrorNoLoginInfo), nil
}
client := resolveClient(in.Client, loginUser.ClientCode)
channelCode := resolveChannel(in.Channel)
orderInfo, err := getOrderInfo(l.ctx, l.svcCtx.OrderSvcName, loginUser.ID, in.OrderSn, loginUser.Type)
if err != nil {
l.Errorf("pay load order: %v", err)
return failResponse(utils.ErrorNotFund), nil
}
if orderPayStatus(orderInfo) == dao.PayStatusOk {
return &payment.Response{
Code: int32(utils.ErrorRepeatPayment.GetCode()),
Msg: utils.ErrorRepeatPayment.GetMsg(),
}, nil
}
status := orderPayStatus(orderInfo)
if status != dao.PayStatusWait && status != dao.PayStatusIn && status != dao.PayStatusFail {
return outResponse(utils.Fail, "订单状态不可支付"), nil
}
amountFen := yuanToFen(orderInfo.PayPrice)
if amountFen <= 0 {
return outResponse(utils.Fail, "支付金额无效"), nil
}
ch, err := channel.Get(channelCode, client)
if err != nil {
l.Errorf("pay channel: %v", err)
return outResponse(utils.Fail, err.Error()), nil
}
prepayReq := &pkgpay.PrepayRequest{
OutTradeNo: in.OrderSn,
Description: "订单支付",
AmountFen: amountFen,
Currency: "CNY",
Attach: in.OrderSn,
}
switch channelCode {
case pkgpay.ChannelWechat:
openid, oErr := loadOpenID(l.ctx, l.svcCtx.UserSvcName, loginUser.ID)
if oErr != nil || openid == utils.StringEmpty {
l.Errorf("pay openid: %v", oErr)
return outResponse(utils.Fail, "未绑定微信openid"), nil
}
prepayReq.OpenID = openid
case pkgpay.ChannelAlipay, pkgpay.ChannelBank:
return outResponse(utils.Fail, "支付渠道暂未开通"), nil
}
result, err := ch.Prepay(l.ctx, client, prepayReq)
if err != nil {
l.Errorf("pay prepay: %v", err)
return outResponse(utils.Fail, err.Error()), nil
}
_ = updateOrderPayStatus(l.ctx, l.svcCtx.OrderSvcName, in.OrderSn, dao.PayStatusIn, 0, in.OrderSn, loginUser.Type)
return okResponse(result), nil
}
func yuanToFen(yuan float64) int64 {
return int64(math.Round(yuan * 100))
}