127 lines
4.8 KiB
Go
127 lines
4.8 KiB
Go
package grpc
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
|
|
"gitea.pena/PenaSide/treasurer/internal/payment_provider"
|
|
"gitea.pena/PenaSide/treasurer/internal/utils"
|
|
"strings"
|
|
"sync"
|
|
|
|
"gitea.pena/PenaSide/treasurer/internal/errors"
|
|
"gitea.pena/PenaSide/treasurer/internal/models"
|
|
"gitea.pena/PenaSide/treasurer/internal/proto/treasurer"
|
|
"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 in 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
|
|
}
|
|
|
|
func (r *PaymentController) getProviderForPaymentMethod(method models.PaymentType) (payment_provider.PaymentProvider, errors.Error) {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
|
|
providers, exists := r.providerMap[method]
|
|
if !exists || len(providers) == 0 {
|
|
return nil, errors.NewWithMessage("no provider found for payment method", errors.ErrNotFound)
|
|
}
|
|
return providers[0], nil
|
|
}
|
|
|
|
func (r *PaymentController) createPayment(ctx context.Context, paymentType models.PaymentType, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
|
provider, err := r.getProviderForPaymentMethod(paymentType)
|
|
if err != nil {
|
|
r.logger.Error("failed to get payment provider",
|
|
zap.String("paymentMethod", string(paymentType)),
|
|
zap.Error(err))
|
|
return nil, errors.GRPC("failed to get payment provider", err)
|
|
}
|
|
|
|
request := map[string]string{
|
|
"type": string(paymentType),
|
|
"currency": in.MainSettings.Currency,
|
|
"amount": fmt.Sprintf("%d", in.MainSettings.Amount),
|
|
"callback_host_grpc": strings.Join(in.MainSettings.CallbackHostGRPC, ","),
|
|
"return_url": in.MainSettings.ReturnURL,
|
|
"user_id": in.MainSettings.UserID,
|
|
"client_ip": in.MainSettings.ClientIP,
|
|
"requisites": utils.ToJSON(yandex.Receipt{
|
|
TaxSystemCode: 2,
|
|
Customer: yandex.Customer{
|
|
FullName: in.MainSettings.Customer.FullName,
|
|
INN: in.MainSettings.Customer.INN,
|
|
Email: in.MainSettings.Customer.Email,
|
|
Phone: in.MainSettings.Customer.Phone,
|
|
},
|
|
Items: utils.ProtoItems2ReceiptItems(in.MainSettings.Items),
|
|
}),
|
|
}
|
|
link, err := provider.CreateInvoice(ctx, request)
|
|
if err != nil {
|
|
r.logger.Error("failed to create payment",
|
|
zap.String("provider", provider.GetName()),
|
|
zap.Error(err))
|
|
return nil, errors.GRPC("failed to create payment", err)
|
|
}
|
|
return &treasurer.GetPaymentLinkResponse{RedirectURL: link}, nil
|
|
}
|
|
|
|
func (r *PaymentController) GetPaymentLinkBankCard(ctx context.Context, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
|
r.logger.Info("f<GetPaymentLinkBankCard> of <PaymentController>", zap.Any("Customer", in.MainSettings.Customer))
|
|
return r.createPayment(ctx, models.PaymentTypeBankCard, in)
|
|
}
|
|
|
|
func (r *PaymentController) GetPaymentLinkYooMoney(ctx context.Context, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
|
return r.createPayment(ctx, models.PaymentTypeYoomoney, in)
|
|
}
|
|
|
|
func (r *PaymentController) GetPaymentLinkTinkoff(ctx context.Context, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
|
return r.createPayment(ctx, models.PaymentTypeTinkoff, in)
|
|
}
|
|
|
|
func (r *PaymentController) GetPaymentLinkSBP(ctx context.Context, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
|
return r.createPayment(ctx, models.PaymentTypeSBP, in)
|
|
}
|
|
|
|
func (r *PaymentController) GetPaymentLinkSberPay(ctx context.Context, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
|
return r.createPayment(ctx, models.PaymentTypeSberPay, in)
|
|
}
|
|
|
|
func (r *PaymentController) GetPaymentLinkSberbankB2B(ctx context.Context, in *treasurer.GetPaymentLinkRequest) (*treasurer.GetPaymentLinkResponse, error) {
|
|
return r.createPayment(ctx, models.PaymentTypeSberB2B, in)
|
|
}
|