diff --git a/Configuration/BillingConfig.cs b/Configuration/BillingConfig.cs index 67c3ce7..b2cc6ae 100644 --- a/Configuration/BillingConfig.cs +++ b/Configuration/BillingConfig.cs @@ -8,10 +8,12 @@ namespace Teknik.Configuration { public class BillingConfig { + public bool Enabled { get; set; } public BillingType Type { get; set; } public string StripePublishApiKey { get; set; } public string StripeSecretApiKey { get; set; } public string StripeCheckoutWebhookSecret { get; set; } + public string StripeSubscriptionWebhookSecret { get; set; } public string StripeCustomerWebhookSecret { get; set; } public string UploadProductId { get; set; } @@ -19,10 +21,12 @@ namespace Teknik.Configuration public BillingConfig() { + Enabled = false; Type = BillingType.Stripe; StripePublishApiKey = null; StripeSecretApiKey = null; StripeCheckoutWebhookSecret = null; + StripeSubscriptionWebhookSecret = null; StripeCustomerWebhookSecret = null; } } diff --git a/Teknik/App_Data/endpointMappings.json b/Teknik/App_Data/endpointMappings.json index db8a90e..60cc1e1 100644 --- a/Teknik/App_Data/endpointMappings.json +++ b/Teknik/App_Data/endpointMappings.json @@ -154,6 +154,17 @@ "action": "HandleSubscriptionChange" } }, + { + "Name": "API.v1.HandleCustomerDeletion", + "HostTypes": [ "Full" ], + "SubDomains": [ "api" ], + "Pattern": "v1/Billing/HandleCustomerDeletion", + "Area": "API", + "Defaults": { + "controller": "BillingAPIv1", + "action": "HandleCustomerDeletion" + } + }, { "Name": "API.v1.Claims", "HostTypes": [ "Full" ], diff --git a/Teknik/Areas/Billing/Controllers/BillingController.cs b/Teknik/Areas/Billing/Controllers/BillingController.cs index 81c0697..e9646e1 100644 --- a/Teknik/Areas/Billing/Controllers/BillingController.cs +++ b/Teknik/Areas/Billing/Controllers/BillingController.cs @@ -183,21 +183,7 @@ namespace Teknik.Areas.Billing.Controllers if (user == null) throw new UnauthorizedAccessException(); - if (user.BillingCustomer == null) - { - var custId = billingService.CreateCustomer(user.Username, null); - var customer = new Customer() - { - CustomerId = custId, - User = user - }; - _dbContext.Customers.Add(customer); - user.BillingCustomer = customer; - _dbContext.Entry(user).State = EntityState.Modified; - _dbContext.SaveChanges(); - } - - var session = billingService.CreateCheckoutSession(user.BillingCustomer.CustomerId, + var session = billingService.CreateCheckoutSession(user.BillingCustomer?.CustomerId, priceId, Url.SubRouteUrl("billing", "Billing.CheckoutComplete", new { productId = price.ProductId }), Url.SubRouteUrl("billing", "Billing.Subscriptions")); @@ -211,6 +197,15 @@ namespace Teknik.Areas.Billing.Controllers var checkoutSession = billingService.GetCheckoutSession(session_id); if (checkoutSession != null) { + User user = UserHelper.GetUser(_dbContext, User.Identity.Name); + if (user == null) + throw new UnauthorizedAccessException(); + + if (user.BillingCustomer == null) + { + BillingHelper.CreateCustomer(_dbContext, user, checkoutSession.CustomerId); + } + var subscription = billingService.GetSubscription(checkoutSession.SubscriptionId); if (subscription != null) { @@ -260,32 +255,6 @@ namespace Teknik.Areas.Billing.Controllers return Redirect(Url.SubRouteUrl("billing", "Billing.ViewSubscriptions")); } - public IActionResult CancelSubscription(string subscriptionId, string productId) - { - // Get Subscription Info - var billingService = BillingFactory.GetBillingService(_config.BillingConfig); - - var subscription = billingService.GetSubscription(subscriptionId); - if (subscription == null) - throw new ArgumentException("Invalid Subscription Id", "subscriptionId"); - - if (!subscription.Prices.Exists(p => p.ProductId == productId)) - throw new ArgumentException("Subscription does not relate to product", "productId"); - - var product = billingService.GetProduct(productId); - if (product == null) - throw new ArgumentException("Product does not exist", "productId"); - - var result = billingService.CancelSubscription(subscriptionId); - - var vm = new CancelSubscriptionViewModel() - { - ProductName = product.Name - }; - - return View(vm); - } - public IActionResult SubscriptionSuccess(string priceId) { var vm = new SubscriptionSuccessViewModel(); diff --git a/Teknik/Areas/User/Controllers/UserController.cs b/Teknik/Areas/User/Controllers/UserController.cs index 50ba236..8214a87 100644 --- a/Teknik/Areas/User/Controllers/UserController.cs +++ b/Teknik/Areas/User/Controllers/UserController.cs @@ -1493,5 +1493,31 @@ namespace Teknik.Areas.Users.Controllers } return Json(new { error = "Invalid Type" }); } + + [HttpPost] + [ValidateAntiForgeryToken] + public IActionResult CancelSubscription(string subscriptionId, string productId) + { + // Get Subscription Info + var billingService = BillingFactory.GetBillingService(_config.BillingConfig); + + var subscription = billingService.GetSubscription(subscriptionId); + if (subscription == null) + return Json(new { error = "Invalid Subscription Id" }); + + if (!subscription.Prices.Exists(p => p.ProductId == productId)) + return Json(new { error = "Subscription does not relate to product" }); + + var product = billingService.GetProduct(productId); + if (product == null) + return Json(new { error = "Product does not exist" }); + + var result = billingService.CancelSubscription(subscriptionId); + + if (result) + return Json(new { result = true }); + + return Json(new { error = "Unable to cancel subscription" }); + } } } diff --git a/Teknik/Areas/User/Views/User/Settings/BillingSettings.cshtml b/Teknik/Areas/User/Views/User/Settings/BillingSettings.cshtml index d940614..e3a1756 100644 --- a/Teknik/Areas/User/Views/User/Settings/BillingSettings.cshtml +++ b/Teknik/Areas/User/Views/User/Settings/BillingSettings.cshtml @@ -6,18 +6,24 @@ Layout = "~/Areas/User/Views/User/Settings/Settings.cshtml"; } -