package payment import ( "context" "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" ) type YandexPaymentClient interface { CreatePaymentPhone(ctx context.Context, idempotenceKey string, request *yandex.CreatePaymentRequest[yandex.PaymentMethodPhone]) (*yandex.Payment, errors.Error) CreatePayment(ctx context.Context, idempotenceKey string, request *yandex.CreatePaymentRequest[yandex.PaymentMethodType]) (*yandex.Payment, errors.Error) CreatePaymentBankCard(ctx context.Context, idempotenceKey string, request *yandex.CreatePaymentRequest[yandex.PaymentMethodBankCard]) (*yandex.Payment, errors.Error) CreatePaymentB2B(ctx context.Context, idempotenceKey string, request *yandex.CreatePaymentRequest[yandex.PaymentMethodB2B]) (*yandex.Payment, errors.Error) CreatePaymentLogin(ctx context.Context, idempotenceKey string, request *yandex.CreatePaymentRequest[yandex.PaymentMethodLogin]) (*yandex.Payment, errors.Error) } type YandexPaymentServiceDeps struct { Logger *zap.Logger YandexPaymentClient YandexPaymentClient } type Yandex struct { logger *zap.Logger yandexPaymentClient YandexPaymentClient } func NewYandex(deps YandexPaymentServiceDeps) (*Yandex, errors.Error) { if deps.Logger == nil { return nil, errors.NewWithMessage("logger is nil on ", errors.ErrInvalidArgs) } if deps.YandexPaymentClient == nil { return nil, errors.NewWithMessage("YandexPaymentClient is nil on ", errors.ErrInvalidArgs) } return &Yandex{ logger: deps.Logger, yandexPaymentClient: deps.YandexPaymentClient, }, nil } func (receiver *Yandex) CreatePaymentPhone(ctx context.Context, uuid string, request *models.CreatePayment[string]) (*models.CreatePaymentResult, errors.Error) { yandexPayment, err := receiver.yandexPaymentClient.CreatePaymentPhone(ctx, uuid, &yandex.CreatePaymentRequest[yandex.PaymentMethodPhone]{ Amount: yandex.Amount{ Value: utils.ConvertAmountToStringFloat(request.Amount), Currency: request.Currency, }, PaymentMethodData: &yandex.PaymentMethodPhone{ Type: models.YandexPaymentTypeMap[request.Type], Phone: request.Requisites, }, Confirmation: &yandex.CreateConfirmationRedirect{ Type: yandex.ConfirmationTypeRedirect, Locale: "ru_RU", ReturnURL: request.ReturnURL, Enforce: true, }, Capture: true, ClientIP: request.ClientIP, }) if err != nil { receiver.logger.Error("failed to create payment on of ", zap.Error(err)) return nil, err } return &models.CreatePaymentResult{ Payment: &models.Payment{ UserID: request.UserID, PaymentID: yandexPayment.ID, ClientIP: request.ClientIP, Currency: request.Currency, IdempotencePaymentID: uuid, Amount: request.Amount, Type: request.Type, Status: models.PaymentStatusMap[string(yandexPayment.Status)], Completed: false, RawPaymentBody: yandexPayment, CallbackHostGRPC: request.CallbackHostGRPC, }, RedirectURL: yandexPayment.Confirmation.ConfirmationURL, }, nil } func (receiver *Yandex) CreatePaymentBankCard(ctx context.Context, uuid string, request *models.CreatePayment[*models.BankCard]) (*models.CreatePaymentResult, errors.Error) { yandexPayment, err := receiver.yandexPaymentClient.CreatePaymentBankCard(ctx, uuid, &yandex.CreatePaymentRequest[yandex.PaymentMethodBankCard]{ Amount: yandex.Amount{ Value: utils.ConvertAmountToStringFloat(request.Amount), Currency: request.Currency, }, PaymentMethodData: &yandex.PaymentMethodBankCard{ Type: models.YandexPaymentTypeMap[request.Type], Card: &yandex.BankCardInformation{ Number: request.Requisites.Number, ExpiryYear: request.Requisites.ExpiryYear, ExpiryMonth: request.Requisites.ExpiryMonth, }, }, Confirmation: &yandex.CreateConfirmationRedirect{ Type: yandex.ConfirmationTypeRedirect, Locale: "ru_RU", ReturnURL: request.ReturnURL, Enforce: true, }, Capture: true, ClientIP: request.ClientIP, }) if err != nil { receiver.logger.Error("failed to create payment on of ", zap.Error(err)) return nil, err } return &models.CreatePaymentResult{ Payment: &models.Payment{ UserID: request.UserID, PaymentID: yandexPayment.ID, IdempotencePaymentID: uuid, ClientIP: request.ClientIP, Currency: request.Currency, Amount: request.Amount, Type: request.Type, Status: models.PaymentStatusMap[string(yandexPayment.Status)], Completed: false, RawPaymentBody: yandexPayment, CallbackHostGRPC: request.CallbackHostGRPC, }, RedirectURL: yandexPayment.Confirmation.ConfirmationURL, }, nil } func (receiver *Yandex) CreatePayment(ctx context.Context, uuid string, request *models.CreatePayment[*any]) (*models.CreatePaymentResult, errors.Error) { yandexPayment, err := receiver.yandexPaymentClient.CreatePayment(ctx, uuid, &yandex.CreatePaymentRequest[yandex.PaymentMethodType]{ Amount: yandex.Amount{ Value: utils.ConvertAmountToStringFloat(request.Amount), Currency: request.Currency, }, PaymentMethodData: &yandex.PaymentMethodType{Type: models.YandexPaymentTypeMap[request.Type]}, Confirmation: &yandex.CreateConfirmationRedirect{ Type: yandex.ConfirmationTypeRedirect, Locale: "ru_RU", ReturnURL: request.ReturnURL, Enforce: true, }, Capture: true, ClientIP: request.ClientIP, }) if err != nil { receiver.logger.Error("failed to create payment on of ", zap.Error(err)) return nil, err } return &models.CreatePaymentResult{ Payment: &models.Payment{ UserID: request.UserID, PaymentID: yandexPayment.ID, IdempotencePaymentID: uuid, ClientIP: request.ClientIP, Currency: request.Currency, Amount: request.Amount, Type: request.Type, Status: models.PaymentStatusMap[string(yandexPayment.Status)], Completed: false, RawPaymentBody: yandexPayment, CallbackHostGRPC: request.CallbackHostGRPC, }, RedirectURL: yandexPayment.Confirmation.ConfirmationURL, }, nil } func (receiver *Yandex) CreatePaymentLogin(ctx context.Context, uuid string, request *models.CreatePayment[string]) (*models.CreatePaymentResult, errors.Error) { yandexPayment, err := receiver.yandexPaymentClient.CreatePaymentLogin(ctx, uuid, &yandex.CreatePaymentRequest[yandex.PaymentMethodLogin]{ Amount: yandex.Amount{ Value: utils.ConvertAmountToStringFloat(request.Amount), Currency: request.Currency, }, PaymentMethodData: &yandex.PaymentMethodLogin{ Type: models.YandexPaymentTypeMap[request.Type], Login: request.Requisites, }, Confirmation: &yandex.CreateConfirmationRedirect{ Type: yandex.ConfirmationTypeRedirect, Locale: "ru_RU", ReturnURL: request.ReturnURL, Enforce: true, }, Capture: true, ClientIP: request.ClientIP, }) if err != nil { receiver.logger.Error("failed to create payment on of ", zap.Error(err)) return nil, err } return &models.CreatePaymentResult{ Payment: &models.Payment{ UserID: request.UserID, PaymentID: yandexPayment.ID, IdempotencePaymentID: uuid, ClientIP: request.ClientIP, Currency: request.Currency, Amount: request.Amount, Type: request.Type, Status: models.PaymentStatusMap[string(yandexPayment.Status)], Completed: false, RawPaymentBody: yandexPayment, CallbackHostGRPC: request.CallbackHostGRPC, }, RedirectURL: yandexPayment.Confirmation.ConfirmationURL, }, nil }