package webhook import ( "context" "fmt" "net/url" "go.uber.org/zap" "gitea.pena/PenaSide/treasurer/internal/errors" "gitea.pena/PenaSide/treasurer/internal/models" "gitea.pena/PenaSide/treasurer/internal/models/yandex" ) const ( onYandexSuccessWebhookEventKey = "e242352d-5921-44b1-99f9-d022734fe514-success" onYandexCanceledWebhookEventKey = "e242352d-5921-44b1-99f9-d022734fe514-canceled" onYandexWaitingWebhookEventKey = "e242352d-5921-44b1-99f9-d022734fe514-waiting" onYandexRefundWebhookEventKey = "e242352d-5921-44b1-99f9-d022734fe514-refund" ) type YandexWebhookClient interface { } type YandexDeps struct { Logger *zap.Logger Configuration *models.ConfigurationHTTP YandexWebhookClient YandexWebhookClient } type Yandex struct { logger *zap.Logger configuration *models.ConfigurationHTTP yandexWebhookClient YandexWebhookClient } func NewYandex(deps YandexDeps) (*Yandex, errors.Error) { if deps.Logger == nil { return nil, errors.NewWithMessage("logger is nil on ", errors.ErrInvalidArgs) } if deps.Configuration == nil { return nil, errors.NewWithMessage("Configuration is nil on ", errors.ErrInvalidArgs) } if deps.YandexWebhookClient == nil { return nil, errors.NewWithMessage("PaymentRepository is nil on ", errors.ErrInvalidArgs) } return &Yandex{ logger: deps.Logger, configuration: deps.Configuration, yandexWebhookClient: deps.YandexWebhookClient, }, nil } func (receiver *Yandex) SetOnPaymentSuccess(ctx context.Context) errors.Error { url, urlErr := url.JoinPath(receiver.configuration.Domen, "yandex", "payment", "status", "succeeded") if urlErr != nil { receiver.logger.Error("failed to join url path on of ", zap.Error(urlErr)) return errors.NewWithError(fmt.Errorf("failed to join url path: %w", urlErr), errors.ErrInternalError) } if err := receiver.SetWebhook(ctx, onYandexSuccessWebhookEventKey, &yandex.CreateWebhookRequest{ Event: yandex.WebhookEventPaymentSucceeded, URL: url, }); err != nil { receiver.logger.Error("failed to set webhook on of ", zap.Error(err)) return err } return nil } func (receiver *Yandex) SetOnPaymentCanceled(ctx context.Context) errors.Error { url, urlErr := url.JoinPath(receiver.configuration.Domen, "yandex", "payment", "status", "canceled") if urlErr != nil { receiver.logger.Error("failed to join url path on of ", zap.Error(urlErr)) return errors.NewWithError(fmt.Errorf("failed to join url path: %w", urlErr), errors.ErrInternalError) } if err := receiver.SetWebhook(ctx, onYandexCanceledWebhookEventKey, &yandex.CreateWebhookRequest{ Event: yandex.WebhookEventPaymentCanceled, URL: url, }); err != nil { receiver.logger.Error("failed to set webhook on of ", zap.Error(err)) return err } return nil } func (receiver *Yandex) SetOnPaymentWaiting(ctx context.Context) errors.Error { url, urlErr := url.JoinPath(receiver.configuration.Domen, "yandex", "payment", "status", "waiting") if urlErr != nil { receiver.logger.Error("failed to join url path on of ", zap.Error(urlErr)) return errors.NewWithError(fmt.Errorf("failed to join url path: %w", urlErr), errors.ErrInternalError) } if err := receiver.SetWebhook(ctx, onYandexWaitingWebhookEventKey, &yandex.CreateWebhookRequest{ Event: yandex.WebhookEventPaymentWaiting, URL: url, }); err != nil { receiver.logger.Error("failed to set webhook on of ", zap.Error(err)) return err } return nil } func (receiver *Yandex) SetOnPaymentRefund(ctx context.Context) errors.Error { url, urlErr := url.JoinPath(receiver.configuration.Domen, "yandex", "refund", "status", "canceled") if urlErr != nil { receiver.logger.Error("failed to join url path on of ", zap.Error(urlErr)) return errors.NewWithError(fmt.Errorf("failed to join url path: %w", urlErr), errors.ErrInternalError) } if err := receiver.SetWebhook(ctx, onYandexRefundWebhookEventKey, &yandex.CreateWebhookRequest{ Event: yandex.WebhookEventRefundSucceeded, URL: url, }); err != nil { receiver.logger.Error("failed to set webhook on of ", zap.Error(err)) return err } return nil } func (receiver *Yandex) SetWebhook(ctx context.Context, idempotenceKey string, request *yandex.CreateWebhookRequest) errors.Error { webhook, err := receiver.GetWebhookByType(ctx, request.Event) if err != nil && err.Type() != errors.ErrNotFound { receiver.logger.Error("failed to get webhook on of ", zap.Error(err)) return err } if webhook != nil { receiver.logger.Error("webhook already exist on of ") return errors.NewWithError( fmt.Errorf("yandex webhook with type <%s> already exist", request.Event), errors.ErrConflict, ) } // if _, err := receiver.yandexWebhookClient.SetWebhookEvent(ctx, idempotenceKey, request); err != nil { // receiver.logger.Error("failed to set webhook on of ", zap.Error(err)) // return err // } return nil } func (receiver *Yandex) GetWebhookByType(ctx context.Context, event yandex.WebhookEventType) (*yandex.Webhook, errors.Error) { // webhooks, err := receiver.yandexWebhookClient.GetWebhookEvents(ctx) // if err != nil { // receiver.logger.Error("failed to get webhooks list on of ", zap.Error(err)) // return nil, err // } // if len(webhooks) < 1 { // receiver.logger.Error("empty webhooks on of ") // return nil, errors.NewWithMessage("webhooks empty in yandex server", errors.ErrNotFound) // } // // webhook := array.Find(webhooks, func(webhook yandex.Webhook, _ int, _ []yandex.Webhook) bool { // return webhook.Event == event // }) // if webhook == nil { // receiver.logger.Error("webhook not found on of ", zap.Error(err), zap.String("event", string(event))) // return nil, errors.NewWithError(fmt.Errorf("yandex webhook not found with <%s> event", event), errors.ErrNotFound) // } return nil, nil } func (receiver *Yandex) UnsetWebhook(ctx context.Context, event yandex.WebhookEventType) errors.Error { _, err := receiver.GetWebhookByType(ctx, event) if err != nil { receiver.logger.Error("failed to get webhook on of ", zap.Error(err), zap.String("event", string(event))) return err } // if err := receiver.yandexWebhookClient.DeleteWebhook(ctx, webhook.ID); err != nil { // receiver.logger.Error("failed to delete webhook on of ", zap.Error(err), zap.String("id", webhook.ID)) // return err // } return nil }