From 1a0b99599c2a73f1ce8848db6098585854774710 Mon Sep 17 00:00:00 2001 From: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> Date: Wed, 12 Feb 2025 13:42:24 -0500 Subject: [PATCH] Fix issue with credit card payment (#5399) --- .../PremiumUserBillingService.cs | 62 +++++++++++-------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/src/Core/Billing/Services/Implementations/PremiumUserBillingService.cs b/src/Core/Billing/Services/Implementations/PremiumUserBillingService.cs index 6f571950f5..6b9f32e8f9 100644 --- a/src/Core/Billing/Services/Implementations/PremiumUserBillingService.cs +++ b/src/Core/Billing/Services/Implementations/PremiumUserBillingService.cs @@ -92,32 +92,7 @@ public class PremiumUserBillingService( * If the customer was previously set up with credit, which does not require a billing location, * we need to update the customer on the fly before we start the subscription. */ - if (customerSetup is - { - TokenizedPaymentSource.Type: PaymentMethodType.Credit, - TaxInformation: { Country: not null and not "", PostalCode: not null and not "" } - }) - { - var options = new CustomerUpdateOptions - { - Address = new AddressOptions - { - Line1 = customerSetup.TaxInformation.Line1, - Line2 = customerSetup.TaxInformation.Line2, - City = customerSetup.TaxInformation.City, - PostalCode = customerSetup.TaxInformation.PostalCode, - State = customerSetup.TaxInformation.State, - Country = customerSetup.TaxInformation.Country, - }, - Expand = ["tax"], - Tax = new CustomerTaxOptions - { - ValidateLocation = StripeConstants.ValidateTaxLocationTiming.Immediately - } - }; - - customer = await stripeAdapter.CustomerUpdateAsync(customer.Id, options); - } + customer = await ReconcileBillingLocationAsync(customer, customerSetup.TaxInformation); var subscription = await CreateSubscriptionAsync(user.Id, customer, storage); @@ -167,6 +142,11 @@ public class PremiumUserBillingService( User user, CustomerSetup customerSetup) { + /* + * Creating a Customer via the adding of a payment method or the purchasing of a subscription requires + * an actual payment source. The only time this is not the case is when the Customer is created when the + * User purchases credit. + */ if (customerSetup.TokenizedPaymentSource is not { Type: PaymentMethodType.BankAccount or PaymentMethodType.Card or PaymentMethodType.PayPal, @@ -367,4 +347,34 @@ public class PremiumUserBillingService( return subscription; } + + private async Task ReconcileBillingLocationAsync( + Customer customer, + TaxInformation taxInformation) + { + if (customer is { Address: { Country: not null and not "", PostalCode: not null and not "" } }) + { + return customer; + } + + var options = new CustomerUpdateOptions + { + Address = new AddressOptions + { + Line1 = taxInformation.Line1, + Line2 = taxInformation.Line2, + City = taxInformation.City, + PostalCode = taxInformation.PostalCode, + State = taxInformation.State, + Country = taxInformation.Country, + }, + Expand = ["tax"], + Tax = new CustomerTaxOptions + { + ValidateLocation = StripeConstants.ValidateTaxLocationTiming.Immediately + } + }; + + return await stripeAdapter.CustomerUpdateAsync(customer.Id, options); + } }