From a1007398f65d0f8c90491f2a85d9909d30ddd244 Mon Sep 17 00:00:00 2001 From: Rajiv Sahal Date: Tue, 27 May 2025 18:36:42 +0530 Subject: [PATCH] fix: update stripe webhooks to handle past due subscriptions (#20466) * handle case for past due subscriptions * update user subscription again if active --------- Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com> --- .../billing/controllers/billing.controller.ts | 3 +++ .../billing/services/billing.service.ts | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/apps/api/v2/src/modules/billing/controllers/billing.controller.ts b/apps/api/v2/src/modules/billing/controllers/billing.controller.ts index 8b53a5a680..4898014e61 100644 --- a/apps/api/v2/src/modules/billing/controllers/billing.controller.ts +++ b/apps/api/v2/src/modules/billing/controllers/billing.controller.ts @@ -124,6 +124,9 @@ export class BillingController { case "checkout.session.completed": await this.billingService.handleStripeCheckoutEvents(event); break; + case "customer.subscription.updated": + await this.billingService.handleStripePaymentPastDue(event); + break; case "customer.subscription.deleted": await this.billingService.handleStripeSubscriptionDeleted(event); break; diff --git a/apps/api/v2/src/modules/billing/services/billing.service.ts b/apps/api/v2/src/modules/billing/services/billing.service.ts index 5844ff83e2..4f7057b4ca 100644 --- a/apps/api/v2/src/modules/billing/services/billing.service.ts +++ b/apps/api/v2/src/modules/billing/services/billing.service.ts @@ -216,6 +216,30 @@ export class BillingService implements OnModuleDestroy { } } + async handleStripePaymentPastDue(event: Stripe.Event) { + const invoice = event.data.object as Stripe.Invoice; + const subscriptionId = this.getSubscriptionIdFromInvoice(invoice); + const customerId = this.getCustomerIdFromInvoice(invoice); + + if (subscriptionId && customerId) { + const existingUserSubscription = await this.stripeService + .getStripe() + .subscriptions.retrieve(subscriptionId); + + if (existingUserSubscription.status === "past_due") { + await this.billingRepository.updateBillingOverdue(subscriptionId, customerId, true); + } + + if (existingUserSubscription.status === "active") { + await this.billingRepository.updateBillingOverdue(subscriptionId, customerId, false); + } + } + + if (!subscriptionId || !customerId) { + this.logger.log(`SubscriptionId: ${subscriptionId} or customerId: ${customerId} missing`); + } + } + async handleStripeCheckoutEvents(event: Stripe.Event) { const checkoutSession = event.data.object as Stripe.Checkout.Session;