package rest import ( "context" "fmt" "net/http" "github.com/labstack/echo/v4" "go.uber.org/zap" "gitea.pena/PenaSide/treasurer/internal/errors" "gitea.pena/PenaSide/treasurer/internal/models" "gitea.pena/PenaSide/treasurer/internal/models/yandex" "gitea.pena/PenaSide/treasurer/pkg/echotools" ) type StatusService interface { SetStatusCanceled(context.Context, string) (*models.Payment, errors.Error) SetStatusSuccess(context.Context, string) (*models.Payment, errors.Error) SetStatusWaiting(context.Context, string) (*models.Payment, errors.Error) SetStatusRefund(context.Context, string) (*models.Payment, errors.Error) } type CallbackService interface { OnSuccess(context.Context, *models.Event) errors.Error OnFailure(context.Context, *models.Event) errors.Error } type YandexStatusControllerDeps struct { Logger *zap.Logger StatusService StatusService CallbackService CallbackService } type YandexStatusController struct { logger *zap.Logger statusService StatusService callbackService CallbackService } func NewYandexStatusController(deps YandexStatusControllerDeps) (*YandexStatusController, errors.Error) { if deps.Logger == nil { return nil, errors.NewWithMessage("logger is nil on ", errors.ErrInvalidArgs) } if deps.StatusService == nil { return nil, errors.NewWithMessage("StatusService is nil on ", errors.ErrInvalidArgs) } if deps.CallbackService == nil { return nil, errors.NewWithMessage("CallbackService is nil on ", errors.ErrInvalidArgs) } return &YandexStatusController{ logger: deps.Logger, statusService: deps.StatusService, callbackService: deps.CallbackService, }, nil } func (receiver *YandexStatusController) SetPaymentStatusCanceled(ctx echo.Context) error { request, err := echotools.Bind[yandex.WebhookNotification[yandex.Payment]](ctx) if err != nil { receiver.logger.Error("failed to parse body on of ", zap.Error(err)) return errors.HTTP(ctx, errors.NewWithError(fmt.Errorf("failed to parse input body: %w", err), errors.ErrInternalError)) } payment, setStatusErr := receiver.statusService.SetStatusCanceled(ctx.Request().Context(), request.Object.ID) if setStatusErr != nil { receiver.logger.Error("failed to set canceled payment status on of ", zap.Error(setStatusErr)) return errors.HTTP(ctx, setStatusErr) } if err := receiver.callbackService.OnFailure(ctx.Request().Context(), &models.Event{ Key: string(request.Event), Message: "yandex send event: payment canceled", Payment: payment, }); err != nil { receiver.logger.Error("failed send success callback on of ", zap.Error(err)) return errors.HTTP(ctx, err) } return ctx.JSON(http.StatusOK, nil) } func (receiver *YandexStatusController) SetPaymentStatusSucceeded(ctx echo.Context) error { fmt.Println("SUUUUUUUUUUUU0") request, err := echotools.Bind[yandex.WebhookNotification[yandex.Payment]](ctx) if err != nil { receiver.logger.Error("failed to parse body on of ", zap.Error(err)) return errors.HTTP(ctx, errors.NewWithError(fmt.Errorf("failed to parse input body: %w", err), errors.ErrInternalError)) } fmt.Println("SUUUUUUUUUUUU1", request) payment, setStatusErr := receiver.statusService.SetStatusSuccess(ctx.Request().Context(), request.Object.ID) if setStatusErr != nil { receiver.logger.Error("failed to set success payment status on of ", zap.Error(setStatusErr)) return errors.HTTP(ctx, setStatusErr) } fmt.Println("SUUUUUUUUUUUU2", payment, setStatusErr) if err := receiver.callbackService.OnSuccess(ctx.Request().Context(), &models.Event{ Key: string(request.Event), Message: "yandex send event: payment succeeded", Payment: payment, }); err != nil { receiver.logger.Error("failed send success callback on of ", zap.Error(err)) return errors.HTTP(ctx, err) } return ctx.JSON(http.StatusOK, nil) } func (receiver *YandexStatusController) SetPaymentStatusWaiting(ctx echo.Context) error { request, err := echotools.Bind[yandex.WebhookNotification[yandex.Payment]](ctx) if err != nil { receiver.logger.Error("failed to parse body on of ", zap.Error(err)) return errors.HTTP(ctx, errors.NewWithError(fmt.Errorf("failed to parse input body: %w", err), errors.ErrInternalError)) } if _, err := receiver.statusService.SetStatusWaiting(ctx.Request().Context(), request.Object.ID); err != nil { receiver.logger.Error("failed to set waiting payment status on of ", zap.Error(err)) return errors.HTTP(ctx, err) } return ctx.JSON(http.StatusOK, nil) } func (receiver *YandexStatusController) SetRefundStatusSucceeded(ctx echo.Context) error { request, err := echotools.Bind[yandex.WebhookNotification[yandex.Payment]](ctx) if err != nil { receiver.logger.Error("failed to parse body on of ", zap.Error(err)) return errors.HTTP(ctx, errors.NewWithError(fmt.Errorf("failed to parse input body: %w", err), errors.ErrInternalError)) } if _, err := receiver.statusService.SetStatusRefund(ctx.Request().Context(), request.Object.ID); err != nil { receiver.logger.Error("failed to set payment status refund on of ", zap.Error(err)) return errors.HTTP(ctx, err) } return ctx.JSON(http.StatusOK, nil) }