diff --git a/bitwarden_license/src/Commercial.Core/Billing/ProviderBillingService.cs b/bitwarden_license/src/Commercial.Core/Billing/ProviderBillingService.cs index c8d6505183..401bc22b3b 100644 --- a/bitwarden_license/src/Commercial.Core/Billing/ProviderBillingService.cs +++ b/bitwarden_license/src/Commercial.Core/Billing/ProviderBillingService.cs @@ -550,6 +550,15 @@ public class ProviderBillingService( [ new CustomerTaxIdDataOptions { Type = taxIdType, Value = taxInfo.TaxIdNumber } ]; + + if (taxIdType == StripeConstants.TaxIdType.SpanishNIF) + { + options.TaxIdData.Add(new CustomerTaxIdDataOptions + { + Type = StripeConstants.TaxIdType.EUVAT, + Value = $"ES{taxInfo.TaxIdNumber}" + }); + } } if (!string.IsNullOrEmpty(provider.DiscountId)) diff --git a/src/Core/Billing/Constants/StripeConstants.cs b/src/Core/Billing/Constants/StripeConstants.cs index 28f4dea4b2..0cffad72d3 100644 --- a/src/Core/Billing/Constants/StripeConstants.cs +++ b/src/Core/Billing/Constants/StripeConstants.cs @@ -96,6 +96,12 @@ public static class StripeConstants public const string Reverse = "reverse"; } + public static class TaxIdType + { + public const string EUVAT = "eu_vat"; + public const string SpanishNIF = "es_cif"; + } + public static class ValidateTaxLocationTiming { public const string Deferred = "deferred"; diff --git a/src/Core/Billing/Services/Implementations/OrganizationBillingService.cs b/src/Core/Billing/Services/Implementations/OrganizationBillingService.cs index 95df34dfd4..861b9bbbfd 100644 --- a/src/Core/Billing/Services/Implementations/OrganizationBillingService.cs +++ b/src/Core/Billing/Services/Implementations/OrganizationBillingService.cs @@ -244,12 +244,23 @@ public class OrganizationBillingService( organization.Id, customerSetup.TaxInformation.Country, customerSetup.TaxInformation.TaxId); + + throw new BadRequestException("billingTaxIdTypeInferenceError"); } customerCreateOptions.TaxIdData = [ new() { Type = taxIdType, Value = customerSetup.TaxInformation.TaxId } ]; + + if (taxIdType == StripeConstants.TaxIdType.SpanishNIF) + { + customerCreateOptions.TaxIdData.Add(new CustomerTaxIdDataOptions + { + Type = StripeConstants.TaxIdType.EUVAT, + Value = $"ES{customerSetup.TaxInformation.TaxId}" + }); + } } var (paymentMethodType, paymentMethodToken) = customerSetup.TokenizedPaymentSource; diff --git a/src/Core/Billing/Services/Implementations/SubscriberService.cs b/src/Core/Billing/Services/Implementations/SubscriberService.cs index 75a1bf76ec..796f700e9f 100644 --- a/src/Core/Billing/Services/Implementations/SubscriberService.cs +++ b/src/Core/Billing/Services/Implementations/SubscriberService.cs @@ -648,6 +648,12 @@ public class SubscriberService( { await stripeAdapter.TaxIdCreateAsync(customer.Id, new TaxIdCreateOptions { Type = taxIdType, Value = taxInformation.TaxId }); + + if (taxIdType == StripeConstants.TaxIdType.SpanishNIF) + { + await stripeAdapter.TaxIdCreateAsync(customer.Id, + new TaxIdCreateOptions { Type = StripeConstants.TaxIdType.EUVAT, Value = $"ES{taxInformation.TaxId}" }); + } } catch (StripeException e) { diff --git a/src/Core/Billing/Tax/Commands/PreviewTaxAmountCommand.cs b/src/Core/Billing/Tax/Commands/PreviewTaxAmountCommand.cs index 304abbaae0..c777d0c0d1 100644 --- a/src/Core/Billing/Tax/Commands/PreviewTaxAmountCommand.cs +++ b/src/Core/Billing/Tax/Commands/PreviewTaxAmountCommand.cs @@ -80,6 +80,15 @@ public class PreviewTaxAmountCommand( Value = taxInformation.TaxId } ]; + + if (taxIdType == StripeConstants.TaxIdType.SpanishNIF) + { + options.CustomerDetails.TaxIds.Add(new InvoiceCustomerDetailsTaxIdOptions + { + Type = StripeConstants.TaxIdType.EUVAT, + Value = $"ES{parameters.TaxInformation.TaxId}" + }); + } } if (planType.GetProductTier() == ProductTierType.Families) diff --git a/src/Core/Services/Implementations/StripePaymentService.cs b/src/Core/Services/Implementations/StripePaymentService.cs index 34be6d59c5..b8987c4f3d 100644 --- a/src/Core/Services/Implementations/StripePaymentService.cs +++ b/src/Core/Services/Implementations/StripePaymentService.cs @@ -842,7 +842,13 @@ public class StripePaymentService : IPaymentService try { await _stripeAdapter.TaxIdCreateAsync(customer.Id, - new TaxIdCreateOptions { Type = taxInfo.TaxIdType, Value = taxInfo.TaxIdNumber, }); + new TaxIdCreateOptions { Type = taxInfo.TaxIdType, Value = taxInfo.TaxIdNumber }); + + if (taxInfo.TaxIdType == StripeConstants.TaxIdType.SpanishNIF) + { + await _stripeAdapter.TaxIdCreateAsync(customer.Id, + new TaxIdCreateOptions { Type = StripeConstants.TaxIdType.EUVAT, Value = $"ES{taxInfo.TaxIdNumber}" }); + } } catch (StripeException e) { @@ -1000,6 +1006,15 @@ public class StripePaymentService : IPaymentService Value = parameters.TaxInformation.TaxId } ]; + + if (taxIdType == StripeConstants.TaxIdType.SpanishNIF) + { + options.CustomerDetails.TaxIds.Add(new InvoiceCustomerDetailsTaxIdOptions + { + Type = StripeConstants.TaxIdType.EUVAT, + Value = $"ES{parameters.TaxInformation.TaxId}" + }); + } } if (!string.IsNullOrWhiteSpace(gatewayCustomerId)) @@ -1154,6 +1169,15 @@ public class StripePaymentService : IPaymentService Value = parameters.TaxInformation.TaxId } ]; + + if (taxIdType == StripeConstants.TaxIdType.SpanishNIF) + { + options.CustomerDetails.TaxIds.Add(new InvoiceCustomerDetailsTaxIdOptions + { + Type = StripeConstants.TaxIdType.EUVAT, + Value = $"ES{parameters.TaxInformation.TaxId}" + }); + } } Customer gatewayCustomer = null;