package callback import ( "context" "gitea.pena/PenaSide/treasurer/internal/client" "gitea.pena/PenaSide/treasurer/internal/repository" "sync" "gitea.pena/PenaSide/treasurer/internal/errors" "gitea.pena/PenaSide/treasurer/internal/models" "go.uber.org/zap" ) type Deps struct { Logger *zap.Logger CallbackClient *client.CallbackClient PaymentRepository *repository.PaymentRepository } type Service struct { logger *zap.Logger callbackClient *client.CallbackClient paymentRepository *repository.PaymentRepository } func New(deps Deps) (*Service, errors.Error) { if deps.Logger == nil { return nil, errors.NewWithMessage("logger is nil on ", errors.ErrInvalidArgs) } if deps.CallbackClient == nil { return nil, errors.NewWithMessage("CallbackClient is nil on ", errors.ErrInvalidArgs) } if deps.PaymentRepository == nil { return nil, errors.NewWithMessage("PaymentRepository is nil on ", errors.ErrInvalidArgs) } return &Service{ logger: deps.Logger, callbackClient: deps.CallbackClient, paymentRepository: deps.PaymentRepository, }, nil } func (s *Service) OnSuccess(ctx context.Context, event *models.Event) errors.Error { waitGroup := sync.WaitGroup{} mutex := sync.Mutex{} executeErrors := make([]error, 0) for _, callbackURL := range event.Payment.CallbackHostGRPC { waitGroup.Add(1) go func(url string) { defer waitGroup.Done() if err := s.callbackClient.SendOnSuccess(ctx, url, event); err != nil { s.logger.Error("failid to send callback on of ") mutex.Lock() executeErrors = append(executeErrors, err) mutex.Unlock() return } if _, err := s.paymentRepository.SetPaymentComplete(ctx, event.Payment.PaymentID); err != nil { s.logger.Error("failid to set payment complete on of ") mutex.Lock() executeErrors = append(executeErrors, err) mutex.Unlock() return } }(callbackURL) } waitGroup.Wait() if len(executeErrors) >= len(event.Payment.CallbackHostGRPC) { s.logger.Error("failid to success payment on of ", zap.Errors("errors", executeErrors)) return errors.NewWithMessage("failed to success payment: all operations failed", errors.ErrInternalError) } return nil } func (s *Service) OnFailure(ctx context.Context, event *models.Event) errors.Error { waitGroup := sync.WaitGroup{} mutex := sync.Mutex{} executeErrors := make([]error, 0) for _, callbackURL := range event.Payment.CallbackHostGRPC { waitGroup.Add(1) go func(url string) { defer waitGroup.Done() if err := s.callbackClient.SendOnFailure(ctx, url, event); err != nil { s.logger.Error("failid to send callback on of ") mutex.Lock() executeErrors = append(executeErrors, err) mutex.Unlock() return } }(callbackURL) } waitGroup.Wait() if len(executeErrors) >= len(event.Payment.CallbackHostGRPC) { s.logger.Error("failid to success payment on of ", zap.Errors("errors", executeErrors)) return errors.NewWithMessage("failed to success payment: all operations failed", errors.ErrInternalError) } return nil }