138 lines
5.6 KiB
Go
138 lines
5.6 KiB
Go
![]() |
package rest
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"net/http"
|
||
|
|
||
|
"github.com/labstack/echo/v4"
|
||
|
"go.uber.org/zap"
|
||
|
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/errors"
|
||
|
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models"
|
||
|
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/models/yandex"
|
||
|
"penahub.gitlab.yandexcloud.net/external/treasurer/internal/utils/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 <NewYandexStatusController>", errors.ErrInvalidArgs)
|
||
|
}
|
||
|
|
||
|
if deps.StatusService == nil {
|
||
|
return nil, errors.NewWithMessage("StatusService is nil on <NewYandexStatusController>", errors.ErrInvalidArgs)
|
||
|
}
|
||
|
|
||
|
if deps.CallbackService == nil {
|
||
|
return nil, errors.NewWithMessage("CallbackService is nil on <NewYandexStatusController>", errors.ErrInvalidArgs)
|
||
|
}
|
||
|
|
||
|
return &YandexStatusController{
|
||
|
logger: deps.Logger,
|
||
|
statusService: deps.StatusService,
|
||
|
}, 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 <SetPaymentStatusCanceled> of <YandexStatusController>", 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 <SetPaymentStatusCanceled> of <YandexStatusController>", 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 <SetPaymentStatusSucceeded> of <YandexStatusController>", zap.Error(err))
|
||
|
return errors.HTTP(ctx, err)
|
||
|
}
|
||
|
|
||
|
return ctx.JSON(http.StatusOK, nil)
|
||
|
}
|
||
|
|
||
|
func (receiver *YandexStatusController) SetPaymentStatusSucceeded(ctx echo.Context) error {
|
||
|
request, err := echotools.Bind[yandex.WebhookNotification[yandex.Payment]](ctx)
|
||
|
if err != nil {
|
||
|
receiver.logger.Error("failed to parse body on <SetPaymentStatusSucceeded> of <YandexStatusController>", zap.Error(err))
|
||
|
return errors.HTTP(ctx, errors.NewWithError(fmt.Errorf("failed to parse input body: %w", err), errors.ErrInternalError))
|
||
|
}
|
||
|
|
||
|
payment, setStatusErr := receiver.statusService.SetStatusSuccess(ctx.Request().Context(), request.Object.ID)
|
||
|
if setStatusErr != nil {
|
||
|
receiver.logger.Error("failed to set success payment status on <SetPaymentStatusSucceeded> of <YandexStatusController>", zap.Error(setStatusErr))
|
||
|
return errors.HTTP(ctx, 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 <SetPaymentStatusSucceeded> of <YandexStatusController>", 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 <SetPaymentStatusWaiting> of <YandexStatusController>", 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 <SetPaymentStatusWaiting> of <YandexStatusController>", 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 <SetRefundStatusSucceeded> of <YandexStatusController>", 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 <SetRefundStatusSucceeded> of <YandexStatusController>", zap.Error(err))
|
||
|
return errors.HTTP(ctx, err)
|
||
|
}
|
||
|
|
||
|
return ctx.JSON(http.StatusOK, nil)
|
||
|
}
|