mirror of
https://github.com/bitwarden/server
synced 2025-12-15 15:53:59 +00:00
* Add new endpoint for creating client organizations in consolidated billing * Create empty org and then assign seats for code re-use * Fixes made from debugging client side * few more small fixes * Vincent's feedback
90 lines
3.1 KiB
C#
90 lines
3.1 KiB
C#
using Bit.Core.AdminConsole.Entities;
|
|
using Bit.Core.AdminConsole.Entities.Provider;
|
|
using Bit.Core.Billing.Queries;
|
|
using Bit.Core.Repositories;
|
|
using Bit.Core.Services;
|
|
using Bit.Core.Settings;
|
|
using Microsoft.Extensions.Logging;
|
|
using Stripe;
|
|
|
|
namespace Bit.Core.Billing.Commands.Implementations;
|
|
|
|
public class CreateCustomerCommand(
|
|
IGlobalSettings globalSettings,
|
|
ILogger<CreateCustomerCommand> logger,
|
|
IOrganizationRepository organizationRepository,
|
|
IStripeAdapter stripeAdapter,
|
|
ISubscriberQueries subscriberQueries) : ICreateCustomerCommand
|
|
{
|
|
public async Task CreateCustomer(
|
|
Provider provider,
|
|
Organization organization)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(provider);
|
|
ArgumentNullException.ThrowIfNull(organization);
|
|
|
|
if (!string.IsNullOrEmpty(organization.GatewayCustomerId))
|
|
{
|
|
logger.LogWarning("Client organization ({ID}) already has a populated {FieldName}", organization.Id, nameof(organization.GatewayCustomerId));
|
|
|
|
return;
|
|
}
|
|
|
|
var providerCustomer = await subscriberQueries.GetCustomerOrThrow(provider, new CustomerGetOptions
|
|
{
|
|
Expand = ["tax_ids"]
|
|
});
|
|
|
|
var providerTaxId = providerCustomer.TaxIds.FirstOrDefault();
|
|
|
|
var organizationDisplayName = organization.DisplayName();
|
|
|
|
var customerCreateOptions = new CustomerCreateOptions
|
|
{
|
|
Address = new AddressOptions
|
|
{
|
|
Country = providerCustomer.Address?.Country,
|
|
PostalCode = providerCustomer.Address?.PostalCode,
|
|
Line1 = providerCustomer.Address?.Line1,
|
|
Line2 = providerCustomer.Address?.Line2,
|
|
City = providerCustomer.Address?.City,
|
|
State = providerCustomer.Address?.State
|
|
},
|
|
Name = organizationDisplayName,
|
|
Description = $"{provider.Name} Client Organization",
|
|
Email = provider.BillingEmail,
|
|
InvoiceSettings = new CustomerInvoiceSettingsOptions
|
|
{
|
|
CustomFields =
|
|
[
|
|
new CustomerInvoiceSettingsCustomFieldOptions
|
|
{
|
|
Name = organization.SubscriberType(),
|
|
Value = organizationDisplayName.Length <= 30
|
|
? organizationDisplayName
|
|
: organizationDisplayName[..30]
|
|
}
|
|
]
|
|
},
|
|
Metadata = new Dictionary<string, string>
|
|
{
|
|
{ "region", globalSettings.BaseServiceUri.CloudRegion }
|
|
},
|
|
TaxIdData = providerTaxId == null ? null :
|
|
[
|
|
new CustomerTaxIdDataOptions
|
|
{
|
|
Type = providerTaxId.Type,
|
|
Value = providerTaxId.Value
|
|
}
|
|
]
|
|
};
|
|
|
|
var customer = await stripeAdapter.CustomerCreateAsync(customerCreateOptions);
|
|
|
|
organization.GatewayCustomerId = customer.Id;
|
|
|
|
await organizationRepository.ReplaceAsync(organization);
|
|
}
|
|
}
|