diff --git a/api/server/handlers/project/delete.go b/api/server/handlers/project/delete.go index d1939a36e2..7903024238 100644 --- a/api/server/handlers/project/delete.go +++ b/api/server/handlers/project/delete.go @@ -93,7 +93,7 @@ func (p *ProjectDeleteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) } if p.Config().BillingManager.LagoConfigLoaded && proj.GetFeatureFlag(models.LagoEnabled, p.Config().LaunchDarklyClient) { - err = p.Config().BillingManager.LagoClient.EndCustomerPlan(ctx, proj.ID) + err = p.Config().BillingManager.LagoClient.DeleteCustomer(ctx, proj.ID, proj.EnableSandbox) if err != nil { e := "error ending billing plan" err = telemetry.Error(ctx, span, err, e) @@ -102,6 +102,16 @@ func (p *ProjectDeleteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) } } + if p.Config().BillingManager.StripeConfigLoaded && proj.GetFeatureFlag(models.BillingEnabled, p.Config().LaunchDarklyClient) { + err = p.Config().BillingManager.StripeClient.DeleteCustomer(ctx, proj.BillingID) + if err != nil { + e := "error deleting stripe customer" + err = telemetry.Error(ctx, span, err, e) + p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError)) + return + } + } + deletedProject, err := p.Repo().Project().DeleteProject(proj) if err != nil { e := "error deleting project" diff --git a/internal/billing/stripe.go b/internal/billing/stripe.go index afdc1eb334..36106b6bf9 100644 --- a/internal/billing/stripe.go +++ b/internal/billing/stripe.go @@ -40,13 +40,12 @@ func (s StripeClient) CreateCustomer(ctx context.Context, userEmail string, proj stripe.Key = s.SecretKey // Create customer if not exists - customerName := fmt.Sprintf("project_%s", projectName) projectIDStr := strconv.FormatUint(uint64(projectID), 10) params := &stripe.CustomerParams{ - Name: stripe.String(customerName), + Name: stripe.String(projectName), Email: stripe.String(userEmail), Metadata: map[string]string{ - "porter_project_id": projectIDStr, + "project_id": projectIDStr, }, } diff --git a/internal/billing/usage.go b/internal/billing/usage.go index 15301dce9c..cbad5b3170 100644 --- a/internal/billing/usage.go +++ b/internal/billing/usage.go @@ -188,21 +188,17 @@ func (m LagoClient) GetCustomeActivePlan(ctx context.Context, projectID uint, sa return plan, nil } -// EndCustomerPlan will immediately end the plan for the given customer -func (m LagoClient) EndCustomerPlan(ctx context.Context, projectID uint) (err error) { - ctx, span := telemetry.NewSpan(ctx, "end-lago-customer-plan") +// DeleteCustomer will delete the customer and terminate all subscriptions +func (m LagoClient) DeleteCustomer(ctx context.Context, projectID uint, sandboxEnabled bool) (err error) { + ctx, span := telemetry.NewSpan(ctx, "delete-lago-customer") defer span.End() if projectID == 0 { return telemetry.Error(ctx, span, err, "subscription id empty") } - subscriptionID := m.generateLagoID(SubscriptionIDPrefix, projectID, false) - subscriptionTerminateInput := lago.SubscriptionTerminateInput{ - ExternalID: subscriptionID, - } - - _, lagoErr := m.client.Subscription().Terminate(ctx, subscriptionTerminateInput) + customerID := m.generateLagoID(CustomerIDPrefix, projectID, sandboxEnabled) + _, lagoErr := m.client.Customer().Delete(ctx, customerID) if lagoErr != nil { return telemetry.Error(ctx, span, fmt.Errorf(lagoErr.ErrorCode), "failed to terminate subscription") } @@ -388,11 +384,9 @@ func (m LagoClient) IngestEvents(ctx context.Context, subscriptionID string, eve var currentAttempts int for currentAttempts := 0; currentAttempts < defaultMaxRetries; currentAttempts++ { _, lagoErr := m.client.Event().Batch(ctx, &batchInput) - if lagoErr != nil { - telemetry.Error(ctx, span, err, "failed to send ingest events") - continue + if lagoErr == nil { + return nil } - break } if currentAttempts == defaultMaxRetries {