mirror of
https://github.com/bitwarden/server.git
synced 2025-02-14 01:31:24 +01:00
Merge branch 'km/userkey-rotation-v2' of github.com:bitwarden/server into km/userkey-rotation-v2
This commit is contained in:
commit
b96bfadf38
@ -3,7 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
|
||||||
<Version>2025.1.4</Version>
|
<Version>2025.1.5</Version>
|
||||||
|
|
||||||
<RootNamespace>Bit.$(MSBuildProjectName)</RootNamespace>
|
<RootNamespace>Bit.$(MSBuildProjectName)</RootNamespace>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CsvHelper" Version="32.0.3" />
|
<PackageReference Include="CsvHelper" Version="33.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -37,11 +37,7 @@
|
|||||||
// Premium
|
// Premium
|
||||||
document.getElementById('@(nameof(Model.MaxStorageGb))').value = '1';
|
document.getElementById('@(nameof(Model.MaxStorageGb))').value = '1';
|
||||||
document.getElementById('@(nameof(Model.Premium))').checked = true;
|
document.getElementById('@(nameof(Model.Premium))').checked = true;
|
||||||
using Stripe.Entitlements;
|
|
||||||
// Licensing
|
// Licensing
|
||||||
using Bit.Core;
|
|
||||||
using Stripe.Entitlements;
|
|
||||||
using Microsoft.Identity.Client.Extensibility;
|
|
||||||
document.getElementById('@(nameof(Model.LicenseKey))').value = '@Model.RandomLicenseKey';
|
document.getElementById('@(nameof(Model.LicenseKey))').value = '@Model.RandomLicenseKey';
|
||||||
document.getElementById('@(nameof(Model.PremiumExpirationDate))').value =
|
document.getElementById('@(nameof(Model.PremiumExpirationDate))').value =
|
||||||
'@Model.OneYearExpirationDate';
|
'@Model.OneYearExpirationDate';
|
||||||
|
@ -17,7 +17,6 @@ public class FreshdeskController : Controller
|
|||||||
private readonly BillingSettings _billingSettings;
|
private readonly BillingSettings _billingSettings;
|
||||||
private readonly IUserRepository _userRepository;
|
private readonly IUserRepository _userRepository;
|
||||||
private readonly IOrganizationRepository _organizationRepository;
|
private readonly IOrganizationRepository _organizationRepository;
|
||||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
|
||||||
private readonly ILogger<FreshdeskController> _logger;
|
private readonly ILogger<FreshdeskController> _logger;
|
||||||
private readonly GlobalSettings _globalSettings;
|
private readonly GlobalSettings _globalSettings;
|
||||||
private readonly IHttpClientFactory _httpClientFactory;
|
private readonly IHttpClientFactory _httpClientFactory;
|
||||||
@ -25,7 +24,6 @@ public class FreshdeskController : Controller
|
|||||||
public FreshdeskController(
|
public FreshdeskController(
|
||||||
IUserRepository userRepository,
|
IUserRepository userRepository,
|
||||||
IOrganizationRepository organizationRepository,
|
IOrganizationRepository organizationRepository,
|
||||||
IOrganizationUserRepository organizationUserRepository,
|
|
||||||
IOptions<BillingSettings> billingSettings,
|
IOptions<BillingSettings> billingSettings,
|
||||||
ILogger<FreshdeskController> logger,
|
ILogger<FreshdeskController> logger,
|
||||||
GlobalSettings globalSettings,
|
GlobalSettings globalSettings,
|
||||||
@ -34,7 +32,6 @@ public class FreshdeskController : Controller
|
|||||||
_billingSettings = billingSettings?.Value;
|
_billingSettings = billingSettings?.Value;
|
||||||
_userRepository = userRepository;
|
_userRepository = userRepository;
|
||||||
_organizationRepository = organizationRepository;
|
_organizationRepository = organizationRepository;
|
||||||
_organizationUserRepository = organizationUserRepository;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_globalSettings = globalSettings;
|
_globalSettings = globalSettings;
|
||||||
_httpClientFactory = httpClientFactory;
|
_httpClientFactory = httpClientFactory;
|
||||||
|
@ -1,53 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
|
|
||||||
namespace Billing.Controllers;
|
|
||||||
|
|
||||||
public class LoginController : Controller
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
private readonly PasswordlessSignInManager<IdentityUser> _signInManager;
|
|
||||||
|
|
||||||
public LoginController(
|
|
||||||
PasswordlessSignInManager<IdentityUser> signInManager)
|
|
||||||
{
|
|
||||||
_signInManager = signInManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IActionResult Index()
|
|
||||||
{
|
|
||||||
return View();
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost]
|
|
||||||
[ValidateAntiForgeryToken]
|
|
||||||
public async Task<IActionResult> Index(LoginModel model)
|
|
||||||
{
|
|
||||||
if (ModelState.IsValid)
|
|
||||||
{
|
|
||||||
var result = await _signInManager.PasswordlessSignInAsync(model.Email,
|
|
||||||
Url.Action("Confirm", "Login", null, Request.Scheme));
|
|
||||||
if (result.Succeeded)
|
|
||||||
{
|
|
||||||
return RedirectToAction("Index", "Home");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ModelState.AddModelError(string.Empty, "Account not found.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return View(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IActionResult> Confirm(string email, string token)
|
|
||||||
{
|
|
||||||
var result = await _signInManager.PasswordlessSignInAsync(email, token, false);
|
|
||||||
if (!result.Succeeded)
|
|
||||||
{
|
|
||||||
return View("Error");
|
|
||||||
}
|
|
||||||
|
|
||||||
return RedirectToAction("Index", "Home");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
@ -1,7 +1,6 @@
|
|||||||
using Bit.Billing.Constants;
|
using Bit.Billing.Constants;
|
||||||
using Bit.Core.AdminConsole.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.AdminConsole.Repositories;
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
using Bit.Core.Billing.Constants;
|
|
||||||
using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.Interfaces;
|
using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.Interfaces;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
@ -161,18 +160,13 @@ public class UpcomingInvoiceHandler : IUpcomingInvoiceHandler
|
|||||||
|
|
||||||
private async Task<Subscription> TryEnableAutomaticTaxAsync(Subscription subscription)
|
private async Task<Subscription> TryEnableAutomaticTaxAsync(Subscription subscription)
|
||||||
{
|
{
|
||||||
var customerGetOptions = new CustomerGetOptions { Expand = ["tax"] };
|
if (subscription.AutomaticTax.Enabled)
|
||||||
var customer = await _stripeFacade.GetCustomer(subscription.CustomerId, customerGetOptions);
|
|
||||||
|
|
||||||
if (subscription.AutomaticTax.Enabled ||
|
|
||||||
customer.Tax?.AutomaticTax != StripeConstants.AutomaticTaxStatus.Supported)
|
|
||||||
{
|
{
|
||||||
return subscription;
|
return subscription;
|
||||||
}
|
}
|
||||||
|
|
||||||
var subscriptionUpdateOptions = new SubscriptionUpdateOptions
|
var subscriptionUpdateOptions = new SubscriptionUpdateOptions
|
||||||
{
|
{
|
||||||
DefaultTaxRates = [],
|
|
||||||
AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true }
|
AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -360,7 +360,7 @@ public class OrganizationBillingService(
|
|||||||
{
|
{
|
||||||
AutomaticTax = new SubscriptionAutomaticTaxOptions
|
AutomaticTax = new SubscriptionAutomaticTaxOptions
|
||||||
{
|
{
|
||||||
Enabled = customer.Tax?.AutomaticTax == StripeConstants.AutomaticTaxStatus.Supported
|
Enabled = true
|
||||||
},
|
},
|
||||||
CollectionMethod = StripeConstants.CollectionMethod.ChargeAutomatically,
|
CollectionMethod = StripeConstants.CollectionMethod.ChargeAutomatically,
|
||||||
Customer = customer.Id,
|
Customer = customer.Id,
|
||||||
|
@ -235,7 +235,7 @@ public class PremiumUserBillingService(
|
|||||||
{
|
{
|
||||||
AutomaticTax = new SubscriptionAutomaticTaxOptions
|
AutomaticTax = new SubscriptionAutomaticTaxOptions
|
||||||
{
|
{
|
||||||
Enabled = customer.Tax?.AutomaticTax == StripeConstants.AutomaticTaxStatus.Supported,
|
Enabled = true
|
||||||
},
|
},
|
||||||
CollectionMethod = StripeConstants.CollectionMethod.ChargeAutomatically,
|
CollectionMethod = StripeConstants.CollectionMethod.ChargeAutomatically,
|
||||||
Customer = customer.Id,
|
Customer = customer.Id,
|
||||||
|
@ -661,23 +661,13 @@ public class SubscriberService(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SubscriberIsEligibleForAutomaticTax(subscriber, customer))
|
|
||||||
{
|
|
||||||
await stripeAdapter.SubscriptionUpdateAsync(subscriber.GatewaySubscriptionId,
|
await stripeAdapter.SubscriptionUpdateAsync(subscriber.GatewaySubscriptionId,
|
||||||
new SubscriptionUpdateOptions
|
new SubscriptionUpdateOptions
|
||||||
{
|
{
|
||||||
AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true }
|
AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool SubscriberIsEligibleForAutomaticTax(ISubscriber localSubscriber, Customer localCustomer)
|
|
||||||
=> !string.IsNullOrEmpty(localSubscriber.GatewaySubscriptionId) &&
|
|
||||||
(localCustomer.Subscriptions?.Any(sub => sub.Id == localSubscriber.GatewaySubscriptionId && !sub.AutomaticTax.Enabled) ?? false) &&
|
|
||||||
localCustomer.Tax?.AutomaticTax == StripeConstants.AutomaticTaxStatus.Supported;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task VerifyBankAccount(
|
public async Task VerifyBankAccount(
|
||||||
ISubscriber subscriber,
|
ISubscriber subscriber,
|
||||||
string descriptorCode)
|
string descriptorCode)
|
||||||
|
@ -167,6 +167,7 @@ public static class FeatureFlagKeys
|
|||||||
public const string UserkeyRotationV2 = "userkey-rotation-v2";
|
public const string UserkeyRotationV2 = "userkey-rotation-v2";
|
||||||
public const string EnablePasswordManagerSyncAndroid = "enable-password-manager-sync-android";
|
public const string EnablePasswordManagerSyncAndroid = "enable-password-manager-sync-android";
|
||||||
public const string EnablePasswordManagerSynciOS = "enable-password-manager-sync-ios";
|
public const string EnablePasswordManagerSynciOS = "enable-password-manager-sync-ios";
|
||||||
|
public const string AccountDeprovisioningBanner = "pm-17120-account-deprovisioning-admin-console-banner";
|
||||||
|
|
||||||
public static List<string> GetAllKeys()
|
public static List<string> GetAllKeys()
|
||||||
{
|
{
|
||||||
|
@ -177,11 +177,7 @@ public class StripePaymentService : IPaymentService
|
|||||||
customer = await _stripeAdapter.CustomerCreateAsync(customerCreateOptions);
|
customer = await _stripeAdapter.CustomerCreateAsync(customerCreateOptions);
|
||||||
subCreateOptions.AddExpand("latest_invoice.payment_intent");
|
subCreateOptions.AddExpand("latest_invoice.payment_intent");
|
||||||
subCreateOptions.Customer = customer.Id;
|
subCreateOptions.Customer = customer.Id;
|
||||||
|
|
||||||
if (CustomerHasTaxLocationVerified(customer))
|
|
||||||
{
|
|
||||||
subCreateOptions.AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true };
|
subCreateOptions.AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true };
|
||||||
}
|
|
||||||
|
|
||||||
subscription = await _stripeAdapter.SubscriptionCreateAsync(subCreateOptions);
|
subscription = await _stripeAdapter.SubscriptionCreateAsync(subCreateOptions);
|
||||||
if (subscription.Status == "incomplete" && subscription.LatestInvoice?.PaymentIntent != null)
|
if (subscription.Status == "incomplete" && subscription.LatestInvoice?.PaymentIntent != null)
|
||||||
@ -362,13 +358,10 @@ public class StripePaymentService : IPaymentService
|
|||||||
customer = await _stripeAdapter.CustomerUpdateAsync(org.GatewayCustomerId, customerUpdateOptions);
|
customer = await _stripeAdapter.CustomerUpdateAsync(org.GatewayCustomerId, customerUpdateOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
var subCreateOptions = new OrganizationUpgradeSubscriptionOptions(customer.Id, org, plan, upgrade);
|
var subCreateOptions = new OrganizationUpgradeSubscriptionOptions(customer.Id, org, plan, upgrade)
|
||||||
|
|
||||||
if (CustomerHasTaxLocationVerified(customer))
|
|
||||||
{
|
{
|
||||||
subCreateOptions.DefaultTaxRates = [];
|
AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true }
|
||||||
subCreateOptions.AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true };
|
};
|
||||||
}
|
|
||||||
|
|
||||||
var (stripePaymentMethod, paymentMethodType) = IdentifyPaymentMethod(customer, subCreateOptions);
|
var (stripePaymentMethod, paymentMethodType) = IdentifyPaymentMethod(customer, subCreateOptions);
|
||||||
|
|
||||||
@ -527,6 +520,10 @@ public class StripePaymentService : IPaymentService
|
|||||||
|
|
||||||
var customerCreateOptions = new CustomerCreateOptions
|
var customerCreateOptions = new CustomerCreateOptions
|
||||||
{
|
{
|
||||||
|
Tax = new CustomerTaxOptions
|
||||||
|
{
|
||||||
|
ValidateLocation = StripeConstants.ValidateTaxLocationTiming.Immediately
|
||||||
|
},
|
||||||
Description = user.Name,
|
Description = user.Name,
|
||||||
Email = user.Email,
|
Email = user.Email,
|
||||||
Metadata = stripeCustomerMetadata,
|
Metadata = stripeCustomerMetadata,
|
||||||
@ -564,6 +561,7 @@ public class StripePaymentService : IPaymentService
|
|||||||
|
|
||||||
var subCreateOptions = new SubscriptionCreateOptions
|
var subCreateOptions = new SubscriptionCreateOptions
|
||||||
{
|
{
|
||||||
|
AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true },
|
||||||
Customer = customer.Id,
|
Customer = customer.Id,
|
||||||
Items = [],
|
Items = [],
|
||||||
Metadata = new Dictionary<string, string>
|
Metadata = new Dictionary<string, string>
|
||||||
@ -583,16 +581,10 @@ public class StripePaymentService : IPaymentService
|
|||||||
subCreateOptions.Items.Add(new SubscriptionItemOptions
|
subCreateOptions.Items.Add(new SubscriptionItemOptions
|
||||||
{
|
{
|
||||||
Plan = StoragePlanId,
|
Plan = StoragePlanId,
|
||||||
Quantity = additionalStorageGb
|
Quantity = additionalStorageGb,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CustomerHasTaxLocationVerified(customer))
|
|
||||||
{
|
|
||||||
subCreateOptions.DefaultTaxRates = [];
|
|
||||||
subCreateOptions.AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true };
|
|
||||||
}
|
|
||||||
|
|
||||||
var subscription = await ChargeForNewSubscriptionAsync(user, customer, createdStripeCustomer,
|
var subscription = await ChargeForNewSubscriptionAsync(user, customer, createdStripeCustomer,
|
||||||
stripePaymentMethod, paymentMethodType, subCreateOptions, braintreeCustomer);
|
stripePaymentMethod, paymentMethodType, subCreateOptions, braintreeCustomer);
|
||||||
|
|
||||||
@ -630,10 +622,7 @@ public class StripePaymentService : IPaymentService
|
|||||||
SubscriptionItems = ToInvoiceSubscriptionItemOptions(subCreateOptions.Items)
|
SubscriptionItems = ToInvoiceSubscriptionItemOptions(subCreateOptions.Items)
|
||||||
});
|
});
|
||||||
|
|
||||||
if (CustomerHasTaxLocationVerified(customer))
|
|
||||||
{
|
|
||||||
previewInvoice.AutomaticTax = new InvoiceAutomaticTax { Enabled = true };
|
previewInvoice.AutomaticTax = new InvoiceAutomaticTax { Enabled = true };
|
||||||
}
|
|
||||||
|
|
||||||
if (previewInvoice.AmountDue > 0)
|
if (previewInvoice.AmountDue > 0)
|
||||||
{
|
{
|
||||||
@ -691,13 +680,11 @@ public class StripePaymentService : IPaymentService
|
|||||||
Customer = customer.Id,
|
Customer = customer.Id,
|
||||||
SubscriptionItems = ToInvoiceSubscriptionItemOptions(subCreateOptions.Items),
|
SubscriptionItems = ToInvoiceSubscriptionItemOptions(subCreateOptions.Items),
|
||||||
SubscriptionDefaultTaxRates = subCreateOptions.DefaultTaxRates,
|
SubscriptionDefaultTaxRates = subCreateOptions.DefaultTaxRates,
|
||||||
};
|
AutomaticTax = new InvoiceAutomaticTaxOptions
|
||||||
|
|
||||||
if (CustomerHasTaxLocationVerified(customer))
|
|
||||||
{
|
{
|
||||||
upcomingInvoiceOptions.AutomaticTax = new InvoiceAutomaticTaxOptions { Enabled = true };
|
Enabled = true
|
||||||
upcomingInvoiceOptions.SubscriptionDefaultTaxRates = [];
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var previewInvoice = await _stripeAdapter.InvoiceUpcomingAsync(upcomingInvoiceOptions);
|
var previewInvoice = await _stripeAdapter.InvoiceUpcomingAsync(upcomingInvoiceOptions);
|
||||||
|
|
||||||
@ -817,7 +804,11 @@ public class StripePaymentService : IPaymentService
|
|||||||
Items = updatedItemOptions,
|
Items = updatedItemOptions,
|
||||||
ProrationBehavior = invoiceNow ? Constants.AlwaysInvoice : Constants.CreateProrations,
|
ProrationBehavior = invoiceNow ? Constants.AlwaysInvoice : Constants.CreateProrations,
|
||||||
DaysUntilDue = daysUntilDue ?? 1,
|
DaysUntilDue = daysUntilDue ?? 1,
|
||||||
CollectionMethod = "send_invoice"
|
CollectionMethod = "send_invoice",
|
||||||
|
AutomaticTax = new SubscriptionAutomaticTaxOptions
|
||||||
|
{
|
||||||
|
Enabled = true
|
||||||
|
}
|
||||||
};
|
};
|
||||||
if (!invoiceNow && isAnnualPlan && sub.Status.Trim() != "trialing")
|
if (!invoiceNow && isAnnualPlan && sub.Status.Trim() != "trialing")
|
||||||
{
|
{
|
||||||
@ -825,13 +816,6 @@ public class StripePaymentService : IPaymentService
|
|||||||
new SubscriptionPendingInvoiceItemIntervalOptions { Interval = "month" };
|
new SubscriptionPendingInvoiceItemIntervalOptions { Interval = "month" };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sub.AutomaticTax.Enabled != true &&
|
|
||||||
CustomerHasTaxLocationVerified(sub.Customer))
|
|
||||||
{
|
|
||||||
subUpdateOptions.DefaultTaxRates = [];
|
|
||||||
subUpdateOptions.AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!subscriptionUpdate.UpdateNeeded(sub))
|
if (!subscriptionUpdate.UpdateNeeded(sub))
|
||||||
{
|
{
|
||||||
// No need to update subscription, quantity matches
|
// No need to update subscription, quantity matches
|
||||||
@ -1516,13 +1500,11 @@ public class StripePaymentService : IPaymentService
|
|||||||
if (!string.IsNullOrEmpty(subscriber.GatewaySubscriptionId) &&
|
if (!string.IsNullOrEmpty(subscriber.GatewaySubscriptionId) &&
|
||||||
customer.Subscriptions.Any(sub =>
|
customer.Subscriptions.Any(sub =>
|
||||||
sub.Id == subscriber.GatewaySubscriptionId &&
|
sub.Id == subscriber.GatewaySubscriptionId &&
|
||||||
!sub.AutomaticTax.Enabled) &&
|
!sub.AutomaticTax.Enabled))
|
||||||
CustomerHasTaxLocationVerified(customer))
|
|
||||||
{
|
{
|
||||||
var subscriptionUpdateOptions = new SubscriptionUpdateOptions
|
var subscriptionUpdateOptions = new SubscriptionUpdateOptions
|
||||||
{
|
{
|
||||||
AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true },
|
AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true }
|
||||||
DefaultTaxRates = []
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_ = await _stripeAdapter.SubscriptionUpdateAsync(
|
_ = await _stripeAdapter.SubscriptionUpdateAsync(
|
||||||
@ -2280,14 +2262,6 @@ public class StripePaymentService : IPaymentService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Determines if a Stripe customer supports automatic tax
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="customer"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private static bool CustomerHasTaxLocationVerified(Customer customer) =>
|
|
||||||
customer?.Tax?.AutomaticTax == StripeConstants.AutomaticTaxStatus.Supported;
|
|
||||||
|
|
||||||
// We are taking only first 30 characters of the SubscriberName because stripe provide
|
// We are taking only first 30 characters of the SubscriberName because stripe provide
|
||||||
// for 30 characters for custom_fields,see the link: https://stripe.com/docs/api/invoices/create
|
// for 30 characters for custom_fields,see the link: https://stripe.com/docs/api/invoices/create
|
||||||
private static string GetFirstThirtyCharacters(string subscriberName)
|
private static string GetFirstThirtyCharacters(string subscriberName)
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="coverlet.collector" Version="6.0.2">
|
<PackageReference Include="coverlet.collector" Version="6.0.4">
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
Loading…
Reference in New Issue
Block a user