From ed9a94cba1444aec64b95f732697cbe1829f6b07 Mon Sep 17 00:00:00 2001 From: Uncled1023 Date: Fri, 19 Nov 2021 16:14:27 -0800 Subject: [PATCH] Added handling of customer deletion --- BillingCore/BillingService.cs | 1 + BillingCore/StripeService.cs | 11 ++- .../V1/Controllers/BillingAPIv1Controller.cs | 20 ++++- Teknik/Areas/Billing/BillingHelper.cs | 77 +++++++++++++++---- 4 files changed, 90 insertions(+), 19 deletions(-) diff --git a/BillingCore/BillingService.cs b/BillingCore/BillingService.cs index df53fd8..2d8f758 100644 --- a/BillingCore/BillingService.cs +++ b/BillingCore/BillingService.cs @@ -41,5 +41,6 @@ namespace Teknik.BillingCore public abstract Task ParseEvent(HttpRequest request, string apiKey); public abstract CheckoutSession ProcessCheckoutCompletedEvent(Event e); public abstract Subscription ProcessSubscriptionEvent(Event e); + public abstract Customer ProcessCustomerEvent(Event e); } } diff --git a/BillingCore/StripeService.cs b/BillingCore/StripeService.cs index 2f63080..0b5c08b 100644 --- a/BillingCore/StripeService.cs +++ b/BillingCore/StripeService.cs @@ -310,6 +310,14 @@ namespace Teknik.BillingCore return ConvertSubscription(subscription); } + public override Models.Customer ProcessCustomerEvent(Models.Event ev) + { + // Handle the checkout.session.completed event + var customer = ev.Data as Stripe.Customer; + + return ConvertCustomer(customer); + } + public override PortalSession CreatePortalSession(string customerId, string returnUrl) { var portalService = new Stripe.BillingPortal.SessionService(); @@ -469,7 +477,8 @@ namespace Teknik.BillingCore CustomerId = customer.Id }; - if (customer.Subscriptions.Any()) + if (customer.Subscriptions != null && + customer.Subscriptions.Any()) returnCust.Subscriptions = customer.Subscriptions.Select(s => ConvertSubscription(s)).ToList(); return returnCust; diff --git a/Teknik/Areas/API/V1/Controllers/BillingAPIv1Controller.cs b/Teknik/Areas/API/V1/Controllers/BillingAPIv1Controller.cs index 6eed219..460be63 100644 --- a/Teknik/Areas/API/V1/Controllers/BillingAPIv1Controller.cs +++ b/Teknik/Areas/API/V1/Controllers/BillingAPIv1Controller.cs @@ -45,7 +45,7 @@ namespace Teknik.Areas.API.V1.Controllers { var billingService = BillingFactory.GetBillingService(_config.BillingConfig); - var billingEvent = await billingService.ParseEvent(Request, _config.BillingConfig.StripeCustomerWebhookSecret); + var billingEvent = await billingService.ParseEvent(Request, _config.BillingConfig.StripeSubscriptionWebhookSecret); if (billingEvent == null) return BadRequest(); @@ -58,5 +58,23 @@ namespace Teknik.Areas.API.V1.Controllers return Ok(); } + + public async Task HandleCustomerDeletion() + { + var billingService = BillingFactory.GetBillingService(_config.BillingConfig); + + var billingEvent = await billingService.ParseEvent(Request, _config.BillingConfig.StripeCustomerWebhookSecret); + + if (billingEvent == null) + return BadRequest(); + + var customerEvent = billingService.ProcessCustomerEvent(billingEvent); + if (customerEvent == null) + return BadRequest(); + + BillingHelper.RemoveCustomer(_dbContext, customerEvent.CustomerId); + + return Ok(); + } } } diff --git a/Teknik/Areas/Billing/BillingHelper.cs b/Teknik/Areas/Billing/BillingHelper.cs index 6e3cdbe..be251ac 100644 --- a/Teknik/Areas/Billing/BillingHelper.cs +++ b/Teknik/Areas/Billing/BillingHelper.cs @@ -11,11 +11,41 @@ namespace Teknik.Areas.Billing { public static class BillingHelper { + public static Models.Customer CreateCustomer(TeknikEntities db, User user, string customerId) + { + var customer = new Models.Customer() + { + CustomerId = customerId, + User = user + }; + db.Customers.Add(customer); + user.BillingCustomer = customer; + db.Entry(user).State = EntityState.Modified; + db.SaveChanges(); + + return customer; + } + + public static void RemoveCustomer(TeknikEntities db, string customerId) + { + // They have paid, so let's get their subscription and update their user settings + var user = db.Users.FirstOrDefault(u => u.BillingCustomer != null && + u.BillingCustomer.CustomerId == customerId); + if (user != null && + user.BillingCustomer != null) + { + db.Customers.Remove(user.BillingCustomer); + user.BillingCustomer = null; + db.Entry(user).State = EntityState.Modified; + db.SaveChanges(); + } + } + public static void ProcessSubscription(Config config, TeknikEntities db, string customerId, Subscription subscription) { // They have paid, so let's get their subscription and update their user settings var user = db.Users.FirstOrDefault(u => u.BillingCustomer != null && - u.BillingCustomer.CustomerId == customerId); + u.BillingCustomer.CustomerId == customerId); if (user != null) { var isActive = subscription.Status == SubscriptionStatus.Active; @@ -31,25 +61,38 @@ namespace Teknik.Areas.Billing // What type of subscription is this if (config.BillingConfig.UploadProductId == price.ProductId) { - // Process Upload Settings - user.UploadSettings.MaxUploadStorage = active ? price.Storage : config.UploadConfig.MaxStorage; - user.UploadSettings.MaxUploadFileSize = active ? price.FileSize : config.UploadConfig.MaxUploadFileSize; - db.Entry(user).State = EntityState.Modified; - db.SaveChanges(); + SetUploadLimits(db, + user, + active ? price.Storage : config.UploadConfig.MaxStorage, + active ? price.FileSize : config.UploadConfig.MaxUploadFileSize); } else if (config.BillingConfig.EmailProductId == price.ProductId) { - // Process an email subscription - string email = UserHelper.GetUserEmailAddress(config, user.Username); - if (active) - { - UserHelper.EnableUserEmail(config, email); - UserHelper.EditUserEmailMaxSize(config, email, price.Storage); - } - else - { - UserHelper.DisableUserEmail(config, email); - } + SetEmailLimits(config, user, price.Storage, active); + } + } + + public static void SetUploadLimits(TeknikEntities db, User user, long storage, long fileSize) + { + // Process Upload Settings + user.UploadSettings.MaxUploadStorage = storage; + user.UploadSettings.MaxUploadFileSize = fileSize; + db.Entry(user).State = EntityState.Modified; + db.SaveChanges(); + } + + public static void SetEmailLimits(Config config, User user, long storage, bool active) + { + // Process an email subscription + string email = UserHelper.GetUserEmailAddress(config, user.Username); + if (active) + { + UserHelper.EnableUserEmail(config, email); + UserHelper.EditUserEmailMaxSize(config, email, storage); + } + else + { + UserHelper.DisableUserEmail(config, email); } } }