package yandex import ( "context" "fmt" "github.com/gofiber/fiber/v2" "net/http" "gitea.pena/PenaSide/treasurer/internal/errors" "gitea.pena/PenaSide/treasurer/internal/models" "gitea.pena/PenaSide/treasurer/internal/models/yandex" "go.uber.org/zap" ) 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 (r *YandexStatusController) SetPaymentStatusCanceled(ctx *fiber.Ctx) error { var request yandex.WebhookNotification[yandex.Payment] if err := ctx.BodyParser(&request); err != nil { r.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 := r.statusService.SetStatusCanceled(ctx.Context(), request.Object.ID) if setStatusErr != nil { r.logger.Error("failed to set canceled payment status on of ", zap.Error(setStatusErr)) return errors.HTTP(ctx, setStatusErr) } if err := r.callbackService.OnFailure(ctx.Context(), &models.Event{ Key: string(request.Event), Message: "yandex send event: payment canceled", Payment: payment, }); err != nil { r.logger.Error("failed send success callback on of ", zap.Error(err)) return errors.HTTP(ctx, err) } return ctx.SendStatus(http.StatusOK) } func (r *YandexStatusController) SetPaymentStatusSucceeded(ctx *fiber.Ctx) error { var request yandex.WebhookNotification[yandex.Payment] if err := ctx.BodyParser(&request); err != nil { r.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 := r.statusService.SetStatusSuccess(ctx.Context(), request.Object.ID) if setStatusErr != nil { r.logger.Error("failed to set success payment status on of ", zap.Error(setStatusErr)) return errors.HTTP(ctx, setStatusErr) } if err := r.callbackService.OnSuccess(ctx.Context(), &models.Event{ Key: string(request.Event), Message: "yandex send event: payment succeeded", Payment: payment, }); err != nil { r.logger.Error("failed send success callback on of ", zap.Error(err)) return errors.HTTP(ctx, err) } return ctx.SendStatus(http.StatusOK) } func (r *YandexStatusController) SetPaymentStatusWaiting(ctx *fiber.Ctx) error { var request yandex.WebhookNotification[yandex.Payment] if err := ctx.BodyParser(&request); err != nil { r.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 := r.statusService.SetStatusWaiting(ctx.Context(), request.Object.ID); err != nil { r.logger.Error("failed to set waiting payment status on of ", zap.Error(err)) return errors.HTTP(ctx, err) } return ctx.SendStatus(http.StatusOK) } func (r *YandexStatusController) SetRefundStatusSucceeded(ctx *fiber.Ctx) error { var request yandex.WebhookNotification[yandex.Payment] if err := ctx.BodyParser(&request); err != nil { r.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 := r.statusService.SetStatusRefund(ctx.Context(), request.Object.ID); err != nil { r.logger.Error("failed to set payment status refund on of ", zap.Error(err)) return errors.HTTP(ctx, err) } return ctx.SendStatus(http.StatusOK) }