added logic for create invoice

This commit is contained in:
Pasha 2025-07-22 14:16:36 +03:00
parent 570b1c0d2e
commit 330d8753e0
3 changed files with 68 additions and 17 deletions

@ -30,8 +30,9 @@ type Payment struct {
*/
CallbackHostGRPC []string `json:"callbackHostGrpc" bson:"callbackHostGrpc"`
WalletAddress string `json:"walletAddress" bson:"walletAddress"` // for crypto
CryptoAmount float64 `json:"cryptoAmount" bson:"cryptoAmount"` // for crypto
ToWalletAddress string `json:"toWalletAddress" bson:"toWalletAddress"` // for crypto our
FromWalletAddress string `json:"fromWalletAddress" bson:"fromWalletAddress"` // for crypto them
CryptoAmount float64 `json:"cryptoAmount" bson:"cryptoAmount"` // for crypto
}
func (p *Payment) Sanitize() *Payment {

@ -9,6 +9,9 @@ import (
"gitea.pena/PenaSide/treasurer/internal/repository"
"github.com/gofiber/fiber/v2"
"go.uber.org/zap"
"strconv"
"strings"
"time"
)
const ProviderName = "alchemy"
@ -44,9 +47,49 @@ func (p *Provider) GetSupportedPaymentMethods() []models.PaymentType {
return []models.PaymentType{models.PaymentTypeAlchemy}
}
// todo
func (p *Provider) CreateInvoice(ctx context.Context, req map[string]string) (string, errors.Error) {
return "", nil
amountStr := req["cryptoAmount"]
fromWallet := req["fromWalletAddress"]
if amountStr == "" || fromWallet == "" {
p.logger.Error("amount or fromWallet address is empty", zap.String("fromWalletAddress", fromWallet), zap.String("cryptoAmount", amountStr))
return "", errors.NewWithMessage("cryptoAmount and fromWalletAddress required", errors.ErrInvalidArgs)
}
cryptoAmount, err := strconv.ParseFloat(amountStr, 64)
if err != nil {
p.logger.Error("failed to parse cryptoAmount from wallet address", zap.Error(err))
return "", errors.NewWithMessage("invalid cryptoAmount", errors.ErrInvalidArgs)
}
now := time.Now()
payment := &models.Payment{
UserID: req["user_id"],
ClientIP: req["client_ip"],
Currency: req["currency"],
Type: models.PaymentType(req["type"]),
Status: models.PaymentStatusWaiting,
Completed: false,
IsDeleted: false,
CreatedAt: now,
UpdatedAt: now,
ToWalletAddress: p.config.WalletAddress,
FromWalletAddress: fromWallet,
CryptoAmount: cryptoAmount,
}
var callbackHosts []string
if val, ok := req["callback_host_grpc"]; ok && val != "" {
callbackHosts = strings.Split(val, ",")
}
payment.CallbackHostGRPC = callbackHosts
_, err = p.repository.Insert(ctx, payment)
if err != nil {
p.logger.Error("failed to insert payment into database", zap.Error(err))
return "", errors.NewWithMessage(fmt.Sprintf("failed to insert payment into database: %v", err), errors.ErrInternalError)
}
return p.config.WalletAddress, nil
}
func (p *Provider) RegisterWebhookHandlers(router fiber.Router) {
@ -63,7 +106,7 @@ func (p *Provider) handleWebhook(ctx *fiber.Ctx) error {
if act.ToAddress != p.config.WalletAddress {
continue
}
payment, err := p.repository.FindByWalletAddressAndAmount(ctx.Context(), act.FromAddress, act.Value)
payment, err := p.repository.FindByWalletsAndAmount(ctx.Context(), act.ToAddress, act.FromAddress, act.Value)
if err != nil {
if err.Type() == errors.ErrNotFound {
return ctx.Status(fiber.StatusNotFound).SendString(fmt.Sprintf("payment not found: %s", err.Error()))

@ -32,8 +32,10 @@ var PaymentFields = struct {
RawPaymentBody string
CallbackHostGRPC string
WalletAddress string // for crypto
CryptoAmount string // for crypto
WalletAddress string // for crypto
CryptoAmount string // for crypto
ToWalletAddress string
FromWalletAddress string
}{
ID: "_id",
UserID: "userId",
@ -52,8 +54,10 @@ var PaymentFields = struct {
RawPaymentBody: "rawPaymentBody",
CallbackHostGRPC: "callbackHostGrpc",
WalletAddress: "walletAddress",
CryptoAmount: "cryptoAmount",
WalletAddress: "walletAddress",
CryptoAmount: "cryptoAmount",
ToWalletAddress: "toWalletAddress",
FromWalletAddress: "fromWalletAddress",
}
type PaymentRepositoryDeps struct {
@ -163,22 +167,25 @@ func (r *PaymentRepository) SetPaymentStatus(ctx context.Context, paymentID stri
return &payment, nil
}
func (r *PaymentRepository) FindByWalletAddressAndAmount(ctx context.Context, walletAddress string, cryptoAmount float64) (*models.Payment, errors.Error) {
func (r *PaymentRepository) FindByWalletsAndAmount(ctx context.Context, toWalletAddress, fromWalletAddress string, cryptoAmount float64) (*models.Payment, errors.Error) {
payment := models.Payment{}
filter := bson.M{
PaymentFields.WalletAddress: walletAddress,
PaymentFields.CryptoAmount: cryptoAmount,
PaymentFields.Completed: false, //не завершённые
PaymentFields.ToWalletAddress: toWalletAddress,
PaymentFields.FromWalletAddress: fromWalletAddress,
PaymentFields.CryptoAmount: cryptoAmount,
PaymentFields.Completed: false,
PaymentFields.Status: models.PaymentStatusWaiting,
}
if err := r.collection.FindOne(ctx, filter).Decode(&payment); err != nil {
r.logger.Error("failed to find payment by walletAddress and amount on <FindByWalletAddressAndAmount> of <PaymentRepository>",
r.logger.Error("failed to find payment by wallets and amount on <FindByWalletsAndAmount> of <PaymentRepository>",
zap.Error(err),
zap.String("walletAddress", walletAddress),
zap.Float64("amount", cryptoAmount),
zap.String("toWalletAddress", toWalletAddress),
zap.String("fromWalletAddress", fromWalletAddress),
zap.Float64("cryptoAmount", cryptoAmount),
)
findErr := errors.NewWithError(
fmt.Errorf("failed to find payment by walletAddress and amount: %w", err),
fmt.Errorf("failed to find payment by wallets and amount: %w", err),
errors.ErrInternalError,
)