128 lines
4.6 KiB
Go
128 lines
4.6 KiB
Go
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
|
|
}
|