package payments import ( "context" "fmt" "github.com/mercadopago/sdk-go/pkg/config" "github.com/mercadopago/sdk-go/pkg/preference" "github.com/saveinmed/backend-go/internal/domain" ) type MercadoPagoGateway struct { BaseURL string AccessToken string BackendURL string MarketplaceCommission float64 } func NewMercadoPagoGateway(baseURL, accessToken, backendURL string, commission float64) *MercadoPagoGateway { return &MercadoPagoGateway{ BaseURL: baseURL, AccessToken: accessToken, BackendURL: backendURL, MarketplaceCommission: commission, } } func (g *MercadoPagoGateway) CreatePreference(ctx context.Context, order *domain.Order) (*domain.PaymentPreference, error) { cfg, err := config.New(g.AccessToken) if err != nil { return nil, fmt.Errorf("failed to create mp config: %w", err) } client := preference.NewClient(cfg) var items []preference.ItemRequest for _, i := range order.Items { items = append(items, preference.ItemRequest{ ID: i.ProductID.String(), Title: "Produto", // Fallback as we might not have product details loaded here Description: fmt.Sprintf("Product ID %s", i.ProductID), Quantity: int(i.Quantity), UnitPrice: float64(i.UnitCents) / 100.0, CurrencyID: "BRL", }) } shipmentCost := float64(order.ShippingFeeCents) / 100.0 notificationURL := g.BackendURL + "/api/v1/payments/webhook" request := preference.Request{ Items: items, Shipments: &preference.ShipmentsRequest{ Cost: shipmentCost, Mode: "not_specified", }, ExternalReference: order.ID.String(), NotificationURL: notificationURL, BinaryMode: true, BackURLs: &preference.BackURLsRequest{ Success: g.BackendURL + "/checkout/success", // Adjust if frontend is on different host? Usually same domain or configured. Failure: g.BackendURL + "/checkout/failure", Pending: g.BackendURL + "/checkout/pending", }, AutoReturn: "approved", } pref, err := client.Create(ctx, request) if err != nil { return nil, fmt.Errorf("failed to create preference: %w", err) } svcFee := int64(float64(order.TotalCents) * (g.MarketplaceCommission / 100)) sellerRec := order.TotalCents - svcFee return &domain.PaymentPreference{ OrderID: order.ID, Gateway: "mercadopago", PaymentID: pref.ID, PaymentURL: pref.InitPoint, // Use SandboxInitPoint if testing? SDK returns proper one based on AccessToken type usually. CommissionPct: g.MarketplaceCommission, MarketplaceFee: svcFee, SellerReceivable: sellerRec, }, nil }