diff --git a/src/Billing/Jobs/SubscriptionCancellationJob.cs b/src/Billing/Jobs/SubscriptionCancellationJob.cs index c46581272e..b59bb10eaf 100644 --- a/src/Billing/Jobs/SubscriptionCancellationJob.cs +++ b/src/Billing/Jobs/SubscriptionCancellationJob.cs @@ -23,9 +23,9 @@ public class SubscriptionCancellationJob( } var subscription = await stripeFacade.GetSubscription(subscriptionId); - if (subscription?.Status != "unpaid") + if (subscription?.Status != "unpaid" || + subscription.LatestInvoice?.BillingReason is not ("subscription_cycle" or "subscription_create")) { - // Subscription is no longer unpaid, skip cancellation return; } diff --git a/src/Billing/Services/Implementations/SubscriptionUpdatedHandler.cs b/src/Billing/Services/Implementations/SubscriptionUpdatedHandler.cs index 10a1d1a186..4e142f8cae 100644 --- a/src/Billing/Services/Implementations/SubscriptionUpdatedHandler.cs +++ b/src/Billing/Services/Implementations/SubscriptionUpdatedHandler.cs @@ -59,7 +59,7 @@ public class SubscriptionUpdatedHandler : ISubscriptionUpdatedHandler /// public async Task HandleAsync(Event parsedEvent) { - var subscription = await _stripeEventService.GetSubscription(parsedEvent, true, ["customer", "discounts"]); + var subscription = await _stripeEventService.GetSubscription(parsedEvent, true, ["customer", "discounts", "latest_invoice"]); var (organizationId, userId, providerId) = _stripeEventUtilityService.GetIdsFromMetadata(subscription.Metadata); switch (subscription.Status) @@ -68,7 +68,8 @@ public class SubscriptionUpdatedHandler : ISubscriptionUpdatedHandler when organizationId.HasValue: { await _organizationService.DisableAsync(organizationId.Value, subscription.CurrentPeriodEnd); - if (subscription.Status == StripeSubscriptionStatus.Unpaid) + if (subscription.Status == StripeSubscriptionStatus.Unpaid && + subscription.LatestInvoice is { BillingReason: "subscription_cycle" or "subscription_create" }) { await ScheduleCancellationJobAsync(subscription.Id, organizationId.Value); } @@ -96,7 +97,10 @@ public class SubscriptionUpdatedHandler : ISubscriptionUpdatedHandler { await _organizationEnableCommand.EnableAsync(organizationId.Value); var organization = await _organizationRepository.GetByIdAsync(organizationId.Value); - await _pushNotificationService.PushSyncOrganizationStatusAsync(organization); + if (organization != null) + { + await _pushNotificationService.PushSyncOrganizationStatusAsync(organization); + } break; } case StripeSubscriptionStatus.Active: @@ -204,23 +208,24 @@ public class SubscriptionUpdatedHandler : ISubscriptionUpdatedHandler private async Task ScheduleCancellationJobAsync(string subscriptionId, Guid organizationId) { var isResellerManagedOrgAlertEnabled = _featureService.IsEnabled(FeatureFlagKeys.ResellerManagedOrgAlert); - - if (isResellerManagedOrgAlertEnabled) + if (!isResellerManagedOrgAlertEnabled) { - var scheduler = await _schedulerFactory.GetScheduler(); - - var job = JobBuilder.Create() - .WithIdentity($"cancel-sub-{subscriptionId}", "subscription-cancellations") - .UsingJobData("subscriptionId", subscriptionId) - .UsingJobData("organizationId", organizationId.ToString()) - .Build(); - - var trigger = TriggerBuilder.Create() - .WithIdentity($"cancel-trigger-{subscriptionId}", "subscription-cancellations") - .StartAt(DateTimeOffset.UtcNow.AddDays(7)) - .Build(); - - await scheduler.ScheduleJob(job, trigger); + return; } + + var scheduler = await _schedulerFactory.GetScheduler(); + + var job = JobBuilder.Create() + .WithIdentity($"cancel-sub-{subscriptionId}", "subscription-cancellations") + .UsingJobData("subscriptionId", subscriptionId) + .UsingJobData("organizationId", organizationId.ToString()) + .Build(); + + var trigger = TriggerBuilder.Create() + .WithIdentity($"cancel-trigger-{subscriptionId}", "subscription-cancellations") + .StartAt(DateTimeOffset.UtcNow.AddDays(7)) + .Build(); + + await scheduler.ScheduleJob(job, trigger); } }