treasurer/internal/controller/http_controllers/payment/payment.go
2025-06-09 16:19:07 +03:00

86 lines
3.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package payment
import (
"fmt"
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
"gitea.pena/PenaSide/treasurer/internal/payment_provider"
"github.com/gofiber/fiber/v2"
"sync"
"gitea.pena/PenaSide/treasurer/internal/errors"
"gitea.pena/PenaSide/treasurer/internal/models"
"go.uber.org/zap"
)
type PaymentControllerDeps struct {
Logger *zap.Logger
PaymentProviders []payment_provider.PaymentProvider
}
type PaymentController struct {
logger *zap.Logger
paymentProviders []payment_provider.PaymentProvider
providerMap map[models.PaymentType][]payment_provider.PaymentProvider
mu sync.RWMutex
}
func NewPaymentController(deps PaymentControllerDeps) (*PaymentController, errors.Error) {
if deps.Logger == nil {
return nil, errors.NewWithMessage("Logger is nil on <NewPaymentController>", errors.ErrInvalidArgs)
}
if len(deps.PaymentProviders) == 0 {
return nil, errors.NewWithMessage("No payment providers provided on <NewPaymentController>", errors.ErrInvalidArgs)
}
controller := &PaymentController{
logger: deps.Logger,
paymentProviders: deps.PaymentProviders,
providerMap: make(map[models.PaymentType][]payment_provider.PaymentProvider),
}
for _, provider := range deps.PaymentProviders {
for _, method := range provider.GetSupportedPaymentMethods() {
controller.providerMap[method] = append(controller.providerMap[method], provider)
}
}
return controller, nil
}
// TODO Добавить более сложную логику выбора провайдера (приоритеты, доступность и т.д.)
func (receiver *PaymentController) getProviderForPaymentMethod(method models.PaymentType) (payment_provider.PaymentProvider, errors.Error) {
receiver.mu.RLock()
defer receiver.mu.RUnlock()
providers, exists := receiver.providerMap[method]
if !exists || len(providers) == 0 {
return nil, errors.NewWithMessage("no provider found for payment method", errors.ErrNotFound)
}
return providers[0], nil
}
// обрабатывает запрос на создание платежа
func (receiver *PaymentController) CreatePayment(ctx *fiber.Ctx) error {
var req models.CreatePayment[yandex.Receipt]
if err := ctx.BodyParser(&req); err != nil {
receiver.logger.Error("failed to parse payment request", zap.Error(err))
return errors.HTTP(ctx, errors.NewWithError(fmt.Errorf("failed to parse input body: %w", err), errors.ErrInternalError))
}
provider, err := receiver.getProviderForPaymentMethod(req.Type)
if err != nil {
receiver.logger.Error("failed to get payment provider", zap.String("paymentMethod", string(req.Type)), zap.Error(err))
return errors.HTTP(ctx, err)
}
// todo потом нужно будет сделать так чтобы работало не только с yandex.Receipt
resp, err := provider.CreateInvoice(ctx.Context(), &req)
if err != nil {
receiver.logger.Error("failed to create payment", zap.String("provider", provider.GetName()), zap.Error(err))
return errors.HTTP(ctx, err)
}
return ctx.JSON(resp)
}