From 48da6eba1c23c14b96b59a7ece03c146b0e3dbcb Mon Sep 17 00:00:00 2001 From: cyprain-okeke <108260115+cyprain-okeke@users.noreply.github.com> Date: Tue, 2 Apr 2024 17:36:53 +0100 Subject: [PATCH] [PM-3891] Remove the dollar threshold changes and Implement time-based threshold (#3948) * implement time threshold Signed-off-by: Cy Okeke * add code to make failed payment is tried Signed-off-by: Cy Okeke --------- Signed-off-by: Cy Okeke Co-authored-by: Conner Turnbull <133619638+cturnbull-bitwarden@users.noreply.github.com> --- src/Billing/Controllers/StripeController.cs | 2 +- .../Implementations/StripePaymentService.cs | 45 ++++++------------- 2 files changed, 14 insertions(+), 33 deletions(-) diff --git a/src/Billing/Controllers/StripeController.cs b/src/Billing/Controllers/StripeController.cs index e78ed31ff1..679dea15ce 100644 --- a/src/Billing/Controllers/StripeController.cs +++ b/src/Billing/Controllers/StripeController.cs @@ -868,7 +868,7 @@ public class StripeController : Controller private bool UnpaidAutoChargeInvoiceForSubscriptionCycle(Invoice invoice) { return invoice.AmountDue > 0 && !invoice.Paid && invoice.CollectionMethod == "charge_automatically" && - invoice.BillingReason == "subscription_cycle" && invoice.SubscriptionId != null; + invoice.BillingReason is "subscription_cycle" or "automatic_pending_invoice_item_invoice" && invoice.SubscriptionId != null; } private async Task VerifyCorrectTaxRateForCharge(Invoice invoice, Subscription subscription) diff --git a/src/Core/Services/Implementations/StripePaymentService.cs b/src/Core/Services/Implementations/StripePaymentService.cs index e89bdacfe1..a9e688fcbf 100644 --- a/src/Core/Services/Implementations/StripePaymentService.cs +++ b/src/Core/Services/Implementations/StripePaymentService.cs @@ -777,6 +777,7 @@ public class StripePaymentService : IPaymentService var chargeNow = collectionMethod == "charge_automatically"; var updatedItemOptions = subscriptionUpdate.UpgradeItemsOptions(sub); var isPm5864DollarThresholdEnabled = _featureService.IsEnabled(FeatureFlagKeys.PM5864DollarThreshold); + var isAnnualPlan = sub?.Items?.Data.FirstOrDefault()?.Plan?.Interval == "year"; var subUpdateOptions = new SubscriptionUpdateOptions { @@ -788,25 +789,10 @@ public class StripePaymentService : IPaymentService CollectionMethod = "send_invoice", ProrationDate = prorationDate, }; - var immediatelyInvoice = false; - if (!invoiceNow && isPm5864DollarThresholdEnabled && sub.Status.Trim() != "trialing") + if (!invoiceNow && isAnnualPlan && isPm5864DollarThresholdEnabled && sub.Status.Trim() != "trialing") { - var upcomingInvoiceWithChanges = await _stripeAdapter.InvoiceUpcomingAsync(new UpcomingInvoiceOptions - { - Customer = subscriber.GatewayCustomerId, - Subscription = subscriber.GatewaySubscriptionId, - SubscriptionItems = ToInvoiceSubscriptionItemOptions(updatedItemOptions), - SubscriptionProrationBehavior = Constants.CreateProrations, - SubscriptionProrationDate = prorationDate, - SubscriptionBillingCycleAnchor = SubscriptionBillingCycleAnchor.Now - }); - - var isAnnualPlan = sub?.Items?.Data.FirstOrDefault()?.Plan?.Interval == "year"; - immediatelyInvoice = isAnnualPlan && upcomingInvoiceWithChanges.AmountRemaining >= 50000; - - subUpdateOptions.BillingCycleAnchor = immediatelyInvoice - ? SubscriptionBillingCycleAnchor.Now - : SubscriptionBillingCycleAnchor.Unchanged; + subUpdateOptions.PendingInvoiceItemInterval = + new SubscriptionPendingInvoiceItemIntervalOptions { Interval = "month" }; } var pm5766AutomaticTaxIsEnabled = _featureService.IsEnabled(FeatureFlagKeys.PM5766AutomaticTax); @@ -859,21 +845,16 @@ public class StripePaymentService : IPaymentService { try { - if (!isPm5864DollarThresholdEnabled || immediatelyInvoice || invoiceNow) + if (chargeNow) { - if (chargeNow) - { - paymentIntentClientSecret = await PayInvoiceAfterSubscriptionChangeAsync(subscriber, invoice); - } - else - { - invoice = await _stripeAdapter.InvoiceFinalizeInvoiceAsync(subResponse.LatestInvoiceId, new InvoiceFinalizeOptions - { - AutoAdvance = false, - }); - await _stripeAdapter.InvoiceSendInvoiceAsync(invoice.Id, new InvoiceSendOptions()); - paymentIntentClientSecret = null; - } + paymentIntentClientSecret = await PayInvoiceAfterSubscriptionChangeAsync(subscriber, invoice); + } + else + { + invoice = await _stripeAdapter.InvoiceFinalizeInvoiceAsync(subResponse.LatestInvoiceId, + new InvoiceFinalizeOptions { AutoAdvance = false, }); + await _stripeAdapter.InvoiceSendInvoiceAsync(invoice.Id, new InvoiceSendOptions()); + paymentIntentClientSecret = null; } } catch