mirror of
https://github.com/andwati/telecom-platform.git
synced 2026-10-18 19:12:54 +00:00
- Remove all method implementations from subscriber.go (CreateSubscriber/GetSubscriber/GetSubscriberByIMSI/UpdateSubscriber/SuspendSubscriber/TerminateSubscriber/ListSubscribers/terminateSubscriberSessions/GetAccount/ListInvoices/GetInvoice/ListRatingPlans/GetRatingPlan/ListAlerts/SearchSubscribers/ResolveAlert/CreateAlert and all other methods) - Update SubscriberService struct comment
123 lines
4.2 KiB
Go
123 lines
4.2 KiB
Go
package services
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/nutcas3/telecom-platform/apps/api-server/internal/models"
|
|
)
|
|
|
|
// AddPaymentMethod creates a new payment method for the given subscriber.
|
|
func (s *SubscriberService) AddPaymentMethod(ctx context.Context, subscriberId int, req *models.AddPaymentMethodRequest) (*models.PaymentMethod, error) {
|
|
paymentMethodID := fmt.Sprintf("pm_%d_%d", subscriberId, time.Now().Unix())
|
|
|
|
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: last4,
|
|
Brand: brand,
|
|
ExpiryMonth: expiryMonth,
|
|
ExpiryYear: expiryYear,
|
|
IsDefault: req.IsDefault,
|
|
CreatedAt: time.Now(),
|
|
}
|
|
|
|
if err := s.db.DB.WithContext(ctx).Create(paymentMethod).Error; err != nil {
|
|
return nil, fmt.Errorf("failed to add payment method: %w", err)
|
|
}
|
|
|
|
return paymentMethod, nil
|
|
}
|
|
|
|
// processPaymentToken resolves a Stripe token to card details.
|
|
func (s *SubscriberService) processPaymentToken(ctx context.Context, token string) (last4, brand string, expiryMonth, expiryYear int, err error) {
|
|
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 details.Last4, details.Brand, details.ExpiryMonth, details.ExpiryYear, nil
|
|
}
|
|
|
|
// RemovePaymentMethod removes a payment method, preventing removal of the only one and
|
|
// reassigning the default before deletion.
|
|
func (s *SubscriberService) RemovePaymentMethod(ctx context.Context, paymentMethodId string) (bool, error) {
|
|
var paymentMethod models.PaymentMethod
|
|
if err := s.db.DB.WithContext(ctx).First(&paymentMethod, "id = ?", paymentMethodId).Error; err != nil {
|
|
return false, fmt.Errorf("payment method not found: %w", err)
|
|
}
|
|
|
|
var count int64
|
|
if err := s.db.DB.WithContext(ctx).
|
|
Model(&models.PaymentMethod{}).
|
|
Where("subscriber_id = ?", paymentMethod.SubscriberID).
|
|
Count(&count).Error; err != nil {
|
|
return false, fmt.Errorf("failed to check payment methods: %w", err)
|
|
}
|
|
|
|
if count == 1 {
|
|
return false, fmt.Errorf("cannot remove the only payment method")
|
|
}
|
|
|
|
if paymentMethod.IsDefault {
|
|
var newDefault models.PaymentMethod
|
|
if err := s.db.DB.WithContext(ctx).
|
|
Where("subscriber_id = ? AND id != ?", paymentMethod.SubscriberID, paymentMethodId).
|
|
First(&newDefault).Error; err != nil {
|
|
return false, fmt.Errorf("failed to find alternative payment method: %w", err)
|
|
}
|
|
|
|
if err := s.db.DB.WithContext(ctx).
|
|
Model(&newDefault).
|
|
Update("is_default", true).Error; err != nil {
|
|
return false, fmt.Errorf("failed to set new default payment method: %w", err)
|
|
}
|
|
}
|
|
|
|
if err := s.db.DB.WithContext(ctx).Delete(&paymentMethod).Error; err != nil {
|
|
return false, fmt.Errorf("failed to delete payment method: %w", err)
|
|
}
|
|
|
|
return true, nil
|
|
}
|
|
|
|
// SetDefaultPaymentMethod marks one payment method as default and unsets others in a transaction.
|
|
func (s *SubscriberService) SetDefaultPaymentMethod(ctx context.Context, paymentMethodId string) (*models.PaymentMethod, error) {
|
|
var paymentMethod models.PaymentMethod
|
|
tx := s.db.DB.WithContext(ctx).Begin()
|
|
|
|
if err := tx.Model(&models.PaymentMethod{}).
|
|
Where("id = ?", paymentMethodId).
|
|
First(&paymentMethod).Error; err != nil {
|
|
tx.Rollback()
|
|
return nil, fmt.Errorf("payment method not found: %w", err)
|
|
}
|
|
|
|
if err := tx.Model(&models.PaymentMethod{}).
|
|
Where("subscriber_id = ? AND id != ?", paymentMethod.SubscriberID, paymentMethodId).
|
|
Update("is_default", false).Error; err != nil {
|
|
tx.Rollback()
|
|
return nil, fmt.Errorf("failed to update other payment methods: %w", err)
|
|
}
|
|
|
|
if err := tx.Model(&paymentMethod).
|
|
Update("is_default", true).Error; err != nil {
|
|
tx.Rollback()
|
|
return nil, fmt.Errorf("failed to set default payment method: %w", err)
|
|
}
|
|
|
|
if err := tx.Commit().Error; err != nil {
|
|
return nil, fmt.Errorf("failed to commit transaction: %w", err)
|
|
}
|
|
|
|
return &paymentMethod, nil
|
|
}
|