package logic import ( "errors" "fusenapi/constants" "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" "fusenapi/utils/pay" "time" "context" "fusenapi/server/pay/internal/svc" "fusenapi/server/pay/internal/types" "github.com/zeromicro/go-zero/core/logx" "gorm.io/gorm" ) type OrderPaymentIntentLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewOrderPaymentIntentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *OrderPaymentIntentLogic { return &OrderPaymentIntentLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } // 处理进入前逻辑w,r // func (l *OrderPaymentIntentLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { // } // 处理逻辑后 w,r 如:重定向, resp 必须重新处理 // func (l *OrderPaymentIntentLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { // // httpx.OkJsonCtx(r.Context(), w, resp) // } func (l *OrderPaymentIntentLogic) OrderPaymentIntent(req *types.OrderPaymentIntentReq, userinfo *auth.UserInfo) (resp *basic.Response) { // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // userinfo 传入值时, 一定不为null if userinfo == nil || userinfo.UserId == 0 { return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order not found") } // 查询订单数据 orderModel := gmodel.NewFsOrderModel(l.svcCtx.MysqlConn) orderInfo, err := orderModel.FindOneBySn(l.ctx, userinfo.UserId, req.Sn) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order not found") } logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get order info") } // 校验订单状态 if *orderInfo.IsCancel == 1 { return resp.SetStatusWithMessage(basic.CodeServiceErr, "order cancelled") } // 校验地址信息 addressModel := gmodel.NewFsAddressModel(l.svcCtx.MysqlConn) _, err = addressModel.GetOne(l.ctx, req.AddressId, userinfo.UserId) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "address not found") } logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get address info") } // 校验订单支付信息 if *orderInfo.IsPayCompleted == 1 { return resp.SetStatusWithMessage(basic.CodeServiceErr, "order is pay completed") } // 判断订单状态以及该支付金额 var nowAt int64 = time.Now().Unix() var payAmount int64 if *orderInfo.Status == int64(constants.STATUS_NEW_NOT_PAY) { payAmount = *orderInfo.TotalAmount / 2 *orderInfo.DeliveryMethod = req.DeliveryMethod *orderInfo.AddressId = req.AddressId *orderInfo.PayMethod = req.PayMethod } else { payAmount = *orderInfo.TotalAmount - *orderInfo.TotalAmount/2 } payConfig := &pay.Config{} var generatePrepaymentReq = &pay.GeneratePrepaymentReq{ OrderSn: req.Sn, ProductName: "支付标题", Amount: payAmount, Currency: "eur", Quantity: 1, ProductDescription: "支付描述", } var resData types.OrderPaymentIntentRes // 事务处理 ctx := l.ctx err = l.svcCtx.MysqlConn.Transaction(func(connGorm *gorm.DB) error { // 支付记录--处理 //支付记录改为一条订单多条,分首款尾款 var payStatus int64 = 0 var orderSource int64 = 1 var payStage int64 var fspay *gmodel.FsPay newFsPayModel := gmodel.NewFsPayModel(connGorm) if *orderInfo.Status == int64(constants.STATUS_NEW_NOT_PAY) { fspay, err = newFsPayModel.GetListByOrderNumberStage(ctx, *orderInfo.Sn, 1) if err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { return err } } payStage = 1 } else { fspay, err = newFsPayModel.GetListByOrderNumberStage(ctx, *orderInfo.Sn, 2) if err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { return err } } payStage = 2 } // 支付预付--生成 if constants.PayMethod(req.PayMethod) == constants.PAYMETHOD_STRIPE { payConfig.Stripe.Key = l.svcCtx.Config.PayConfig.Stripe.Key generatePrepaymentReq.SuccessURL = l.svcCtx.Config.PayConfig.Stripe.SuccessURL generatePrepaymentReq.CancelURL = l.svcCtx.Config.PayConfig.Stripe.CancelURL } payDriver := pay.NewPayDriver(req.PayMethod, payConfig) prepaymentRes, err := payDriver.GeneratePrepayment(generatePrepaymentReq) if err != nil { return err } // 订单信息--修改 err = gmodel.NewFsOrderModel(connGorm).Update(ctx, orderInfo) if err != nil { return err } if fspay == nil { fspay = &gmodel.FsPay{ UserId: orderInfo.UserId, OrderNumber: orderInfo.Sn, CreatedAt: &nowAt, } } else { fspay.UpdatedAt = &nowAt } fspay.PayAmount = &payAmount fspay.PayStage = &payStage //fspay.TradeNo = &prepaymentRes.TradeNo fspay.PaymentMethod = &req.PayMethod fspay.OrderSource = &orderSource fspay.PayStatus = &payStatus _, err = newFsPayModel.CreateOrUpdate(ctx, fspay) if err != nil { return err } resData.RedirectUrl = prepaymentRes.URL resData.ClientSecret = prepaymentRes.ClientSecret return nil }) if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to make payment") } return resp.SetStatusWithMessage(basic.CodeOK, "success", resData) }