From a1957d2506630d606fde3c16eb02949e748ac94f Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Thu, 5 Apr 2018 21:56:36 -0400 Subject: [PATCH] handle sub unpaid and upcoming invoice events --- src/Billing/Controllers/StripeController.cs | 91 +++++++++++++++++++-- 1 file changed, 82 insertions(+), 9 deletions(-) diff --git a/src/Billing/Controllers/StripeController.cs b/src/Billing/Controllers/StripeController.cs index d8cd23f276..807aef0d36 100644 --- a/src/Billing/Controllers/StripeController.cs +++ b/src/Billing/Controllers/StripeController.cs @@ -6,6 +6,7 @@ using Stripe; using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Threading.Tasks; namespace Bit.Billing.Controllers @@ -56,13 +57,25 @@ namespace Bit.Billing.Controllers return new BadRequestResult(); } - if(parsedEvent.Type.Equals("customer.subscription.deleted") || - parsedEvent.Type.Equals("customer.subscription.updated")) + var invUpcoming = parsedEvent.Type.Equals("invoice.upcoming"); + var subDeleted = parsedEvent.Type.Equals("customer.subscription.deleted"); + var subUpdated = parsedEvent.Type.Equals("customer.subscription.updated"); + + if(subDeleted || subUpdated) { - StripeSubscription subscription = Mapper.MapFromJson(parsedEvent.Data.Object.ToString()); + StripeSubscription subscription = Mapper.MapFromJson( + parsedEvent.Data.Object.ToString()); + if(subscription == null) + { + throw new Exception("Subscription is null."); + } + var ids = GetIdsFromMetaData(subscription.Metadata); - if(parsedEvent.Type.Equals("customer.subscription.deleted") && subscription?.Status == "canceled") + var subCanceled = subDeleted && subscription.Status == "canceled"; + var subUnpaid = subUpdated && subscription.Status == "unpaid"; + + if(subCanceled || subUnpaid) { // org if(ids.Item1.HasValue) @@ -75,37 +88,97 @@ namespace Bit.Billing.Controllers await _userService.DisablePremiumAsync(ids.Item2.Value, subscription.CurrentPeriodEnd); } } - else if(parsedEvent.Type.Equals("customer.subscription.updated")) + + if(subUpdated) { // org if(ids.Item1.HasValue) { - await _organizationService.UpdateExpirationDateAsync(ids.Item1.Value, subscription.CurrentPeriodEnd); + await _organizationService.UpdateExpirationDateAsync(ids.Item1.Value, + subscription.CurrentPeriodEnd); } // user else if(ids.Item2.HasValue) { - await _userService.UpdatePremiumExpirationAsync(ids.Item2.Value, subscription.CurrentPeriodEnd); + await _userService.UpdatePremiumExpirationAsync(ids.Item2.Value, + subscription.CurrentPeriodEnd); } } } + else if(false /* Disabled for now */ && invUpcoming) + { + StripeInvoice invoice = Mapper.MapFromJson( + parsedEvent.Data.Object.ToString()); + if(invoice == null) + { + throw new Exception("Invoice is null."); + } + + // TODO: maybe invoice subscription expandable is already here any we don't need to call API? + var subscriptionService = new StripeSubscriptionService(); + var subscription = await subscriptionService.GetAsync(invoice.SubscriptionId); + if(subscription == null) + { + throw new Exception("Invoice subscription is null."); + } + + var ids = GetIdsFromMetaData(subscription.Metadata); + + // To include in email: + // invoice.AmountDue; + // invoice.DueDate; + + // org + if(ids.Item1.HasValue) + { + // TODO: email billing contact + } + // user + else if(ids.Item2.HasValue) + { + // TODO: email user + } + } return new OkResult(); } private Tuple GetIdsFromMetaData(IDictionary metaData) { + if(metaData == null) + { + return new Tuple(null, null); + } + Guid? orgId = null; Guid? userId = null; - if(metaData?.ContainsKey("organizationId") ?? false) + + if(metaData.ContainsKey("organizationId")) { orgId = new Guid(metaData["organizationId"]); } - else if(metaData?.ContainsKey("userId") ?? false) + else if(metaData.ContainsKey("userId")) { userId = new Guid(metaData["userId"]); } + if(userId == null && orgId == null) + { + var orgIdKey = metaData.Keys.FirstOrDefault(k => k.ToLowerInvariant() == "organizationid"); + if(!string.IsNullOrWhiteSpace(orgIdKey)) + { + orgId = new Guid(metaData[orgIdKey]); + } + else + { + var userIdKey = metaData.Keys.FirstOrDefault(k => k.ToLowerInvariant() == "userid"); + if(!string.IsNullOrWhiteSpace(userIdKey)) + { + userId = new Guid(metaData[userIdKey]); + } + } + } + return new Tuple(orgId, userId); } }