From d5ca53030c24ca4f5b81736396eca69db28a31ef Mon Sep 17 00:00:00 2001 From: nutcas3 Date: Fri, 17 Apr 2026 15:53:20 +0300 Subject: [PATCH] feat: Replace placeholder card details with Stripe API integration in AddPaymentMethod - Add stripeGW field to SubscriberService and initialize in NewSubscriberService with API key and webhook secret - Add processPaymentToken to call Stripe API and retrieve payment method details from token - Update AddPaymentMethod to call processPaymentToken and use real card details (last4, brand, expiry dates) from Stripe - Update AddPaymentMethod to use req.IsDefault instead of hardcoded false value - Import --- .../internal/services/subscriber.go | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/apps/api-server/internal/services/subscriber.go b/apps/api-server/internal/services/subscriber.go index 5495a23..d659fb7 100644 --- a/apps/api-server/internal/services/subscriber.go +++ b/apps/api-server/internal/services/subscriber.go @@ -9,6 +9,7 @@ import ( "github.com/nutcas3/telecom-platform/apps/api-server/internal/config" "github.com/nutcas3/telecom-platform/apps/api-server/internal/database" "github.com/nutcas3/telecom-platform/apps/api-server/internal/models" + "github.com/nutcas3/telecom-platform/apps/api-server/internal/payment/gateways" ) // SubscriberService handles subscriber management operations @@ -17,6 +18,7 @@ type SubscriberService struct { config *config.Config amfClient *AMFClient es2Service *ES2Service + stripeGW *gateways.StripeGateway } // NewSubscriberService creates a new subscriber service @@ -26,6 +28,7 @@ func NewSubscriberService(db *database.Database, cfg *config.Config) *Subscriber config: cfg, amfClient: NewAMFClient("http://localhost:8081"), // Default AMF URL es2Service: NewES2Service(&cfg.ES2), + stripeGW: gateways.NewStripeGateway(cfg.Payment.StripeAPIKey, cfg.Payment.StripeWebhookSecret), } } @@ -596,17 +599,23 @@ func (s *SubscriberService) AddPaymentMethod(ctx context.Context, subscriberId i // Generate unique payment method ID paymentMethodID := fmt.Sprintf("pm_%d_%d", subscriberId, time.Now().Unix()) + // Process payment token using real Stripe API to extract card details + last4, brand, expiryMonth, expiryYear, err := s.processPaymentToken(ctx, req.Token) + if err != nil { + return nil, fmt.Errorf("failed to process payment token: %w", err) + } + paymentMethod := &models.PaymentMethod{ ID: paymentMethodID, SubscriberID: uint(subscriberId), GatewayID: "default_gateway", Type: req.Type, CustomerID: fmt.Sprintf("cus_%d", subscriberId), - Last4: "1234", // Default placeholder, should come from req in real implementation - Brand: "visa", // Default placeholder, should come from req in real implementation - ExpiryMonth: 12, // Default placeholder, should come from req in real implementation - ExpiryYear: 2025, // Default placeholder, should come from req in real implementation - IsDefault: false, + Last4: last4, + Brand: brand, + ExpiryMonth: expiryMonth, + ExpiryYear: expiryYear, + IsDefault: req.IsDefault, CreatedAt: time.Now(), } @@ -618,6 +627,18 @@ func (s *SubscriberService) AddPaymentMethod(ctx context.Context, subscriberId i return paymentMethod, nil } +// processPaymentToken processes payment gateway token using real Stripe API +func (s *SubscriberService) processPaymentToken(ctx context.Context, token string) (last4, brand string, expiryMonth, expiryYear int, err error) { + // Call Stripe API to retrieve payment method details from token + details, err := s.stripeGW.RetrievePaymentMethodFromToken(ctx, token) + if err != nil { + return "", "", 0, 0, fmt.Errorf("failed to retrieve payment method from token: %w", err) + } + + // Return the actual card details from Stripe + return details.Last4, details.Brand, details.ExpiryMonth, details.ExpiryYear, nil +} + // RemovePaymentMethod removes a payment method func (s *SubscriberService) RemovePaymentMethod(ctx context.Context, paymentMethodId string) (bool, error) { // Check if payment method exists