package payments import ( "context" "fmt" "time" "github.com/saveinmed/backend-go/internal/domain" ) // StripeGateway implements payment processing via Stripe. // In production, this would use the Stripe Go SDK. type StripeGateway struct { APIKey string MarketplaceCommission float64 } func NewStripeGateway(apiKey string, commission float64) *StripeGateway { return &StripeGateway{ APIKey: apiKey, MarketplaceCommission: commission, } } func (g *StripeGateway) CreatePreference(ctx context.Context, order *domain.Order, payer *domain.User, sellerAcc *domain.SellerPaymentAccount) (*domain.PaymentPreference, error) { select { case <-ctx.Done(): return nil, ctx.Err() default: } // Calculate marketplace fee fee := int64(float64(order.TotalCents) * (g.MarketplaceCommission / 100)) // In production, this would: // 1. Create a Stripe PaymentIntent with transfer_data for connected accounts // 2. Set application_fee_amount for marketplace commission // 3. Return the client_secret for frontend confirmation pref := &domain.PaymentPreference{ OrderID: order.ID, Gateway: "stripe", CommissionPct: g.MarketplaceCommission, MarketplaceFee: fee, SellerReceivable: order.TotalCents - fee, PaymentURL: fmt.Sprintf("https://checkout.stripe.com/pay/%s", order.ID.String()), // In production: would include client_secret, payment_intent_id } // Simulate API latency time.Sleep(15 * time.Millisecond) return pref, nil } // CreatePayment executes a direct payment via Stripe. func (g *StripeGateway) CreatePayment(ctx context.Context, order *domain.Order, token, issuerID, paymentMethodID string, installments int, payer *domain.User, sellerAcc *domain.SellerPaymentAccount) (*domain.PaymentResult, error) { // In production, this would use stripe.PaymentIntent.New with the token (PaymentMethod ID) return &domain.PaymentResult{ PaymentID: fmt.Sprintf("pi_%s", order.ID.String()[:8]), Status: "approved", Gateway: "stripe", Message: "Pagamento aprovado via Stripe", }, nil } // CreatePixPayment generates a Pix payment using Stripe. func (g *StripeGateway) CreatePixPayment(ctx context.Context, order *domain.Order) (*domain.PixPaymentResult, error) { // Stripe supports Pix via PaymentIntents with payment_method_types=['pix'] return &domain.PixPaymentResult{ PaymentID: fmt.Sprintf("pix_%s", order.ID.String()[:8]), OrderID: order.ID, Gateway: "stripe", PixKey: "stripe@saveinmed.com", QRCode: "stripe_pix_qr_code_data", QRCodeBase64: "data:image/png;base64,...", CopyPasta: "stripe_pix_copy_and_paste", AmountCents: order.TotalCents + order.ShippingFeeCents, Status: "pending", ExpiresAt: time.Now().Add(30 * time.Minute), }, nil } // CreateBoletoPayment generates a Boleto payment using Stripe. func (g *StripeGateway) CreateBoletoPayment(ctx context.Context, order *domain.Order, payer *domain.User) (*domain.BoletoPaymentResult, error) { // Stripe supports Boleto via PaymentIntents with payment_method_types=['boleto'] return &domain.BoletoPaymentResult{ PaymentID: fmt.Sprintf("bol_%s", order.ID.String()[:8]), OrderID: order.ID, Gateway: "stripe", BoletoURL: "https://stripe.com/boleto/...", BarCode: "00000000000000000000000000000000000000000000", DigitableLine: "00000.00000 00000.000000 00000.000000 0 00000000000000", AmountCents: order.TotalCents + order.ShippingFeeCents, DueDate: time.Now().AddDate(0, 0, 3), Status: "pending", }, nil } // GetPaymentStatus fetches payment details from Stripe. func (g *StripeGateway) GetPaymentStatus(ctx context.Context, paymentID string) (*domain.PaymentWebhookEvent, error) { // In production, call stripe.PaymentIntent.Get(paymentID) return &domain.PaymentWebhookEvent{ PaymentID: paymentID, Status: "approved", Gateway: "stripe", }, nil } func (g *StripeGateway) CreatePaymentIntent(ctx context.Context, order *domain.Order) (map[string]interface{}, error) { select { case <-ctx.Done(): return nil, ctx.Err() default: } fee := int64(float64(order.TotalCents) * (g.MarketplaceCommission / 100)) // Simulated Stripe PaymentIntent response return map[string]interface{}{ "id": fmt.Sprintf("pi_%s", order.ID.String()[:8]), "client_secret": fmt.Sprintf("pi_%s_secret_%d", order.ID.String()[:8], time.Now().UnixNano()), "amount": order.TotalCents, "currency": "brl", "status": "requires_payment_method", "application_fee": fee, "transfer_data": map[string]interface{}{"destination": order.SellerID.String()}, }, nil }