85 lines
2.9 KiB
Go
85 lines
2.9 KiB
Go
package payment
|
|
|
|
import (
|
|
"fmt"
|
|
"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 payment_provider.PaymentRequest
|
|
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.PaymentMethod)
|
|
if err != nil {
|
|
receiver.logger.Error("failed to get payment provider", zap.String("paymentMethod", string(req.PaymentMethod)), zap.Error(err))
|
|
return errors.HTTP(ctx, err)
|
|
}
|
|
|
|
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)
|
|
}
|