treasurer/internal/payment_provider/alchemy/provider.go

80 lines
2.2 KiB
Go

package alchemy
import (
"context"
"fmt"
"gitea.pena/PenaSide/treasurer/internal/errors"
"gitea.pena/PenaSide/treasurer/internal/models"
"gitea.pena/PenaSide/treasurer/internal/models/alchemy"
"gitea.pena/PenaSide/treasurer/internal/repository"
"github.com/gofiber/fiber/v2"
"go.uber.org/zap"
)
const ProviderName = "alchemy"
type Config struct {
WalletAddress string `json:"walletAddress"`
}
type Provider struct {
repository *repository.PaymentRepository
logger *zap.Logger
config *Config
}
type Deps struct {
Repository *repository.PaymentMethodRepository
Logger *zap.Logger
Config *Config
}
func New(deps Deps) *Provider {
return &Provider{
logger: deps.Logger,
config: deps.Config,
}
}
func (p *Provider) GetName() string {
return ProviderName
}
func (p *Provider) GetSupportedPaymentMethods() []models.PaymentType {
return []models.PaymentType{models.PaymentTypeAlchemy}
}
func (p *Provider) CreateInvoice(ctx context.Context, req map[string]string) (string, errors.Error) {
return "", nil
}
func (p *Provider) RegisterWebhookHandlers(router fiber.Router) {
router.Post("/webhook/alchemy", p.handleWebhook)
}
func (p *Provider) handleWebhook(ctx *fiber.Ctx) error {
var payload alchemy.AlchemyAddressActivityWebhook
if err := ctx.BodyParser(&payload); err != nil {
return ctx.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("failed to parse Alchemy webhook: %s", err.Error()))
}
for _, act := range payload.Event.Activity {
if act.ToAddress != p.config.WalletAddress {
continue
}
amountStr := fmt.Sprintf("%v", act.Value)
payment, err := p.repository.FindByWalletAddressAndAmount(ctx.Context(), act.FromAddress, amountStr)
if err != nil {
if err.Type() == errors.ErrNotFound {
return ctx.Status(fiber.StatusNotFound).SendString(fmt.Sprintf("payment not found: %s", err.Error()))
}
return ctx.Status(fiber.StatusInternalServerError).SendString(fmt.Sprintf("internal error while searching payment: %s", err.Error()))
}
_, err = p.repository.SetPaymentComplete(ctx.Context(), payment.PaymentID)
if err != nil {
return ctx.Status(fiber.StatusInternalServerError).SendString(fmt.Sprintf("failed to set payment complete: %s", err.Error()))
}
}
return ctx.SendStatus(fiber.StatusOK)
}