1
0
mirror of https://github.com/bitwarden/server synced 2026-01-06 02:23:51 +00:00

[PM-19956] [PM-18795] Require provider payment method during setup behind FF (#5752)

* Require provider payment method during setup behind FF

* Fix failing test

* Run dotnet format

* Rui's feedback
This commit is contained in:
Alex Morask
2025-05-01 12:12:45 -04:00
committed by GitHub
parent dc5db5673f
commit e77acbc5ad
10 changed files with 848 additions and 32 deletions

View File

@@ -84,22 +84,22 @@ public class ProvidersController : Controller
var userId = _userService.GetProperUserId(User).Value;
var taxInfo = model.TaxInfo != null
? new TaxInfo
{
BillingAddressCountry = model.TaxInfo.Country,
BillingAddressPostalCode = model.TaxInfo.PostalCode,
TaxIdNumber = model.TaxInfo.TaxId,
BillingAddressLine1 = model.TaxInfo.Line1,
BillingAddressLine2 = model.TaxInfo.Line2,
BillingAddressCity = model.TaxInfo.City,
BillingAddressState = model.TaxInfo.State
}
: null;
var taxInfo = new TaxInfo
{
BillingAddressCountry = model.TaxInfo.Country,
BillingAddressPostalCode = model.TaxInfo.PostalCode,
TaxIdNumber = model.TaxInfo.TaxId,
BillingAddressLine1 = model.TaxInfo.Line1,
BillingAddressLine2 = model.TaxInfo.Line2,
BillingAddressCity = model.TaxInfo.City,
BillingAddressState = model.TaxInfo.State
};
var tokenizedPaymentSource = model.PaymentSource?.ToDomain();
var response =
await _providerService.CompleteSetupAsync(model.ToProvider(provider), userId, model.Token, model.Key,
taxInfo);
taxInfo, tokenizedPaymentSource);
return new ProviderResponseModel(response);
}

View File

@@ -1,5 +1,6 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using Bit.Api.Billing.Models.Requests;
using Bit.Api.Models.Request;
using Bit.Core.AdminConsole.Entities.Provider;
using Bit.Core.Utilities;
@@ -23,7 +24,9 @@ public class ProviderSetupRequestModel
public string Token { get; set; }
[Required]
public string Key { get; set; }
[Required]
public ExpandedTaxInfoUpdateRequestModel TaxInfo { get; set; }
public TokenizedPaymentSourceRequestBody PaymentSource { get; set; }
public virtual Provider ToProvider(Provider provider)
{

View File

@@ -1,5 +1,6 @@
using Bit.Core.AdminConsole.Entities.Provider;
using Bit.Core.AdminConsole.Models.Business.Provider;
using Bit.Core.Billing.Models;
using Bit.Core.Entities;
using Bit.Core.Models.Business;
@@ -7,7 +8,8 @@ namespace Bit.Core.AdminConsole.Services;
public interface IProviderService
{
Task<Provider> CompleteSetupAsync(Provider provider, Guid ownerUserId, string token, string key, TaxInfo taxInfo = null);
Task<Provider> CompleteSetupAsync(Provider provider, Guid ownerUserId, string token, string key, TaxInfo taxInfo,
TokenizedPaymentSource tokenizedPaymentSource = null);
Task UpdateAsync(Provider provider, bool updateBilling = false);
Task<List<ProviderUser>> InviteUserAsync(ProviderUserInvite<string> invite);

View File

@@ -1,5 +1,6 @@
using Bit.Core.AdminConsole.Entities.Provider;
using Bit.Core.AdminConsole.Models.Business.Provider;
using Bit.Core.Billing.Models;
using Bit.Core.Entities;
using Bit.Core.Models.Business;
@@ -7,7 +8,7 @@ namespace Bit.Core.AdminConsole.Services.NoopImplementations;
public class NoopProviderService : IProviderService
{
public Task<Provider> CompleteSetupAsync(Provider provider, Guid ownerUserId, string token, string key, TaxInfo taxInfo = null) => throw new NotImplementedException();
public Task<Provider> CompleteSetupAsync(Provider provider, Guid ownerUserId, string token, string key, TaxInfo taxInfo, TokenizedPaymentSource tokenizedPaymentSource = null) => throw new NotImplementedException();
public Task UpdateAsync(Provider provider, bool updateBilling = false) => throw new NotImplementedException();

View File

@@ -79,10 +79,12 @@ public interface IProviderBillingService
/// </summary>
/// <param name="provider">The <see cref="Provider"/> to create a Stripe customer for.</param>
/// <param name="taxInfo">The <see cref="TaxInfo"/> to use for calculating the customer's automatic tax.</param>
/// <param name="tokenizedPaymentSource">The <see cref="TokenizedPaymentSource"/> (ex. Credit Card) to attach to the customer.</param>
/// <returns>The newly created <see cref="Stripe.Customer"/> for the <paramref name="provider"/>.</returns>
Task<Customer> SetupCustomer(
Provider provider,
TaxInfo taxInfo);
TaxInfo taxInfo,
TokenizedPaymentSource tokenizedPaymentSource = null);
/// <summary>
/// For use during the provider setup process, this method starts a Stripe <see cref="Stripe.Subscription"/> for the given <paramref name="provider"/>.

View File

@@ -149,6 +149,7 @@ public static class FeatureFlagKeys
public const string PM19422_AllowAutomaticTaxUpdates = "pm-19422-allow-automatic-tax-updates";
public const string PM18770_EnableOrganizationBusinessUnitConversion = "pm-18770-enable-organization-business-unit-conversion";
public const string PM199566_UpdateMSPToChargeAutomatically = "pm-199566-update-msp-to-charge-automatically";
public const string PM19956_RequireProviderPaymentMethodDuringSetup = "pm-19956-require-provider-payment-method-during-setup";
/* Data Insights and Reporting Team */
public const string RiskInsightsCriticalApplication = "pm-14466-risk-insights-critical-application";