1
0
mirror of https://github.com/bitwarden/server synced 2025-12-21 18:53:41 +00:00

[PM-24616] refactor stripe adapter (#6527)

* move billing services+tests to billing namespaces

* reorganized methods in file and added comment headers

* renamed StripeAdapter methods for better clarity

* clean up redundant qualifiers

* Upgrade Stripe.net to v48.4.0

* Update PreviewTaxAmountCommand

* Remove unused UpcomingInvoiceOptionExtensions

* Added SubscriptionExtensions with GetCurrentPeriodEnd

* Update PremiumUserBillingService

* Update OrganizationBillingService

* Update GetOrganizationWarningsQuery

* Update BillingHistoryInfo

* Update SubscriptionInfo

* Remove unused Sql Billing folder

* Update StripeAdapter

* Update StripePaymentService

* Update InvoiceCreatedHandler

* Update PaymentFailedHandler

* Update PaymentSucceededHandler

* Update ProviderEventService

* Update StripeEventUtilityService

* Update SubscriptionDeletedHandler

* Update SubscriptionUpdatedHandler

* Update UpcomingInvoiceHandler

* Update ProviderSubscriptionResponse

* Remove unused Stripe Subscriptions Admin Tool

* Update RemoveOrganizationFromProviderCommand

* Update ProviderBillingService

* Update RemoveOrganizatinoFromProviderCommandTests

* Update PreviewTaxAmountCommandTests

* Update GetCloudOrganizationLicenseQueryTests

* Update GetOrganizationWarningsQueryTests

* Update StripePaymentServiceTests

* Update ProviderBillingControllerTests

* Update ProviderEventServiceTests

* Update SubscriptionDeletedHandlerTests

* Update SubscriptionUpdatedHandlerTests

* Resolve Billing test failures

I completely removed tests for the StripeEventService as they were using a system I setup a while back that read JSON files of the Stripe event structure. I did not anticipate how frequently these structures would change with each API version and the cost of trying to update these specific JSON files to test a very static data retrieval service far outweigh the benefit.

* Resolve Core test failures

* Run dotnet format

* Remove unused provider migration

* Fixed failing tests

* Run dotnet format

* Replace the old webhook secret key with new one (#6223)

* Fix compilation failures in additions

* Run dotnet format

* Bump Stripe API version

* Fix recent addition: CreatePremiumCloudHostedSubscriptionCommand

* Fix new code in main according to Stripe update

* Fix InvoiceExtensions

* Bump SDK version to match API Version

* cleanup

* fixing items missed after the merge

* use expression body for all simple returns

* forgot fixes, format, and pr feedback

* claude pr feedback

* pr feedback and cleanup

* more claude feedback

---------

Co-authored-by: Alex Morask <amorask@bitwarden.com>
Co-authored-by: cyprain-okeke <108260115+cyprain-okeke@users.noreply.github.com>
This commit is contained in:
Kyle Denney
2025-12-12 15:32:43 -06:00
committed by GitHub
parent 196e555116
commit 99e1326039
100 changed files with 941 additions and 1016 deletions

1
.gitignore vendored
View File

@@ -234,6 +234,7 @@ bitwarden_license/src/Sso/Sso.zip
/identity.json
/api.json
/api.public.json
.serena/
# Serena
.serena/

View File

@@ -113,7 +113,7 @@ public class RemoveOrganizationFromProviderCommand : IRemoveOrganizationFromProv
await _providerBillingService.CreateCustomerForClientOrganization(provider, organization);
}
var customer = await _stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId, new CustomerUpdateOptions
var customer = await _stripeAdapter.UpdateCustomerAsync(organization.GatewayCustomerId, new CustomerUpdateOptions
{
Description = string.Empty,
Email = organization.BillingEmail,
@@ -138,7 +138,7 @@ public class RemoveOrganizationFromProviderCommand : IRemoveOrganizationFromProv
subscriptionCreateOptions.AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true };
var subscription = await _stripeAdapter.SubscriptionCreateAsync(subscriptionCreateOptions);
var subscription = await _stripeAdapter.CreateSubscriptionAsync(subscriptionCreateOptions);
organization.GatewaySubscriptionId = subscription.Id;
organization.Status = OrganizationStatusType.Created;
@@ -148,27 +148,26 @@ public class RemoveOrganizationFromProviderCommand : IRemoveOrganizationFromProv
}
else if (organization.IsStripeEnabled())
{
var subscription = await _stripeAdapter.SubscriptionGetAsync(organization.GatewaySubscriptionId, new SubscriptionGetOptions
var subscription = await _stripeAdapter.GetSubscriptionAsync(organization.GatewaySubscriptionId, new SubscriptionGetOptions
{
Expand = ["customer"]
});
if (subscription.Status is StripeConstants.SubscriptionStatus.Canceled or StripeConstants.SubscriptionStatus.IncompleteExpired)
{
return;
}
await _stripeAdapter.CustomerUpdateAsync(subscription.CustomerId, new CustomerUpdateOptions
await _stripeAdapter.UpdateCustomerAsync(subscription.CustomerId, new CustomerUpdateOptions
{
Email = organization.BillingEmail
});
if (subscription.Customer.Discount?.Coupon != null)
{
await _stripeAdapter.CustomerDeleteDiscountAsync(subscription.CustomerId);
await _stripeAdapter.DeleteCustomerDiscountAsync(subscription.CustomerId);
}
await _stripeAdapter.SubscriptionUpdateAsync(organization.GatewaySubscriptionId, new SubscriptionUpdateOptions
await _stripeAdapter.UpdateSubscriptionAsync(organization.GatewaySubscriptionId, new SubscriptionUpdateOptions
{
CollectionMethod = StripeConstants.CollectionMethod.SendInvoice,
DaysUntilDue = 30,

View File

@@ -15,6 +15,7 @@ using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Payment.Models;
using Bit.Core.Billing.Pricing;
using Bit.Core.Billing.Providers.Services;
using Bit.Core.Billing.Services;
using Bit.Core.Context;
using Bit.Core.Entities;
using Bit.Core.Enums;
@@ -427,7 +428,7 @@ public class ProviderService : IProviderService
if (!string.IsNullOrEmpty(organization.GatewayCustomerId))
{
await _stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId, new CustomerUpdateOptions
await _stripeAdapter.UpdateCustomerAsync(organization.GatewayCustomerId, new CustomerUpdateOptions
{
Email = provider.BillingEmail
});
@@ -487,7 +488,7 @@ public class ProviderService : IProviderService
private async Task<SubscriptionItem> GetSubscriptionItemAsync(string subscriptionId, string oldPlanId)
{
var subscriptionDetails = await _stripeAdapter.SubscriptionGetAsync(subscriptionId);
var subscriptionDetails = await _stripeAdapter.GetSubscriptionAsync(subscriptionId);
return subscriptionDetails.Items.Data.FirstOrDefault(item => item.Price.Id == oldPlanId);
}
@@ -497,7 +498,7 @@ public class ProviderService : IProviderService
{
if (subscriptionItem.Price.Id != extractedPlanType)
{
await _stripeAdapter.SubscriptionUpdateAsync(subscriptionItem.Subscription,
await _stripeAdapter.UpdateSubscriptionAsync(subscriptionItem.Subscription,
new Stripe.SubscriptionUpdateOptions
{
Items = new List<Stripe.SubscriptionItemOptions>

View File

@@ -4,7 +4,6 @@ using Bit.Core.Billing.Providers.Models;
using Bit.Core.Billing.Providers.Queries;
using Bit.Core.Billing.Services;
using Bit.Core.Context;
using Bit.Core.Services;
using Stripe;
using Stripe.Tax;
@@ -76,8 +75,8 @@ public class GetProviderWarningsQuery(
// Get active and scheduled registrations
var registrations = (await Task.WhenAll(
stripeAdapter.TaxRegistrationsListAsync(new RegistrationListOptions { Status = TaxRegistrationStatus.Active }),
stripeAdapter.TaxRegistrationsListAsync(new RegistrationListOptions { Status = TaxRegistrationStatus.Scheduled })))
stripeAdapter.ListTaxRegistrationsAsync(new RegistrationListOptions { Status = TaxRegistrationStatus.Active }),
stripeAdapter.ListTaxRegistrationsAsync(new RegistrationListOptions { Status = TaxRegistrationStatus.Scheduled })))
.SelectMany(registrations => registrations.Data);
// Find the matching registration for the customer

View File

@@ -101,7 +101,7 @@ public class BusinessUnitConverter(
providerUser.Status = ProviderUserStatusType.Confirmed;
// Stripe requires that we clear all the custom fields from the invoice settings if we want to replace them.
await stripeAdapter.CustomerUpdateAsync(subscription.CustomerId, new CustomerUpdateOptions
await stripeAdapter.UpdateCustomerAsync(subscription.CustomerId, new CustomerUpdateOptions
{
InvoiceSettings = new CustomerInvoiceSettingsOptions
{
@@ -116,7 +116,7 @@ public class BusinessUnitConverter(
["convertedFrom"] = organization.Id.ToString()
};
var updateCustomer = stripeAdapter.CustomerUpdateAsync(subscription.CustomerId, new CustomerUpdateOptions
var updateCustomer = stripeAdapter.UpdateCustomerAsync(subscription.CustomerId, new CustomerUpdateOptions
{
InvoiceSettings = new CustomerInvoiceSettingsOptions
{
@@ -148,7 +148,7 @@ public class BusinessUnitConverter(
// Replace the existing password manager price with the new business unit price.
var updateSubscription =
stripeAdapter.SubscriptionUpdateAsync(subscription.Id,
stripeAdapter.UpdateSubscriptionAsync(subscription.Id,
new SubscriptionUpdateOptions
{
Items = [

View File

@@ -61,11 +61,11 @@ public class ProviderBillingService(
Organization organization,
string key)
{
await stripeAdapter.SubscriptionUpdateAsync(organization.GatewaySubscriptionId,
await stripeAdapter.UpdateSubscriptionAsync(organization.GatewaySubscriptionId,
new SubscriptionUpdateOptions { CancelAtPeriodEnd = false });
var subscription =
await stripeAdapter.SubscriptionCancelAsync(organization.GatewaySubscriptionId,
await stripeAdapter.CancelSubscriptionAsync(organization.GatewaySubscriptionId,
new SubscriptionCancelOptions
{
CancellationDetails = new SubscriptionCancellationDetailsOptions
@@ -83,7 +83,7 @@ public class ProviderBillingService(
if (!wasTrialing && subscription.LatestInvoice.Status == InvoiceStatus.Draft)
{
await stripeAdapter.InvoiceFinalizeInvoiceAsync(subscription.LatestInvoiceId,
await stripeAdapter.FinalizeInvoiceAsync(subscription.LatestInvoiceId,
new InvoiceFinalizeOptions { AutoAdvance = true });
}
@@ -138,7 +138,7 @@ public class ProviderBillingService(
if (clientCustomer.Balance != 0)
{
await stripeAdapter.CustomerBalanceTransactionCreate(provider.GatewayCustomerId,
await stripeAdapter.CreateCustomerBalanceTransactionAsync(provider.GatewayCustomerId,
new CustomerBalanceTransactionCreateOptions
{
Amount = clientCustomer.Balance,
@@ -187,7 +187,7 @@ public class ProviderBillingService(
]
};
await stripeAdapter.SubscriptionUpdateAsync(provider.GatewaySubscriptionId, updateOptions);
await stripeAdapter.UpdateSubscriptionAsync(provider.GatewaySubscriptionId, updateOptions);
// Refactor later to ?ChangeClientPlanCommand? (ProviderPlanId, ProviderId, OrganizationId)
// 1. Retrieve PlanType and PlanName for ProviderPlan
@@ -275,7 +275,7 @@ public class ProviderBillingService(
customerCreateOptions.TaxExempt = TaxExempt.Reverse;
}
var customer = await stripeAdapter.CustomerCreateAsync(customerCreateOptions);
var customer = await stripeAdapter.CreateCustomerAsync(customerCreateOptions);
organization.GatewayCustomerId = customer.Id;
@@ -525,7 +525,7 @@ public class ProviderBillingService(
case TokenizablePaymentMethodType.BankAccount:
{
var setupIntent =
(await stripeAdapter.SetupIntentList(new SetupIntentListOptions
(await stripeAdapter.ListSetupIntentsAsync(new SetupIntentListOptions
{
PaymentMethod = paymentMethod.Token
}))
@@ -558,7 +558,7 @@ public class ProviderBillingService(
try
{
return await stripeAdapter.CustomerCreateAsync(options);
return await stripeAdapter.CreateCustomerAsync(options);
}
catch (StripeException stripeException) when (stripeException.StripeError?.Code == ErrorCodes.TaxIdInvalid)
{
@@ -580,7 +580,7 @@ public class ProviderBillingService(
case TokenizablePaymentMethodType.BankAccount:
{
var setupIntentId = await setupIntentCache.GetSetupIntentIdForSubscriber(provider.Id);
await stripeAdapter.SetupIntentCancel(setupIntentId,
await stripeAdapter.CancelSetupIntentAsync(setupIntentId,
new SetupIntentCancelOptions { CancellationReason = "abandoned" });
await setupIntentCache.RemoveSetupIntentForSubscriber(provider.Id);
break;
@@ -638,7 +638,7 @@ public class ProviderBillingService(
var setupIntentId = await setupIntentCache.GetSetupIntentIdForSubscriber(provider.Id);
var setupIntent = !string.IsNullOrEmpty(setupIntentId)
? await stripeAdapter.SetupIntentGet(setupIntentId,
? await stripeAdapter.GetSetupIntentAsync(setupIntentId,
new SetupIntentGetOptions { Expand = ["payment_method"] })
: null;
@@ -673,7 +673,7 @@ public class ProviderBillingService(
try
{
var subscription = await stripeAdapter.SubscriptionCreateAsync(subscriptionCreateOptions);
var subscription = await stripeAdapter.CreateSubscriptionAsync(subscriptionCreateOptions);
if (subscription is
{
@@ -708,7 +708,7 @@ public class ProviderBillingService(
subscriberService.UpdatePaymentSource(provider, tokenizedPaymentSource),
subscriberService.UpdateTaxInformation(provider, taxInformation));
await stripeAdapter.SubscriptionUpdateAsync(provider.GatewaySubscriptionId,
await stripeAdapter.UpdateSubscriptionAsync(provider.GatewaySubscriptionId,
new SubscriptionUpdateOptions { CollectionMethod = CollectionMethod.ChargeAutomatically });
}
@@ -791,7 +791,7 @@ public class ProviderBillingService(
if (subscriptionItemOptionsList.Count > 0)
{
await stripeAdapter.SubscriptionUpdateAsync(provider.GatewaySubscriptionId,
await stripeAdapter.UpdateSubscriptionAsync(provider.GatewaySubscriptionId,
new SubscriptionUpdateOptions { Items = subscriptionItemOptionsList });
}
}
@@ -807,7 +807,7 @@ public class ProviderBillingService(
var item = subscription.Items.First(item => item.Price.Id == priceId);
await stripeAdapter.SubscriptionUpdateAsync(provider.GatewaySubscriptionId, new SubscriptionUpdateOptions
await stripeAdapter.UpdateSubscriptionAsync(provider.GatewaySubscriptionId, new SubscriptionUpdateOptions
{
Items =
[

View File

@@ -8,6 +8,7 @@ using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.E
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models;
using Bit.Core.AdminConsole.Utilities.Commands;
using Bit.Core.Billing.Pricing;
using Bit.Core.Billing.Services;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
@@ -24,7 +25,7 @@ public class PostUserCommand(
IOrganizationRepository organizationRepository,
IOrganizationUserRepository organizationUserRepository,
IOrganizationService organizationService,
IPaymentService paymentService,
IStripePaymentService paymentService,
IScimContext scimContext,
IFeatureService featureService,
IInviteOrganizationUsersCommand inviteOrganizationUsersCommand,

View File

@@ -131,7 +131,7 @@ public class RemoveOrganizationFromProviderCommandTests
Arg.Is<IEnumerable<string>>(emails => emails.FirstOrDefault() == "a@example.com"));
await sutProvider.GetDependency<IStripeAdapter>().DidNotReceiveWithAnyArgs()
.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>());
.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>());
}
[Theory, BitAutoData]
@@ -156,7 +156,7 @@ public class RemoveOrganizationFromProviderCommandTests
"b@example.com"
]);
sutProvider.GetDependency<IStripeAdapter>().SubscriptionGetAsync(organization.GatewaySubscriptionId, Arg.Is<SubscriptionGetOptions>(
sutProvider.GetDependency<IStripeAdapter>().GetSubscriptionAsync(organization.GatewaySubscriptionId, Arg.Is<SubscriptionGetOptions>(
options => options.Expand.Contains("customer")))
.Returns(GetSubscription(organization.GatewaySubscriptionId, organization.GatewayCustomerId));
@@ -164,12 +164,14 @@ public class RemoveOrganizationFromProviderCommandTests
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
await stripeAdapter.Received(1).CustomerUpdateAsync(organization.GatewayCustomerId,
await stripeAdapter.Received(1).UpdateCustomerAsync(organization.GatewayCustomerId,
Arg.Is<CustomerUpdateOptions>(options => options.Email == "a@example.com"));
await stripeAdapter.Received(1).CustomerDeleteDiscountAsync(organization.GatewayCustomerId);
await stripeAdapter.Received(1).DeleteCustomerDiscountAsync(organization.GatewayCustomerId);
await stripeAdapter.Received(1).SubscriptionUpdateAsync(organization.GatewaySubscriptionId,
await stripeAdapter.Received(1).DeleteCustomerDiscountAsync(organization.GatewayCustomerId);
await stripeAdapter.Received(1).UpdateSubscriptionAsync(organization.GatewaySubscriptionId,
Arg.Is<SubscriptionUpdateOptions>(options =>
options.CollectionMethod == StripeConstants.CollectionMethod.SendInvoice &&
options.DaysUntilDue == 30));
@@ -226,7 +228,7 @@ public class RemoveOrganizationFromProviderCommandTests
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
stripeAdapter.UpdateCustomerAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
options.Description == string.Empty &&
options.Email == organization.BillingEmail &&
options.Expand[0] == "tax" &&
@@ -239,14 +241,14 @@ public class RemoveOrganizationFromProviderCommandTests
}
});
stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(new Subscription
stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(new Subscription
{
Id = "subscription_id"
});
await sutProvider.Sut.RemoveOrganizationFromProvider(provider, providerOrganization, organization);
await stripeAdapter.Received(1).SubscriptionCreateAsync(Arg.Is<SubscriptionCreateOptions>(options =>
await stripeAdapter.Received(1).CreateSubscriptionAsync(Arg.Is<SubscriptionCreateOptions>(options =>
options.Customer == organization.GatewayCustomerId &&
options.CollectionMethod == StripeConstants.CollectionMethod.SendInvoice &&
options.DaysUntilDue == 30 &&
@@ -315,7 +317,7 @@ public class RemoveOrganizationFromProviderCommandTests
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
stripeAdapter.UpdateCustomerAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
options.Description == string.Empty &&
options.Email == organization.BillingEmail &&
options.Expand[0] == "tax" &&
@@ -328,14 +330,14 @@ public class RemoveOrganizationFromProviderCommandTests
}
});
stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(new Subscription
stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(new Subscription
{
Id = "subscription_id"
});
await sutProvider.Sut.RemoveOrganizationFromProvider(provider, providerOrganization, organization);
await stripeAdapter.Received(1).SubscriptionCreateAsync(Arg.Is<SubscriptionCreateOptions>(options =>
await stripeAdapter.Received(1).CreateSubscriptionAsync(Arg.Is<SubscriptionCreateOptions>(options =>
options.Customer == organization.GatewayCustomerId &&
options.CollectionMethod == StripeConstants.CollectionMethod.SendInvoice &&
options.DaysUntilDue == 30 &&
@@ -434,7 +436,7 @@ public class RemoveOrganizationFromProviderCommandTests
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId, Arg.Any<CustomerUpdateOptions>())
stripeAdapter.UpdateCustomerAsync(organization.GatewayCustomerId, Arg.Any<CustomerUpdateOptions>())
.Returns(new Customer
{
Id = "customer_id",
@@ -444,7 +446,7 @@ public class RemoveOrganizationFromProviderCommandTests
}
});
stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(new Subscription
stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(new Subscription
{
Id = "new_subscription_id"
});

View File

@@ -12,6 +12,7 @@ using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Payment.Models;
using Bit.Core.Billing.Pricing;
using Bit.Core.Billing.Providers.Services;
using Bit.Core.Billing.Services;
using Bit.Core.Context;
using Bit.Core.Entities;
using Bit.Core.Enums;
@@ -757,7 +758,7 @@ public class ProviderServiceTests
await organizationRepository.Received(1)
.ReplaceAsync(Arg.Is<Organization>(org => org.BillingEmail == provider.BillingEmail));
await sutProvider.GetDependency<IStripeAdapter>().Received(1).CustomerUpdateAsync(
await sutProvider.GetDependency<IStripeAdapter>().Received(1).UpdateCustomerAsync(
organization.GatewayCustomerId,
Arg.Is<CustomerUpdateOptions>(options => options.Email == provider.BillingEmail));
@@ -828,9 +829,9 @@ public class ProviderServiceTests
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organization.Id).Returns(organization);
var subscriptionItem = GetSubscription(organization.GatewaySubscriptionId);
sutProvider.GetDependency<IStripeAdapter>().SubscriptionGetAsync(organization.GatewaySubscriptionId)
sutProvider.GetDependency<IStripeAdapter>().GetSubscriptionAsync(organization.GatewaySubscriptionId)
.Returns(GetSubscription(organization.GatewaySubscriptionId));
await sutProvider.GetDependency<IStripeAdapter>().SubscriptionUpdateAsync(
await sutProvider.GetDependency<IStripeAdapter>().UpdateSubscriptionAsync(
organization.GatewaySubscriptionId, SubscriptionUpdateRequest(expectedPlanId, subscriptionItem));
await sutProvider.Sut.AddOrganization(provider.Id, organization.Id, key);

View File

@@ -3,7 +3,6 @@ using Bit.Core.AdminConsole.Entities.Provider;
using Bit.Core.Billing.Constants;
using Bit.Core.Billing.Services;
using Bit.Core.Context;
using Bit.Core.Services;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
using NSubstitute;
@@ -63,7 +62,7 @@ public class GetProviderWarningsQueryTests
});
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(provider.Id).Returns(true);
sutProvider.GetDependency<IStripeAdapter>().TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
sutProvider.GetDependency<IStripeAdapter>().ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
.Returns(new StripeList<Registration> { Data = [] });
var response = await sutProvider.Sut.Run(provider);
@@ -95,7 +94,7 @@ public class GetProviderWarningsQueryTests
});
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(provider.Id).Returns(true);
sutProvider.GetDependency<IStripeAdapter>().TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
sutProvider.GetDependency<IStripeAdapter>().ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
.Returns(new StripeList<Registration> { Data = [] });
var response = await sutProvider.Sut.Run(provider);
@@ -129,7 +128,7 @@ public class GetProviderWarningsQueryTests
});
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(provider.Id).Returns(false);
sutProvider.GetDependency<IStripeAdapter>().TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
sutProvider.GetDependency<IStripeAdapter>().ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
.Returns(new StripeList<Registration> { Data = [] });
var response = await sutProvider.Sut.Run(provider);
@@ -163,7 +162,7 @@ public class GetProviderWarningsQueryTests
});
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(provider.Id).Returns(true);
sutProvider.GetDependency<IStripeAdapter>().TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
sutProvider.GetDependency<IStripeAdapter>().ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
.Returns(new StripeList<Registration> { Data = [] });
var response = await sutProvider.Sut.Run(provider);
@@ -224,7 +223,7 @@ public class GetProviderWarningsQueryTests
});
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(provider.Id).Returns(true);
sutProvider.GetDependency<IStripeAdapter>().TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
sutProvider.GetDependency<IStripeAdapter>().ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
.Returns(new StripeList<Registration>
{
Data = [new Registration { Country = "GB" }]
@@ -257,7 +256,7 @@ public class GetProviderWarningsQueryTests
});
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(provider.Id).Returns(true);
sutProvider.GetDependency<IStripeAdapter>().TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
sutProvider.GetDependency<IStripeAdapter>().ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
.Returns(new StripeList<Registration>
{
Data = [new Registration { Country = "CA" }]
@@ -296,7 +295,7 @@ public class GetProviderWarningsQueryTests
});
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(provider.Id).Returns(true);
sutProvider.GetDependency<IStripeAdapter>().TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
sutProvider.GetDependency<IStripeAdapter>().ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
.Returns(new StripeList<Registration>
{
Data = [new Registration { Country = "CA" }]
@@ -338,7 +337,7 @@ public class GetProviderWarningsQueryTests
});
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(provider.Id).Returns(true);
sutProvider.GetDependency<IStripeAdapter>().TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
sutProvider.GetDependency<IStripeAdapter>().ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
.Returns(new StripeList<Registration>
{
Data = [new Registration { Country = "CA" }]
@@ -383,7 +382,7 @@ public class GetProviderWarningsQueryTests
});
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(provider.Id).Returns(true);
sutProvider.GetDependency<IStripeAdapter>().TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
sutProvider.GetDependency<IStripeAdapter>().ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
.Returns(new StripeList<Registration>
{
Data = [new Registration { Country = "CA" }]
@@ -428,7 +427,7 @@ public class GetProviderWarningsQueryTests
});
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(provider.Id).Returns(true);
sutProvider.GetDependency<IStripeAdapter>().TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
sutProvider.GetDependency<IStripeAdapter>().ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
.Returns(new StripeList<Registration>
{
Data = [new Registration { Country = "CA" }]
@@ -461,7 +460,7 @@ public class GetProviderWarningsQueryTests
});
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(provider.Id).Returns(true);
sutProvider.GetDependency<IStripeAdapter>().TaxRegistrationsListAsync(Arg.Is<RegistrationListOptions>(opt => opt.Status == TaxRegistrationStatus.Active))
sutProvider.GetDependency<IStripeAdapter>().ListTaxRegistrationsAsync(Arg.Is<RegistrationListOptions>(opt => opt.Status == TaxRegistrationStatus.Active))
.Returns(new StripeList<Registration>
{
Data = [
@@ -470,7 +469,7 @@ public class GetProviderWarningsQueryTests
new Registration { Country = "FR" }
]
});
sutProvider.GetDependency<IStripeAdapter>().TaxRegistrationsListAsync(Arg.Is<RegistrationListOptions>(opt => opt.Status == TaxRegistrationStatus.Scheduled))
sutProvider.GetDependency<IStripeAdapter>().ListTaxRegistrationsAsync(Arg.Is<RegistrationListOptions>(opt => opt.Status == TaxRegistrationStatus.Scheduled))
.Returns(new StripeList<Registration> { Data = [] });
var response = await sutProvider.Sut.Run(provider);
@@ -505,7 +504,7 @@ public class GetProviderWarningsQueryTests
});
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(provider.Id).Returns(true);
sutProvider.GetDependency<IStripeAdapter>().TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
sutProvider.GetDependency<IStripeAdapter>().ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
.Returns(new StripeList<Registration>
{
Data = [new Registration { Country = "CA" }]
@@ -543,7 +542,7 @@ public class GetProviderWarningsQueryTests
});
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(provider.Id).Returns(true);
sutProvider.GetDependency<IStripeAdapter>().TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
sutProvider.GetDependency<IStripeAdapter>().ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
.Returns(new StripeList<Registration>
{
Data = [new Registration { Country = "US" }]

View File

@@ -144,11 +144,11 @@ public class BusinessUnitConverterTests
await businessUnitConverter.FinalizeConversion(organization, userId, token, providerKey, organizationKey);
await _stripeAdapter.Received(2).CustomerUpdateAsync(subscription.CustomerId, Arg.Any<CustomerUpdateOptions>());
await _stripeAdapter.Received(2).UpdateCustomerAsync(subscription.CustomerId, Arg.Any<CustomerUpdateOptions>());
var updatedPriceId = ProviderPriceAdapter.GetActivePriceId(provider, enterpriseAnnually.Type);
await _stripeAdapter.Received(1).SubscriptionUpdateAsync(subscription.Id, Arg.Is<SubscriptionUpdateOptions>(
await _stripeAdapter.Received(1).UpdateSubscriptionAsync(subscription.Id, Arg.Is<SubscriptionUpdateOptions>(
arguments =>
arguments.Items.Count == 2 &&
arguments.Items[0].Id == "subscription_item_id" &&

View File

@@ -20,7 +20,6 @@ using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Settings;
using Bit.Core.Test.Billing.Mocks;
using Bit.Test.Common.AutoFixture;
@@ -85,7 +84,7 @@ public class ProviderBillingServiceTests
// Assert
await providerPlanRepository.Received(0).ReplaceAsync(Arg.Any<ProviderPlan>());
await stripeAdapter.Received(0).SubscriptionUpdateAsync(Arg.Any<string>(), Arg.Any<SubscriptionUpdateOptions>());
await stripeAdapter.Received(0).UpdateSubscriptionAsync(Arg.Any<string>(), Arg.Any<SubscriptionUpdateOptions>());
}
[Theory, BitAutoData]
@@ -113,7 +112,7 @@ public class ProviderBillingServiceTests
// Assert
await providerPlanRepository.Received(0).ReplaceAsync(Arg.Any<ProviderPlan>());
await stripeAdapter.Received(0).SubscriptionUpdateAsync(Arg.Any<string>(), Arg.Any<SubscriptionUpdateOptions>());
await stripeAdapter.Received(0).UpdateSubscriptionAsync(Arg.Any<string>(), Arg.Any<SubscriptionUpdateOptions>());
}
[Theory, BitAutoData]
@@ -180,14 +179,14 @@ public class ProviderBillingServiceTests
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
await stripeAdapter.Received(1)
.SubscriptionUpdateAsync(
.UpdateSubscriptionAsync(
Arg.Is(provider.GatewaySubscriptionId),
Arg.Is<SubscriptionUpdateOptions>(p =>
p.Items.Count(si => si.Id == "si_ent_annual" && si.Deleted == true) == 1));
var newPlanCfg = MockPlans.Get(command.NewPlan);
await stripeAdapter.Received(1)
.SubscriptionUpdateAsync(
.UpdateSubscriptionAsync(
Arg.Is(provider.GatewaySubscriptionId),
Arg.Is<SubscriptionUpdateOptions>(p =>
p.Items.Count(si =>
@@ -268,7 +267,7 @@ public class ProviderBillingServiceTests
CloudRegion = "US"
});
sutProvider.GetDependency<IStripeAdapter>().CustomerCreateAsync(Arg.Is<CustomerCreateOptions>(
sutProvider.GetDependency<IStripeAdapter>().CreateCustomerAsync(Arg.Is<CustomerCreateOptions>(
options =>
options.Address.Country == providerCustomer.Address.Country &&
options.Address.PostalCode == providerCustomer.Address.PostalCode &&
@@ -288,7 +287,7 @@ public class ProviderBillingServiceTests
await sutProvider.Sut.CreateCustomerForClientOrganization(provider, organization);
await sutProvider.GetDependency<IStripeAdapter>().Received(1).CustomerCreateAsync(Arg.Is<CustomerCreateOptions>(
await sutProvider.GetDependency<IStripeAdapter>().Received(1).CreateCustomerAsync(Arg.Is<CustomerCreateOptions>(
options =>
options.Address.Country == providerCustomer.Address.Country &&
options.Address.PostalCode == providerCustomer.Address.PostalCode &&
@@ -349,7 +348,7 @@ public class ProviderBillingServiceTests
CloudRegion = "US"
});
sutProvider.GetDependency<IStripeAdapter>().CustomerCreateAsync(Arg.Is<CustomerCreateOptions>(
sutProvider.GetDependency<IStripeAdapter>().CreateCustomerAsync(Arg.Is<CustomerCreateOptions>(
options =>
options.Address.Country == providerCustomer.Address.Country &&
options.Address.PostalCode == providerCustomer.Address.PostalCode &&
@@ -370,7 +369,7 @@ public class ProviderBillingServiceTests
await sutProvider.Sut.CreateCustomerForClientOrganization(provider, organization);
await sutProvider.GetDependency<IStripeAdapter>().Received(1).CustomerCreateAsync(Arg.Is<CustomerCreateOptions>(
await sutProvider.GetDependency<IStripeAdapter>().Received(1).CreateCustomerAsync(Arg.Is<CustomerCreateOptions>(
options =>
options.Address.Country == providerCustomer.Address.Country &&
options.Address.PostalCode == providerCustomer.Address.PostalCode &&
@@ -535,7 +534,7 @@ public class ProviderBillingServiceTests
await sutProvider.Sut.ScaleSeats(provider, PlanType.TeamsMonthly, 10);
// 50 assigned seats + 10 seat scale up = 60 seats, well below the 100 minimum
await sutProvider.GetDependency<IStripeAdapter>().DidNotReceiveWithAnyArgs().SubscriptionUpdateAsync(
await sutProvider.GetDependency<IStripeAdapter>().DidNotReceiveWithAnyArgs().UpdateSubscriptionAsync(
Arg.Any<string>(),
Arg.Any<SubscriptionUpdateOptions>());
@@ -619,7 +618,7 @@ public class ProviderBillingServiceTests
await sutProvider.Sut.ScaleSeats(provider, PlanType.TeamsMonthly, 10);
// 95 current + 10 seat scale = 105 seats, 5 above the minimum
await sutProvider.GetDependency<IStripeAdapter>().Received(1).SubscriptionUpdateAsync(
await sutProvider.GetDependency<IStripeAdapter>().Received(1).UpdateSubscriptionAsync(
provider.GatewaySubscriptionId,
Arg.Is<SubscriptionUpdateOptions>(
options =>
@@ -707,7 +706,7 @@ public class ProviderBillingServiceTests
await sutProvider.Sut.ScaleSeats(provider, PlanType.TeamsMonthly, 10);
// 110 current + 10 seat scale up = 120 seats
await sutProvider.GetDependency<IStripeAdapter>().Received(1).SubscriptionUpdateAsync(
await sutProvider.GetDependency<IStripeAdapter>().Received(1).UpdateSubscriptionAsync(
provider.GatewaySubscriptionId,
Arg.Is<SubscriptionUpdateOptions>(
options =>
@@ -795,7 +794,7 @@ public class ProviderBillingServiceTests
await sutProvider.Sut.ScaleSeats(provider, PlanType.TeamsMonthly, -30);
// 110 seats - 30 scale down seats = 80 seats, below the 100 seat minimum.
await sutProvider.GetDependency<IStripeAdapter>().Received(1).SubscriptionUpdateAsync(
await sutProvider.GetDependency<IStripeAdapter>().Received(1).UpdateSubscriptionAsync(
provider.GatewaySubscriptionId,
Arg.Is<SubscriptionUpdateOptions>(
options =>
@@ -914,12 +913,12 @@ public class ProviderBillingServiceTests
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
var tokenizedPaymentMethod = new TokenizedPaymentMethod { Type = TokenizablePaymentMethodType.BankAccount, Token = "token" };
stripeAdapter.SetupIntentList(Arg.Is<SetupIntentListOptions>(options =>
stripeAdapter.ListSetupIntentsAsync(Arg.Is<SetupIntentListOptions>(options =>
options.PaymentMethod == tokenizedPaymentMethod.Token)).Returns([
new SetupIntent { Id = "setup_intent_id" }
]);
stripeAdapter.CustomerCreateAsync(Arg.Is<CustomerCreateOptions>(o =>
stripeAdapter.CreateCustomerAsync(Arg.Is<CustomerCreateOptions>(o =>
o.Address.Country == billingAddress.Country &&
o.Address.PostalCode == billingAddress.PostalCode &&
o.Address.Line1 == billingAddress.Line1 &&
@@ -942,7 +941,7 @@ public class ProviderBillingServiceTests
await sutProvider.GetDependency<ISetupIntentCache>().Received(1).Set(provider.Id, "setup_intent_id");
await stripeAdapter.Received(1).SetupIntentCancel("setup_intent_id", Arg.Is<SetupIntentCancelOptions>(options =>
await stripeAdapter.Received(1).CancelSetupIntentAsync("setup_intent_id", Arg.Is<SetupIntentCancelOptions>(options =>
options.CancellationReason == "abandoned"));
await sutProvider.GetDependency<ISetupIntentCache>().Received(1).RemoveSetupIntentForSubscriber(provider.Id);
@@ -964,7 +963,7 @@ public class ProviderBillingServiceTests
sutProvider.GetDependency<ISubscriberService>().CreateBraintreeCustomer(provider, tokenizedPaymentMethod.Token)
.Returns("braintree_customer_id");
stripeAdapter.CustomerCreateAsync(Arg.Is<CustomerCreateOptions>(o =>
stripeAdapter.CreateCustomerAsync(Arg.Is<CustomerCreateOptions>(o =>
o.Address.Country == billingAddress.Country &&
o.Address.PostalCode == billingAddress.PostalCode &&
o.Address.Line1 == billingAddress.Line1 &&
@@ -1007,12 +1006,12 @@ public class ProviderBillingServiceTests
var tokenizedPaymentMethod = new TokenizedPaymentMethod { Type = TokenizablePaymentMethodType.BankAccount, Token = "token" };
stripeAdapter.SetupIntentList(Arg.Is<SetupIntentListOptions>(options =>
stripeAdapter.ListSetupIntentsAsync(Arg.Is<SetupIntentListOptions>(options =>
options.PaymentMethod == tokenizedPaymentMethod.Token)).Returns([
new SetupIntent { Id = "setup_intent_id" }
]);
stripeAdapter.CustomerCreateAsync(Arg.Is<CustomerCreateOptions>(o =>
stripeAdapter.CreateCustomerAsync(Arg.Is<CustomerCreateOptions>(o =>
o.Address.Country == billingAddress.Country &&
o.Address.PostalCode == billingAddress.PostalCode &&
o.Address.Line1 == billingAddress.Line1 &&
@@ -1058,7 +1057,7 @@ public class ProviderBillingServiceTests
sutProvider.GetDependency<ISubscriberService>().CreateBraintreeCustomer(provider, tokenizedPaymentMethod.Token)
.Returns("braintree_customer_id");
stripeAdapter.CustomerCreateAsync(Arg.Is<CustomerCreateOptions>(o =>
stripeAdapter.CreateCustomerAsync(Arg.Is<CustomerCreateOptions>(o =>
o.Address.Country == billingAddress.Country &&
o.Address.PostalCode == billingAddress.PostalCode &&
o.Address.Line1 == billingAddress.Line1 &&
@@ -1100,7 +1099,7 @@ public class ProviderBillingServiceTests
var tokenizedPaymentMethod = new TokenizedPaymentMethod { Type = TokenizablePaymentMethodType.Card, Token = "token" };
stripeAdapter.CustomerCreateAsync(Arg.Is<CustomerCreateOptions>(o =>
stripeAdapter.CreateCustomerAsync(Arg.Is<CustomerCreateOptions>(o =>
o.Address.Country == billingAddress.Country &&
o.Address.PostalCode == billingAddress.PostalCode &&
o.Address.Line1 == billingAddress.Line1 &&
@@ -1142,7 +1141,7 @@ public class ProviderBillingServiceTests
var tokenizedPaymentMethod = new TokenizedPaymentMethod { Type = TokenizablePaymentMethodType.Card, Token = "token" };
stripeAdapter.CustomerCreateAsync(Arg.Is<CustomerCreateOptions>(o =>
stripeAdapter.CreateCustomerAsync(Arg.Is<CustomerCreateOptions>(o =>
o.Address.Country == billingAddress.Country &&
o.Address.PostalCode == billingAddress.PostalCode &&
o.Address.Line1 == billingAddress.Line1 &&
@@ -1178,7 +1177,7 @@ public class ProviderBillingServiceTests
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
var tokenizedPaymentMethod = new TokenizedPaymentMethod { Type = TokenizablePaymentMethodType.Card, Token = "token" };
stripeAdapter.CustomerCreateAsync(Arg.Any<CustomerCreateOptions>())
stripeAdapter.CreateCustomerAsync(Arg.Any<CustomerCreateOptions>())
.Throws(new StripeException("Invalid tax ID") { StripeError = new StripeError { Code = "tax_id_invalid" } });
var actual = await Assert.ThrowsAsync<BadRequestException>(async () =>
@@ -1216,7 +1215,7 @@ public class ProviderBillingServiceTests
await sutProvider.GetDependency<IStripeAdapter>()
.DidNotReceiveWithAnyArgs()
.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
}
[Theory, BitAutoData]
@@ -1244,7 +1243,7 @@ public class ProviderBillingServiceTests
await sutProvider.GetDependency<IStripeAdapter>()
.DidNotReceiveWithAnyArgs()
.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
}
[Theory, BitAutoData]
@@ -1272,7 +1271,7 @@ public class ProviderBillingServiceTests
await sutProvider.GetDependency<IStripeAdapter>()
.DidNotReceiveWithAnyArgs()
.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
}
[Theory, BitAutoData]
@@ -1323,7 +1322,7 @@ public class ProviderBillingServiceTests
sutProvider.GetDependency<IProviderPlanRepository>().GetByProviderId(provider.Id)
.Returns(providerPlans);
sutProvider.GetDependency<IStripeAdapter>().SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>())
sutProvider.GetDependency<IStripeAdapter>().CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>())
.Returns(
new Subscription { Id = "subscription_id", Status = StripeConstants.SubscriptionStatus.Incomplete });
@@ -1381,7 +1380,7 @@ public class ProviderBillingServiceTests
var expected = new Subscription { Id = "subscription_id", Status = StripeConstants.SubscriptionStatus.Active };
sutProvider.GetDependency<IStripeAdapter>().SubscriptionCreateAsync(Arg.Is<SubscriptionCreateOptions>(
sutProvider.GetDependency<IStripeAdapter>().CreateSubscriptionAsync(Arg.Is<SubscriptionCreateOptions>(
sub =>
sub.AutomaticTax.Enabled == true &&
sub.CollectionMethod == StripeConstants.CollectionMethod.SendInvoice &&
@@ -1458,7 +1457,7 @@ public class ProviderBillingServiceTests
var expected = new Subscription { Id = "subscription_id", Status = StripeConstants.SubscriptionStatus.Active };
sutProvider.GetDependency<IStripeAdapter>().SubscriptionCreateAsync(Arg.Is<SubscriptionCreateOptions>(
sutProvider.GetDependency<IStripeAdapter>().CreateSubscriptionAsync(Arg.Is<SubscriptionCreateOptions>(
sub =>
sub.AutomaticTax.Enabled == true &&
sub.CollectionMethod == StripeConstants.CollectionMethod.ChargeAutomatically &&
@@ -1538,7 +1537,7 @@ public class ProviderBillingServiceTests
sutProvider.GetDependency<ISetupIntentCache>().GetSetupIntentIdForSubscriber(provider.Id).Returns(setupIntentId);
sutProvider.GetDependency<IStripeAdapter>().SetupIntentGet(setupIntentId, Arg.Is<SetupIntentGetOptions>(options =>
sutProvider.GetDependency<IStripeAdapter>().GetSetupIntentAsync(setupIntentId, Arg.Is<SetupIntentGetOptions>(options =>
options.Expand.Contains("payment_method"))).Returns(new SetupIntent
{
Id = setupIntentId,
@@ -1553,7 +1552,7 @@ public class ProviderBillingServiceTests
}
});
sutProvider.GetDependency<IStripeAdapter>().SubscriptionCreateAsync(Arg.Is<SubscriptionCreateOptions>(
sutProvider.GetDependency<IStripeAdapter>().CreateSubscriptionAsync(Arg.Is<SubscriptionCreateOptions>(
sub =>
sub.AutomaticTax.Enabled == true &&
sub.CollectionMethod == StripeConstants.CollectionMethod.ChargeAutomatically &&
@@ -1635,7 +1634,7 @@ public class ProviderBillingServiceTests
var expected = new Subscription { Id = "subscription_id", Status = StripeConstants.SubscriptionStatus.Active };
sutProvider.GetDependency<IStripeAdapter>().SubscriptionCreateAsync(Arg.Is<SubscriptionCreateOptions>(
sutProvider.GetDependency<IStripeAdapter>().CreateSubscriptionAsync(Arg.Is<SubscriptionCreateOptions>(
sub =>
sub.AutomaticTax.Enabled == true &&
sub.CollectionMethod == StripeConstants.CollectionMethod.ChargeAutomatically &&
@@ -1713,7 +1712,7 @@ public class ProviderBillingServiceTests
var expected = new Subscription { Id = "subscription_id", Status = StripeConstants.SubscriptionStatus.Active };
sutProvider.GetDependency<IStripeAdapter>().SubscriptionCreateAsync(Arg.Is<SubscriptionCreateOptions>(
sutProvider.GetDependency<IStripeAdapter>().CreateSubscriptionAsync(Arg.Is<SubscriptionCreateOptions>(
sub =>
sub.AutomaticTax.Enabled == true &&
sub.CollectionMethod == StripeConstants.CollectionMethod.ChargeAutomatically &&
@@ -1828,7 +1827,7 @@ public class ProviderBillingServiceTests
await providerPlanRepository.Received(1).ReplaceAsync(Arg.Is<ProviderPlan>(
providerPlan => providerPlan.PlanType == PlanType.TeamsMonthly && providerPlan.SeatMinimum == 20 && providerPlan.PurchasedSeats == 5));
await stripeAdapter.Received(1).SubscriptionUpdateAsync(provider.GatewaySubscriptionId,
await stripeAdapter.Received(1).UpdateSubscriptionAsync(provider.GatewaySubscriptionId,
Arg.Is<SubscriptionUpdateOptions>(
options =>
options.Items.Count == 2 &&
@@ -1908,7 +1907,7 @@ public class ProviderBillingServiceTests
await providerPlanRepository.Received(1).ReplaceAsync(Arg.Is<ProviderPlan>(
providerPlan => providerPlan.PlanType == PlanType.TeamsMonthly && providerPlan.SeatMinimum == 50));
await stripeAdapter.Received(1).SubscriptionUpdateAsync(provider.GatewaySubscriptionId,
await stripeAdapter.Received(1).UpdateSubscriptionAsync(provider.GatewaySubscriptionId,
Arg.Is<SubscriptionUpdateOptions>(
options =>
options.Items.Count == 2 &&
@@ -1989,7 +1988,7 @@ public class ProviderBillingServiceTests
providerPlan => providerPlan.PlanType == PlanType.TeamsMonthly && providerPlan.SeatMinimum == 60 && providerPlan.PurchasedSeats == 10));
await stripeAdapter.DidNotReceiveWithAnyArgs()
.SubscriptionUpdateAsync(Arg.Any<string>(), Arg.Any<SubscriptionUpdateOptions>());
.UpdateSubscriptionAsync(Arg.Any<string>(), Arg.Any<SubscriptionUpdateOptions>());
}
[Theory, BitAutoData]
@@ -2062,7 +2061,7 @@ public class ProviderBillingServiceTests
await providerPlanRepository.Received(1).ReplaceAsync(Arg.Is<ProviderPlan>(
providerPlan => providerPlan.PlanType == PlanType.TeamsMonthly && providerPlan.SeatMinimum == 80 && providerPlan.PurchasedSeats == 0));
await stripeAdapter.Received(1).SubscriptionUpdateAsync(provider.GatewaySubscriptionId,
await stripeAdapter.Received(1).UpdateSubscriptionAsync(provider.GatewaySubscriptionId,
Arg.Is<SubscriptionUpdateOptions>(
options =>
options.Items.Count == 2 &&
@@ -2142,7 +2141,7 @@ public class ProviderBillingServiceTests
await providerPlanRepository.DidNotReceive().ReplaceAsync(Arg.Is<ProviderPlan>(
providerPlan => providerPlan.PlanType == PlanType.TeamsMonthly));
await stripeAdapter.Received(1).SubscriptionUpdateAsync(provider.GatewaySubscriptionId,
await stripeAdapter.Received(1).UpdateSubscriptionAsync(provider.GatewaySubscriptionId,
Arg.Is<SubscriptionUpdateOptions>(
options =>
options.Items.Count == 1 &&

View File

@@ -1,4 +1,5 @@
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Billing.Services;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.Business;
@@ -36,7 +37,7 @@ public class PostUserCommandTests
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organizationId).Returns(organization);
sutProvider.GetDependency<IPaymentService>().HasSecretsManagerStandalone(organization).Returns(true);
sutProvider.GetDependency<IStripePaymentService>().HasSecretsManagerStandalone(organization).Returns(true);
sutProvider.GetDependency<IOrganizationService>()
.InviteUserAsync(organizationId,

View File

@@ -16,6 +16,7 @@ using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Extensions;
using Bit.Core.Billing.Pricing;
using Bit.Core.Billing.Providers.Services;
using Bit.Core.Billing.Services;
using Bit.Core.Enums;
using Bit.Core.Models.OrganizationConnectionConfigs;
using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.Interfaces;
@@ -41,7 +42,7 @@ public class OrganizationsController : Controller
private readonly ICollectionRepository _collectionRepository;
private readonly IGroupRepository _groupRepository;
private readonly IPolicyRepository _policyRepository;
private readonly IPaymentService _paymentService;
private readonly IStripePaymentService _paymentService;
private readonly IApplicationCacheService _applicationCacheService;
private readonly GlobalSettings _globalSettings;
private readonly IProviderRepository _providerRepository;
@@ -66,7 +67,7 @@ public class OrganizationsController : Controller
ICollectionRepository collectionRepository,
IGroupRepository groupRepository,
IPolicyRepository policyRepository,
IPaymentService paymentService,
IStripePaymentService paymentService,
IApplicationCacheService applicationCacheService,
GlobalSettings globalSettings,
IProviderRepository providerRepository,

View File

@@ -339,11 +339,11 @@ public class ProvidersController : Controller
]);
await _providerBillingService.UpdateSeatMinimums(updateMspSeatMinimumsCommand);
var customer = await _stripeAdapter.CustomerGetAsync(provider.GatewayCustomerId);
var customer = await _stripeAdapter.GetCustomerAsync(provider.GatewayCustomerId);
if (model.PayByInvoice != customer.ApprovedToPayByInvoice())
{
var approvedToPayByInvoice = model.PayByInvoice ? "1" : "0";
await _stripeAdapter.CustomerUpdateAsync(customer.Id, new CustomerUpdateOptions
await _stripeAdapter.UpdateCustomerAsync(customer.Id, new CustomerUpdateOptions
{
Metadata = new Dictionary<string, string>
{

View File

@@ -8,6 +8,7 @@ using Bit.Admin.Utilities;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Billing.Organizations.Queries;
using Bit.Core.Billing.Services;
using Bit.Core.Entities;
using Bit.Core.Platform.Installations;
using Bit.Core.Repositories;

View File

@@ -5,6 +5,7 @@ using Bit.Admin.Models;
using Bit.Admin.Services;
using Bit.Admin.Utilities;
using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
using Bit.Core.Billing.Services;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Settings;
@@ -20,7 +21,7 @@ public class UsersController : Controller
{
private readonly IUserRepository _userRepository;
private readonly ICipherRepository _cipherRepository;
private readonly IPaymentService _paymentService;
private readonly IStripePaymentService _paymentService;
private readonly GlobalSettings _globalSettings;
private readonly IAccessControlService _accessControlService;
private readonly ITwoFactorIsEnabledQuery _twoFactorIsEnabledQuery;
@@ -30,7 +31,7 @@ public class UsersController : Controller
public UsersController(
IUserRepository userRepository,
ICipherRepository cipherRepository,
IPaymentService paymentService,
IStripePaymentService paymentService,
GlobalSettings globalSettings,
IAccessControlService accessControlService,
ITwoFactorIsEnabledQuery twoFactorIsEnabledQuery,

View File

@@ -6,6 +6,7 @@ using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
using Bit.Core.Billing.Services;
using Bit.Core.Context;
using Bit.Core.Repositories;
using Bit.Core.Services;
@@ -24,7 +25,7 @@ public class MembersController : Controller
private readonly ICurrentContext _currentContext;
private readonly IUpdateOrganizationUserCommand _updateOrganizationUserCommand;
private readonly IUpdateOrganizationUserGroupsCommand _updateOrganizationUserGroupsCommand;
private readonly IPaymentService _paymentService;
private readonly IStripePaymentService _paymentService;
private readonly IOrganizationRepository _organizationRepository;
private readonly ITwoFactorIsEnabledQuery _twoFactorIsEnabledQuery;
private readonly IRemoveOrganizationUserCommand _removeOrganizationUserCommand;
@@ -37,7 +38,7 @@ public class MembersController : Controller
ICurrentContext currentContext,
IUpdateOrganizationUserCommand updateOrganizationUserCommand,
IUpdateOrganizationUserGroupsCommand updateOrganizationUserGroupsCommand,
IPaymentService paymentService,
IStripePaymentService paymentService,
IOrganizationRepository organizationRepository,
ITwoFactorIsEnabledQuery twoFactorIsEnabledQuery,
IRemoveOrganizationUserCommand removeOrganizationUserCommand,

View File

@@ -10,7 +10,7 @@ namespace Bit.Api.Billing.Controllers;
[Route("accounts/billing")]
[Authorize("Application")]
public class AccountsBillingController(
IPaymentService paymentService,
IStripePaymentService paymentService,
IUserService userService,
IPaymentHistoryService paymentHistoryService) : Controller
{

View File

@@ -79,7 +79,7 @@ public class AccountsController(
[HttpGet("subscription")]
public async Task<SubscriptionResponseModel> GetSubscriptionAsync(
[FromServices] GlobalSettings globalSettings,
[FromServices] IPaymentService paymentService)
[FromServices] IStripePaymentService paymentService)
{
var user = await userService.GetUserByPrincipalAsync(User);
if (user == null)

View File

@@ -5,7 +5,6 @@ using Bit.Core.Billing.Providers.Services;
using Bit.Core.Billing.Services;
using Bit.Core.Context;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Utilities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
@@ -19,7 +18,7 @@ public class OrganizationBillingController(
ICurrentContext currentContext,
IOrganizationBillingService organizationBillingService,
IOrganizationRepository organizationRepository,
IPaymentService paymentService,
IStripePaymentService paymentService,
IPaymentHistoryService paymentHistoryService) : BaseBillingController
{
// TODO: Remove when pm-25379-use-new-organization-metadata-structure is removed.

View File

@@ -36,7 +36,7 @@ public class OrganizationsController(
IOrganizationUserRepository organizationUserRepository,
IOrganizationService organizationService,
IUserService userService,
IPaymentService paymentService,
IStripePaymentService paymentService,
ICurrentContext currentContext,
IGetCloudOrganizationLicenseQuery getCloudOrganizationLicenseQuery,
GlobalSettings globalSettings,

View File

@@ -43,7 +43,7 @@ public class ProviderBillingController(
return result;
}
var invoices = await stripeAdapter.InvoiceListAsync(new StripeInvoiceListOptions
var invoices = await stripeAdapter.ListInvoicesAsync(new StripeInvoiceListOptions
{
Customer = provider.GatewayCustomerId
});
@@ -87,7 +87,7 @@ public class ProviderBillingController(
return result;
}
var subscription = await stripeAdapter.SubscriptionGetAsync(provider.GatewaySubscriptionId,
var subscription = await stripeAdapter.GetSubscriptionAsync(provider.GatewaySubscriptionId,
new SubscriptionGetOptions { Expand = ["customer.tax_ids", "discounts", "test_clock"] });
var providerPlans = await providerPlanRepository.GetByProviderId(provider.Id);
@@ -96,7 +96,7 @@ public class ProviderBillingController(
{
var plan = await pricingClient.GetPlanOrThrow(providerPlan.PlanType);
var priceId = ProviderPriceAdapter.GetPriceId(provider, subscription, plan.Type);
var price = await stripeAdapter.PriceGetAsync(priceId);
var price = await stripeAdapter.GetPriceAsync(priceId);
var unitAmount = price.UnitAmountDecimal.HasValue
? price.UnitAmountDecimal.Value / 100M

View File

@@ -1,5 +1,5 @@
using Bit.Core.Billing.Tax.Services;
using Bit.Core.Services;
using Bit.Core.Billing.Services;
using Bit.Core.Billing.Tax.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
@@ -28,7 +28,7 @@ public class StripeController(
Usage = "off_session"
};
var setupIntent = await stripeAdapter.SetupIntentCreate(options);
var setupIntent = await stripeAdapter.CreateSetupIntentAsync(options);
return TypedResults.Ok(setupIntent.ClientSecret);
}
@@ -43,7 +43,7 @@ public class StripeController(
Usage = "off_session"
};
var setupIntent = await stripeAdapter.SetupIntentCreate(options);
var setupIntent = await stripeAdapter.CreateSetupIntentAsync(options);
return TypedResults.Ok(setupIntent.ClientSecret);
}

View File

@@ -29,7 +29,7 @@ public class BitPayController(
IUserRepository userRepository,
IProviderRepository providerRepository,
IMailService mailService,
IPaymentService paymentService,
IStripePaymentService paymentService,
ILogger<BitPayController> logger,
IPremiumUserBillingService premiumUserBillingService)
: Controller

View File

@@ -23,7 +23,7 @@ public class PayPalController : Controller
private readonly ILogger<PayPalController> _logger;
private readonly IMailService _mailService;
private readonly IOrganizationRepository _organizationRepository;
private readonly IPaymentService _paymentService;
private readonly IStripePaymentService _paymentService;
private readonly ITransactionRepository _transactionRepository;
private readonly IUserRepository _userRepository;
private readonly IProviderRepository _providerRepository;
@@ -34,7 +34,7 @@ public class PayPalController : Controller
ILogger<PayPalController> logger,
IMailService mailService,
IOrganizationRepository organizationRepository,
IPaymentService paymentService,
IStripePaymentService paymentService,
ITransactionRepository transactionRepository,
IUserRepository userRepository,
IProviderRepository providerRepository,

View File

@@ -2,8 +2,8 @@
using Bit.Core.AdminConsole.Entities.Provider;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Billing.Caches;
using Bit.Core.Billing.Services;
using Bit.Core.Repositories;
using Bit.Core.Services;
using OneOf;
using Stripe;
using Event = Stripe.Event;
@@ -59,10 +59,10 @@ public class SetupIntentSucceededHandler(
return;
}
await stripeAdapter.PaymentMethodAttachAsync(paymentMethod.Id,
await stripeAdapter.AttachPaymentMethodAsync(paymentMethod.Id,
new PaymentMethodAttachOptions { Customer = customerId });
await stripeAdapter.CustomerUpdateAsync(customerId, new CustomerUpdateOptions
await stripeAdapter.UpdateCustomerAsync(customerId, new CustomerUpdateOptions
{
InvoiceSettings = new CustomerInvoiceSettingsOptions
{

View File

@@ -2,6 +2,7 @@
using Bit.Core.AdminConsole.Models.Business;
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Billing.Services;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
@@ -18,7 +19,7 @@ public class ImportOrganizationUsersAndGroupsCommand : IImportOrganizationUsersA
{
private readonly IOrganizationRepository _organizationRepository;
private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly IPaymentService _paymentService;
private readonly IStripePaymentService _paymentService;
private readonly IGroupRepository _groupRepository;
private readonly IEventService _eventService;
private readonly IOrganizationService _organizationService;
@@ -27,7 +28,7 @@ public class ImportOrganizationUsersAndGroupsCommand : IImportOrganizationUsersA
public ImportOrganizationUsersAndGroupsCommand(IOrganizationRepository organizationRepository,
IOrganizationUserRepository organizationUserRepository,
IPaymentService paymentService,
IStripePaymentService paymentService,
IGroupRepository groupRepository,
IEventService eventService,
IOrganizationService organizationService)

View File

@@ -2,10 +2,10 @@
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.PasswordManager;
using Bit.Core.AdminConsole.Utilities.Errors;
using Bit.Core.AdminConsole.Utilities.Validation;
using Bit.Core.Billing.Services;
using Bit.Core.Models.Business;
using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
using Bit.Core.Repositories;
using Bit.Core.Services;
namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation;
@@ -15,7 +15,7 @@ public class InviteOrganizationUsersValidator(
IOrganizationRepository organizationRepository,
IInviteUsersPasswordManagerValidator inviteUsersPasswordManagerValidator,
IUpdateSecretsManagerSubscriptionCommand secretsManagerSubscriptionCommand,
IPaymentService paymentService) : IInviteUsersValidator
IStripePaymentService paymentService) : IInviteUsersValidator
{
public async Task<ValidationResult<InviteOrganizationUsersValidationRequest>> ValidateAsync(
InviteOrganizationUsersValidationRequest request)

View File

@@ -9,8 +9,8 @@ using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.V
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Provider;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.AdminConsole.Utilities.Validation;
using Bit.Core.Billing.Services;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Settings;
namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.PasswordManager;
@@ -22,7 +22,7 @@ public class InviteUsersPasswordManagerValidator(
IInviteUsersEnvironmentValidator inviteUsersEnvironmentValidator,
IInviteUsersOrganizationValidator inviteUsersOrganizationValidator,
IProviderRepository providerRepository,
IPaymentService paymentService,
IStripePaymentService paymentService,
IOrganizationRepository organizationRepository
) : IInviteUsersPasswordManagerValidator
{

View File

@@ -8,6 +8,7 @@ using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Organizations.Models;
using Bit.Core.Billing.Organizations.Services;
using Bit.Core.Billing.Pricing;
using Bit.Core.Billing.Services;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
@@ -33,7 +34,7 @@ public interface ICloudOrganizationSignUpCommand
public class CloudOrganizationSignUpCommand(
IOrganizationUserRepository organizationUserRepository,
IOrganizationBillingService organizationBillingService,
IPaymentService paymentService,
IStripePaymentService paymentService,
IPolicyService policyService,
IOrganizationRepository organizationRepository,
IOrganizationApiKeyRepository organizationApiKeyRepository,

View File

@@ -2,6 +2,7 @@
using Bit.Core.AdminConsole.OrganizationFeatures.Organizations.Interfaces;
using Bit.Core.Auth.Enums;
using Bit.Core.Auth.Repositories;
using Bit.Core.Billing.Services;
using Bit.Core.Exceptions;
using Bit.Core.Repositories;
using Bit.Core.Services;
@@ -12,13 +13,13 @@ public class OrganizationDeleteCommand : IOrganizationDeleteCommand
{
private readonly IApplicationCacheService _applicationCacheService;
private readonly IOrganizationRepository _organizationRepository;
private readonly IPaymentService _paymentService;
private readonly IStripePaymentService _paymentService;
private readonly ISsoConfigRepository _ssoConfigRepository;
public OrganizationDeleteCommand(
IApplicationCacheService applicationCacheService,
IOrganizationRepository organizationRepository,
IPaymentService paymentService,
IStripePaymentService paymentService,
ISsoConfigRepository ssoConfigRepository)
{
_applicationCacheService = applicationCacheService;

View File

@@ -1,6 +1,7 @@
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers;
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models;
using Bit.Core.Billing.Services;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Repositories;
@@ -39,7 +40,7 @@ public class ResellerClientOrganizationSignUpCommand : IResellerClientOrganizati
private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly IEventService _eventService;
private readonly ISendOrganizationInvitesCommand _sendOrganizationInvitesCommand;
private readonly IPaymentService _paymentService;
private readonly IStripePaymentService _paymentService;
public ResellerClientOrganizationSignUpCommand(
IOrganizationRepository organizationRepository,
@@ -48,7 +49,7 @@ public class ResellerClientOrganizationSignUpCommand : IResellerClientOrganizati
IOrganizationUserRepository organizationUserRepository,
IEventService eventService,
ISendOrganizationInvitesCommand sendOrganizationInvitesCommand,
IPaymentService paymentService)
IStripePaymentService paymentService)
{
_organizationRepository = organizationRepository;
_organizationApiKeyRepository = organizationApiKeyRepository;

View File

@@ -30,7 +30,7 @@ public class SelfHostedOrganizationSignUpCommand : ISelfHostedOrganizationSignUp
private readonly ILicensingService _licensingService;
private readonly IPolicyService _policyService;
private readonly IGlobalSettings _globalSettings;
private readonly IPaymentService _paymentService;
private readonly IStripePaymentService _paymentService;
public SelfHostedOrganizationSignUpCommand(
IOrganizationRepository organizationRepository,
@@ -44,7 +44,7 @@ public class SelfHostedOrganizationSignUpCommand : ISelfHostedOrganizationSignUp
ILicensingService licensingService,
IPolicyService policyService,
IGlobalSettings globalSettings,
IPaymentService paymentService)
IStripePaymentService paymentService)
{
_organizationRepository = organizationRepository;
_organizationUserRepository = organizationUserRepository;

View File

@@ -1,12 +1,12 @@
using Bit.Core.AdminConsole.Models.Data.Organizations;
using Bit.Core.AdminConsole.OrganizationFeatures.Organizations.Interfaces;
using Bit.Core.Billing.Services;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Microsoft.Extensions.Logging;
namespace Bit.Core.AdminConsole.OrganizationFeatures.Organizations;
public class UpdateOrganizationSubscriptionCommand(IPaymentService paymentService,
public class UpdateOrganizationSubscriptionCommand(IStripePaymentService paymentService,
IOrganizationRepository repository,
TimeProvider timeProvider,
ILogger<UpdateOrganizationSubscriptionCommand> logger) : IUpdateOrganizationSubscriptionCommand

View File

@@ -21,6 +21,7 @@ using Bit.Core.Billing.Constants;
using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Extensions;
using Bit.Core.Billing.Pricing;
using Bit.Core.Billing.Services;
using Bit.Core.Context;
using Bit.Core.Entities;
using Bit.Core.Enums;
@@ -47,7 +48,7 @@ public class OrganizationService : IOrganizationService
private readonly IPushNotificationService _pushNotificationService;
private readonly IEventService _eventService;
private readonly IApplicationCacheService _applicationCacheService;
private readonly IPaymentService _paymentService;
private readonly IStripePaymentService _paymentService;
private readonly IPolicyRepository _policyRepository;
private readonly IPolicyService _policyService;
private readonly ISsoUserRepository _ssoUserRepository;
@@ -74,7 +75,7 @@ public class OrganizationService : IOrganizationService
IPushNotificationService pushNotificationService,
IEventService eventService,
IApplicationCacheService applicationCacheService,
IPaymentService paymentService,
IStripePaymentService paymentService,
IPolicyRepository policyRepository,
IPolicyService policyService,
ISsoUserRepository ssoUserRepository,
@@ -358,7 +359,7 @@ public class OrganizationService : IOrganizationService
{
var newDisplayName = organization.DisplayName();
await _stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId,
await _stripeAdapter.UpdateCustomerAsync(organization.GatewayCustomerId,
new CustomerUpdateOptions
{
Email = organization.BillingEmail,

View File

@@ -7,8 +7,8 @@ using Bit.Core.Billing.Models;
using Bit.Core.Billing.Organizations.Models;
using Bit.Core.Billing.Payment.Models;
using Bit.Core.Billing.Pricing;
using Bit.Core.Billing.Services;
using Bit.Core.Enums;
using Bit.Core.Services;
using Microsoft.Extensions.Logging;
using OneOf;
using Stripe;
@@ -125,7 +125,7 @@ public class PreviewOrganizationTaxCommand(
options.SubscriptionDetails = new InvoiceSubscriptionDetailsOptions { Items = items };
var invoice = await stripeAdapter.InvoiceCreatePreviewAsync(options);
var invoice = await stripeAdapter.CreateInvoicePreviewAsync(options);
return GetAmounts(invoice);
});
@@ -165,7 +165,7 @@ public class PreviewOrganizationTaxCommand(
options.SubscriptionDetails = new InvoiceSubscriptionDetailsOptions { Items = items };
var invoice = await stripeAdapter.InvoiceCreatePreviewAsync(options);
var invoice = await stripeAdapter.CreateInvoicePreviewAsync(options);
return GetAmounts(invoice);
}
else
@@ -181,7 +181,7 @@ public class PreviewOrganizationTaxCommand(
var options = GetBaseOptions(billingAddress, planChange.Tier != ProductTierType.Families);
var subscription = await stripeAdapter.SubscriptionGetAsync(organization.GatewaySubscriptionId,
var subscription = await stripeAdapter.GetSubscriptionAsync(organization.GatewaySubscriptionId,
new SubscriptionGetOptions { Expand = ["customer"] });
if (subscription.Customer.Discount != null)
@@ -259,7 +259,7 @@ public class PreviewOrganizationTaxCommand(
options.SubscriptionDetails = new InvoiceSubscriptionDetailsOptions { Items = items };
var invoice = await stripeAdapter.InvoiceCreatePreviewAsync(options);
var invoice = await stripeAdapter.CreateInvoicePreviewAsync(options);
return GetAmounts(invoice);
}
});
@@ -278,7 +278,7 @@ public class PreviewOrganizationTaxCommand(
return new BadRequest("Organization does not have a subscription.");
}
var subscription = await stripeAdapter.SubscriptionGetAsync(organization.GatewaySubscriptionId,
var subscription = await stripeAdapter.GetSubscriptionAsync(organization.GatewaySubscriptionId,
new SubscriptionGetOptions { Expand = ["customer.tax_ids"] });
var options = GetBaseOptions(subscription.Customer,
@@ -336,7 +336,7 @@ public class PreviewOrganizationTaxCommand(
options.SubscriptionDetails = new InvoiceSubscriptionDetailsOptions { Items = items };
var invoice = await stripeAdapter.InvoiceCreatePreviewAsync(options);
var invoice = await stripeAdapter.CreateInvoicePreviewAsync(options);
return GetAmounts(invoice);
});

View File

@@ -22,14 +22,14 @@ public interface IGetCloudOrganizationLicenseQuery
public class GetCloudOrganizationLicenseQuery : IGetCloudOrganizationLicenseQuery
{
private readonly IInstallationRepository _installationRepository;
private readonly IPaymentService _paymentService;
private readonly IStripePaymentService _paymentService;
private readonly ILicensingService _licensingService;
private readonly IProviderRepository _providerRepository;
private readonly IFeatureService _featureService;
public GetCloudOrganizationLicenseQuery(
IInstallationRepository installationRepository,
IPaymentService paymentService,
IStripePaymentService paymentService,
ILicensingService licensingService,
IProviderRepository providerRepository,
IFeatureService featureService)

View File

@@ -9,7 +9,6 @@ using Bit.Core.Billing.Organizations.Models;
using Bit.Core.Billing.Payment.Queries;
using Bit.Core.Billing.Services;
using Bit.Core.Context;
using Bit.Core.Services;
using Stripe;
using Stripe.Tax;
@@ -201,7 +200,7 @@ public class GetOrganizationWarningsQuery(
// ReSharper disable once InvertIf
if (subscription.Status == SubscriptionStatus.PastDue)
{
var openInvoices = await stripeAdapter.InvoiceSearchAsync(new InvoiceSearchOptions
var openInvoices = await stripeAdapter.SearchInvoiceAsync(new InvoiceSearchOptions
{
Query = $"subscription:'{subscription.Id}' status:'open'"
});
@@ -257,8 +256,8 @@ public class GetOrganizationWarningsQuery(
// Get active and scheduled registrations
var registrations = (await Task.WhenAll(
stripeAdapter.TaxRegistrationsListAsync(new RegistrationListOptions { Status = TaxRegistrationStatus.Active }),
stripeAdapter.TaxRegistrationsListAsync(new RegistrationListOptions { Status = TaxRegistrationStatus.Scheduled })))
stripeAdapter.ListTaxRegistrationsAsync(new RegistrationListOptions { Status = TaxRegistrationStatus.Active }),
stripeAdapter.ListTaxRegistrationsAsync(new RegistrationListOptions { Status = TaxRegistrationStatus.Scheduled })))
.SelectMany(registrations => registrations.Data);
// Find the matching registration for the customer

View File

@@ -14,7 +14,6 @@ using Bit.Core.Billing.Tax.Services;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Settings;
using Braintree;
using Microsoft.Extensions.Logging;
@@ -161,7 +160,7 @@ public class OrganizationBillingService(
try
{
// Update the subscription in Stripe
await stripeAdapter.SubscriptionUpdateAsync(subscription.Id, updateOptions);
await stripeAdapter.UpdateSubscriptionAsync(subscription.Id, updateOptions);
organization.PlanType = newPlan.Type;
await organizationRepository.ReplaceAsync(organization);
}
@@ -185,7 +184,7 @@ public class OrganizationBillingService(
var newDisplayName = organization.DisplayName();
await stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId,
await stripeAdapter.UpdateCustomerAsync(organization.GatewayCustomerId,
new CustomerUpdateOptions
{
Email = organization.BillingEmail,
@@ -324,7 +323,7 @@ public class OrganizationBillingService(
case PaymentMethodType.BankAccount:
{
var setupIntent =
(await stripeAdapter.SetupIntentList(new SetupIntentListOptions { PaymentMethod = paymentMethodToken }))
(await stripeAdapter.ListSetupIntentsAsync(new SetupIntentListOptions { PaymentMethod = paymentMethodToken }))
.FirstOrDefault();
if (setupIntent == null)
@@ -358,7 +357,7 @@ public class OrganizationBillingService(
try
{
var customer = await stripeAdapter.CustomerCreateAsync(customerCreateOptions);
var customer = await stripeAdapter.CreateCustomerAsync(customerCreateOptions);
organization.Gateway = GatewayType.Stripe;
organization.GatewayCustomerId = customer.Id;
@@ -509,7 +508,7 @@ public class OrganizationBillingService(
subscriptionCreateOptions.AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true };
}
var subscription = await stripeAdapter.SubscriptionCreateAsync(subscriptionCreateOptions);
var subscription = await stripeAdapter.CreateSubscriptionAsync(subscriptionCreateOptions);
organization.GatewaySubscriptionId = subscription.Id;
await organizationRepository.ReplaceAsync(organization);
@@ -537,14 +536,14 @@ public class OrganizationBillingService(
customer = customer switch
{
{ Address.Country: not Core.Constants.CountryAbbreviations.UnitedStates, TaxExempt: not StripeConstants.TaxExempt.Reverse } => await
stripeAdapter.CustomerUpdateAsync(customer.Id,
stripeAdapter.UpdateCustomerAsync(customer.Id,
new CustomerUpdateOptions
{
Expand = expansions,
TaxExempt = StripeConstants.TaxExempt.Reverse
}),
{ Address.Country: Core.Constants.CountryAbbreviations.UnitedStates, TaxExempt: StripeConstants.TaxExempt.Reverse } => await
stripeAdapter.CustomerUpdateAsync(customer.Id,
stripeAdapter.UpdateCustomerAsync(customer.Id,
new CustomerUpdateOptions
{
Expand = expansions,
@@ -603,7 +602,7 @@ public class OrganizationBillingService(
}
}
};
await stripeAdapter.SubscriptionUpdateAsync(organization.GatewaySubscriptionId, options);
await stripeAdapter.UpdateSubscriptionAsync(organization.GatewaySubscriptionId, options);
}
}

View File

@@ -4,7 +4,6 @@ using Bit.Core.Billing.Extensions;
using Bit.Core.Billing.Payment.Models;
using Bit.Core.Billing.Services;
using Bit.Core.Entities;
using Bit.Core.Services;
using Microsoft.Extensions.Logging;
using Stripe;
@@ -46,7 +45,7 @@ public class UpdateBillingAddressCommand(
BillingAddress billingAddress)
{
var customer =
await stripeAdapter.CustomerUpdateAsync(subscriber.GatewayCustomerId,
await stripeAdapter.UpdateCustomerAsync(subscriber.GatewayCustomerId,
new CustomerUpdateOptions
{
Address = new AddressOptions
@@ -71,7 +70,7 @@ public class UpdateBillingAddressCommand(
BillingAddress billingAddress)
{
var customer =
await stripeAdapter.CustomerUpdateAsync(subscriber.GatewayCustomerId,
await stripeAdapter.UpdateCustomerAsync(subscriber.GatewayCustomerId,
new CustomerUpdateOptions
{
Address = new AddressOptions
@@ -92,7 +91,7 @@ public class UpdateBillingAddressCommand(
await EnableAutomaticTaxAsync(subscriber, customer);
var deleteExistingTaxIds = customer.TaxIds?.Any() ?? false
? customer.TaxIds.Select(taxId => stripeAdapter.TaxIdDeleteAsync(customer.Id, taxId.Id)).ToList()
? customer.TaxIds.Select(taxId => stripeAdapter.DeleteTaxIdAsync(customer.Id, taxId.Id)).ToList()
: [];
if (billingAddress.TaxId == null)
@@ -101,12 +100,12 @@ public class UpdateBillingAddressCommand(
return BillingAddress.From(customer.Address);
}
var updatedTaxId = await stripeAdapter.TaxIdCreateAsync(customer.Id,
var updatedTaxId = await stripeAdapter.CreateTaxIdAsync(customer.Id,
new TaxIdCreateOptions { Type = billingAddress.TaxId.Code, Value = billingAddress.TaxId.Value });
if (billingAddress.TaxId.Code == StripeConstants.TaxIdType.SpanishNIF)
{
updatedTaxId = await stripeAdapter.TaxIdCreateAsync(customer.Id,
updatedTaxId = await stripeAdapter.CreateTaxIdAsync(customer.Id,
new TaxIdCreateOptions
{
Type = StripeConstants.TaxIdType.EUVAT,
@@ -130,7 +129,7 @@ public class UpdateBillingAddressCommand(
if (subscription is { AutomaticTax.Enabled: false })
{
await stripeAdapter.SubscriptionUpdateAsync(subscriber.GatewaySubscriptionId,
await stripeAdapter.UpdateSubscriptionAsync(subscriber.GatewaySubscriptionId,
new SubscriptionUpdateOptions
{
AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true }

View File

@@ -4,7 +4,6 @@ using Bit.Core.Billing.Constants;
using Bit.Core.Billing.Payment.Models;
using Bit.Core.Billing.Services;
using Bit.Core.Entities;
using Bit.Core.Services;
using Bit.Core.Settings;
using Bit.Core.Utilities;
using Braintree;
@@ -56,7 +55,7 @@ public class UpdatePaymentMethodCommand(
if (billingAddress != null && customer.Address is not { Country: not null, PostalCode: not null })
{
await stripeAdapter.CustomerUpdateAsync(customer.Id,
await stripeAdapter.UpdateCustomerAsync(customer.Id,
new CustomerUpdateOptions
{
Address = new AddressOptions
@@ -75,7 +74,7 @@ public class UpdatePaymentMethodCommand(
Customer customer,
string token)
{
var setupIntents = await stripeAdapter.SetupIntentList(new SetupIntentListOptions
var setupIntents = await stripeAdapter.ListSetupIntentsAsync(new SetupIntentListOptions
{
Expand = ["data.payment_method"],
PaymentMethod = token
@@ -104,9 +103,9 @@ public class UpdatePaymentMethodCommand(
Customer customer,
string token)
{
var paymentMethod = await stripeAdapter.PaymentMethodAttachAsync(token, new PaymentMethodAttachOptions { Customer = customer.Id });
var paymentMethod = await stripeAdapter.AttachPaymentMethodAsync(token, new PaymentMethodAttachOptions { Customer = customer.Id });
await stripeAdapter.CustomerUpdateAsync(customer.Id,
await stripeAdapter.UpdateCustomerAsync(customer.Id,
new CustomerUpdateOptions
{
InvoiceSettings = new CustomerInvoiceSettingsOptions { DefaultPaymentMethod = token }
@@ -139,7 +138,7 @@ public class UpdatePaymentMethodCommand(
[StripeConstants.MetadataKeys.BraintreeCustomerId] = braintreeCustomer.Id
};
await stripeAdapter.CustomerUpdateAsync(customer.Id, new CustomerUpdateOptions { Metadata = metadata });
await stripeAdapter.UpdateCustomerAsync(customer.Id, new CustomerUpdateOptions { Metadata = metadata });
}
var payPalAccount = braintreeCustomer.DefaultPaymentMethod as PayPalAccount;
@@ -204,7 +203,7 @@ public class UpdatePaymentMethodCommand(
[StripeConstants.MetadataKeys.BraintreeCustomerId] = string.Empty
};
await stripeAdapter.CustomerUpdateAsync(customer.Id, new CustomerUpdateOptions { Metadata = metadata });
await stripeAdapter.UpdateCustomerAsync(customer.Id, new CustomerUpdateOptions { Metadata = metadata });
}
}
}

View File

@@ -4,7 +4,6 @@ using Bit.Core.Billing.Extensions;
using Bit.Core.Billing.Payment.Models;
using Bit.Core.Billing.Services;
using Bit.Core.Entities;
using Bit.Core.Services;
using Braintree;
using Microsoft.Extensions.Logging;
using Stripe;
@@ -53,7 +52,7 @@ public class GetPaymentMethodQuery(
if (!string.IsNullOrEmpty(setupIntentId))
{
var setupIntent = await stripeAdapter.SetupIntentGet(setupIntentId, new SetupIntentGetOptions
var setupIntent = await stripeAdapter.GetSetupIntentAsync(setupIntentId, new SetupIntentGetOptions
{
Expand = ["payment_method"]
});

View File

@@ -3,7 +3,6 @@ using Bit.Core.Billing.Constants;
using Bit.Core.Billing.Extensions;
using Bit.Core.Billing.Services;
using Bit.Core.Entities;
using Bit.Core.Services;
using Stripe;
namespace Bit.Core.Billing.Payment.Queries;
@@ -48,7 +47,7 @@ public class HasPaymentMethodQuery(
return false;
}
var setupIntent = await stripeAdapter.SetupIntentGet(setupIntentId, new SetupIntentGetOptions
var setupIntent = await stripeAdapter.GetSetupIntentAsync(setupIntentId, new SetupIntentGetOptions
{
Expand = ["payment_method"]
});

View File

@@ -210,7 +210,7 @@ public class CreatePremiumCloudHostedSubscriptionCommand(
case TokenizablePaymentMethodType.BankAccount:
{
var setupIntent =
(await stripeAdapter.SetupIntentList(new SetupIntentListOptions { PaymentMethod = tokenizedPaymentMethod.Token }))
(await stripeAdapter.ListSetupIntentsAsync(new SetupIntentListOptions { PaymentMethod = tokenizedPaymentMethod.Token }))
.FirstOrDefault();
if (setupIntent == null)
@@ -243,7 +243,7 @@ public class CreatePremiumCloudHostedSubscriptionCommand(
try
{
return await stripeAdapter.CustomerCreateAsync(customerCreateOptions);
return await stripeAdapter.CreateCustomerAsync(customerCreateOptions);
}
catch
{
@@ -300,7 +300,7 @@ public class CreatePremiumCloudHostedSubscriptionCommand(
ValidateLocation = ValidateTaxLocationTiming.Immediately
}
};
return await stripeAdapter.CustomerUpdateAsync(customer.Id, options);
return await stripeAdapter.UpdateCustomerAsync(customer.Id, options);
}
private async Task<Subscription> CreateSubscriptionAsync(
@@ -349,11 +349,11 @@ public class CreatePremiumCloudHostedSubscriptionCommand(
OffSession = true
};
var subscription = await stripeAdapter.SubscriptionCreateAsync(subscriptionCreateOptions);
var subscription = await stripeAdapter.CreateSubscriptionAsync(subscriptionCreateOptions);
if (usingPayPal)
{
await stripeAdapter.InvoiceUpdateAsync(subscription.LatestInvoiceId, new InvoiceUpdateOptions
await stripeAdapter.UpdateInvoiceAsync(subscription.LatestInvoiceId, new InvoiceUpdateOptions
{
AutoAdvance = false
});

View File

@@ -1,7 +1,7 @@
using Bit.Core.Billing.Commands;
using Bit.Core.Billing.Payment.Models;
using Bit.Core.Billing.Pricing;
using Bit.Core.Services;
using Bit.Core.Billing.Services;
using Microsoft.Extensions.Logging;
using Stripe;
@@ -56,7 +56,7 @@ public class PreviewPremiumTaxCommand(
});
}
var invoice = await stripeAdapter.InvoiceCreatePreviewAsync(options);
var invoice = await stripeAdapter.CreateInvoicePreviewAsync(options);
return GetAmounts(invoice);
});

View File

@@ -0,0 +1,50 @@
// FIXME: Update this file to be null safe and then delete the line below
#nullable disable
using Bit.Core.Models.BitStripe;
using Stripe;
using Stripe.Tax;
namespace Bit.Core.Billing.Services;
public interface IStripeAdapter
{
Task<Customer> CreateCustomerAsync(CustomerCreateOptions customerCreateOptions);
Task<Customer> GetCustomerAsync(string id, CustomerGetOptions options = null);
Task<Customer> UpdateCustomerAsync(string id, CustomerUpdateOptions options = null);
Task<Customer> DeleteCustomerAsync(string id);
Task<List<PaymentMethod>> ListCustomerPaymentMethodsAsync(string id, CustomerPaymentMethodListOptions options = null);
Task<CustomerBalanceTransaction> CreateCustomerBalanceTransactionAsync(string customerId,
CustomerBalanceTransactionCreateOptions options);
Task<Subscription> CreateSubscriptionAsync(SubscriptionCreateOptions subscriptionCreateOptions);
Task<Subscription> GetSubscriptionAsync(string id, SubscriptionGetOptions options = null);
Task<StripeList<Registration>> ListTaxRegistrationsAsync(RegistrationListOptions options = null);
Task DeleteCustomerDiscountAsync(string customerId, CustomerDeleteDiscountOptions options = null);
Task<Subscription> UpdateSubscriptionAsync(string id, SubscriptionUpdateOptions options = null);
Task<Subscription> CancelSubscriptionAsync(string id, SubscriptionCancelOptions options = null);
Task<Invoice> GetInvoiceAsync(string id, InvoiceGetOptions options);
Task<List<Invoice>> ListInvoicesAsync(StripeInvoiceListOptions options);
Task<Invoice> CreateInvoicePreviewAsync(InvoiceCreatePreviewOptions options);
Task<List<Invoice>> SearchInvoiceAsync(InvoiceSearchOptions options);
Task<Invoice> UpdateInvoiceAsync(string id, InvoiceUpdateOptions options);
Task<Invoice> FinalizeInvoiceAsync(string id, InvoiceFinalizeOptions options);
Task<Invoice> SendInvoiceAsync(string id, InvoiceSendOptions options);
Task<Invoice> PayInvoiceAsync(string id, InvoicePayOptions options = null);
Task<Invoice> DeleteInvoiceAsync(string id, InvoiceDeleteOptions options = null);
Task<Invoice> VoidInvoiceAsync(string id, InvoiceVoidOptions options = null);
IEnumerable<PaymentMethod> ListPaymentMethodsAutoPaging(PaymentMethodListOptions options);
IAsyncEnumerable<PaymentMethod> ListPaymentMethodsAutoPagingAsync(PaymentMethodListOptions options);
Task<PaymentMethod> AttachPaymentMethodAsync(string id, PaymentMethodAttachOptions options = null);
Task<PaymentMethod> DetachPaymentMethodAsync(string id, PaymentMethodDetachOptions options = null);
Task<TaxId> CreateTaxIdAsync(string id, TaxIdCreateOptions options);
Task<TaxId> DeleteTaxIdAsync(string customerId, string taxIdId, TaxIdDeleteOptions options = null);
Task<StripeList<Charge>> ListChargesAsync(ChargeListOptions options);
Task<Refund> CreateRefundAsync(RefundCreateOptions options);
Task<Card> DeleteCardAsync(string customerId, string cardId, CardDeleteOptions options = null);
Task<BankAccount> DeleteBankAccountAsync(string customerId, string bankAccount, BankAccountDeleteOptions options = null);
Task<SetupIntent> CreateSetupIntentAsync(SetupIntentCreateOptions options);
Task<List<SetupIntent>> ListSetupIntentsAsync(SetupIntentListOptions options);
Task CancelSetupIntentAsync(string id, SetupIntentCancelOptions options = null);
Task<SetupIntent> GetSetupIntentAsync(string id, SetupIntentGetOptions options = null);
Task<Price> GetPriceAsync(string id, PriceGetOptions options = null);
}

View File

@@ -8,9 +8,9 @@ using Bit.Core.Entities;
using Bit.Core.Models.Business;
using Bit.Core.Models.StaticStore;
namespace Bit.Core.Services;
namespace Bit.Core.Billing.Services;
public interface IPaymentService
public interface IStripePaymentService
{
Task CancelAndRecoverChargesAsync(ISubscriber subscriber);
Task SponsorOrganizationAsync(Organization org, OrganizationSponsorship sponsorship);

View File

@@ -0,0 +1,6 @@
namespace Bit.Core.Billing.Services;
public interface IStripeSyncService
{
Task UpdateCustomerEmailAddressAsync(string gatewayCustomerId, string emailAddress);
}

View File

@@ -4,7 +4,6 @@ using Bit.Core.Billing.Models;
using Bit.Core.Entities;
using Bit.Core.Models.BitStripe;
using Bit.Core.Repositories;
using Bit.Core.Services;
namespace Bit.Core.Billing.Services.Implementations;
@@ -23,7 +22,7 @@ public class PaymentHistoryService(
return Array.Empty<BillingHistoryInfo.BillingInvoice>();
}
var invoices = await stripeAdapter.InvoiceListAsync(new StripeInvoiceListOptions
var invoices = await stripeAdapter.ListInvoicesAsync(new StripeInvoiceListOptions
{
Customer = subscriber.GatewayCustomerId,
Limit = pageSize,

View File

@@ -12,7 +12,6 @@ using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Settings;
using Braintree;
using Microsoft.Extensions.Logging;
@@ -68,7 +67,7 @@ public class PremiumUserBillingService(
}
};
customer = await stripeAdapter.CustomerCreateAsync(options);
customer = await stripeAdapter.CreateCustomerAsync(options);
user.Gateway = GatewayType.Stripe;
user.GatewayCustomerId = customer.Id;
@@ -81,7 +80,7 @@ public class PremiumUserBillingService(
Balance = customer.Balance + credit
};
await stripeAdapter.CustomerUpdateAsync(customer.Id, options);
await stripeAdapter.UpdateCustomerAsync(customer.Id, options);
}
}
@@ -227,7 +226,7 @@ public class PremiumUserBillingService(
case PaymentMethodType.BankAccount:
{
var setupIntent =
(await stripeAdapter.SetupIntentList(new SetupIntentListOptions { PaymentMethod = paymentMethodToken }))
(await stripeAdapter.ListSetupIntentsAsync(new SetupIntentListOptions { PaymentMethod = paymentMethodToken }))
.FirstOrDefault();
if (setupIntent == null)
@@ -260,7 +259,7 @@ public class PremiumUserBillingService(
try
{
return await stripeAdapter.CustomerCreateAsync(customerCreateOptions);
return await stripeAdapter.CreateCustomerAsync(customerCreateOptions);
}
catch (StripeException stripeException) when (stripeException.StripeError?.Code ==
StripeConstants.ErrorCodes.CustomerTaxLocationInvalid)
@@ -347,11 +346,11 @@ public class PremiumUserBillingService(
OffSession = true
};
var subscription = await stripeAdapter.SubscriptionCreateAsync(subscriptionCreateOptions);
var subscription = await stripeAdapter.CreateSubscriptionAsync(subscriptionCreateOptions);
if (usingPayPal)
{
await stripeAdapter.InvoiceUpdateAsync(subscription.LatestInvoiceId, new InvoiceUpdateOptions
await stripeAdapter.UpdateInvoiceAsync(subscription.LatestInvoiceId, new InvoiceUpdateOptions
{
AutoAdvance = false
});
@@ -387,6 +386,6 @@ public class PremiumUserBillingService(
}
};
return await stripeAdapter.CustomerUpdateAsync(customer.Id, options);
return await stripeAdapter.UpdateCustomerAsync(customer.Id, options);
}
}

View File

@@ -0,0 +1,209 @@
// FIXME: Update this file to be null safe and then delete the line below
#nullable disable
using Bit.Core.Models.BitStripe;
using Stripe;
using Stripe.Tax;
using Stripe.TestHelpers;
using CustomerService = Stripe.CustomerService;
using RefundService = Stripe.RefundService;
namespace Bit.Core.Billing.Services.Implementations;
public class StripeAdapter : IStripeAdapter
{
private readonly CustomerService _customerService;
private readonly SubscriptionService _subscriptionService;
private readonly InvoiceService _invoiceService;
private readonly PaymentMethodService _paymentMethodService;
private readonly TaxIdService _taxIdService;
private readonly ChargeService _chargeService;
private readonly RefundService _refundService;
private readonly CardService _cardService;
private readonly BankAccountService _bankAccountService;
private readonly PriceService _priceService;
private readonly SetupIntentService _setupIntentService;
private readonly TestClockService _testClockService;
private readonly CustomerBalanceTransactionService _customerBalanceTransactionService;
private readonly RegistrationService _taxRegistrationService;
public StripeAdapter()
{
_customerService = new CustomerService();
_subscriptionService = new SubscriptionService();
_invoiceService = new InvoiceService();
_paymentMethodService = new PaymentMethodService();
_taxIdService = new TaxIdService();
_chargeService = new ChargeService();
_refundService = new RefundService();
_cardService = new CardService();
_bankAccountService = new BankAccountService();
_priceService = new PriceService();
_setupIntentService = new SetupIntentService();
_testClockService = new TestClockService();
_customerBalanceTransactionService = new CustomerBalanceTransactionService();
_taxRegistrationService = new RegistrationService();
}
/**************
** CUSTOMER **
**************/
public Task<Customer> CreateCustomerAsync(CustomerCreateOptions options) =>
_customerService.CreateAsync(options);
public Task DeleteCustomerDiscountAsync(string customerId, CustomerDeleteDiscountOptions options = null) =>
_customerService.DeleteDiscountAsync(customerId, options);
public Task<Customer> GetCustomerAsync(string id, CustomerGetOptions options = null) =>
_customerService.GetAsync(id, options);
public Task<Customer> UpdateCustomerAsync(string id, CustomerUpdateOptions options = null) =>
_customerService.UpdateAsync(id, options);
public Task<Customer> DeleteCustomerAsync(string id) =>
_customerService.DeleteAsync(id);
public async Task<List<PaymentMethod>> ListCustomerPaymentMethodsAsync(string id,
CustomerPaymentMethodListOptions options = null)
{
var paymentMethods = await _customerService.ListPaymentMethodsAsync(id, options);
return paymentMethods.Data;
}
public Task<CustomerBalanceTransaction> CreateCustomerBalanceTransactionAsync(string customerId,
CustomerBalanceTransactionCreateOptions options) =>
_customerBalanceTransactionService.CreateAsync(customerId, options);
/******************
** SUBSCRIPTION **
******************/
public Task<Subscription> CreateSubscriptionAsync(SubscriptionCreateOptions options) =>
_subscriptionService.CreateAsync(options);
public Task<Subscription> GetSubscriptionAsync(string id, SubscriptionGetOptions options = null) =>
_subscriptionService.GetAsync(id, options);
public Task<Subscription> UpdateSubscriptionAsync(string id,
SubscriptionUpdateOptions options = null) =>
_subscriptionService.UpdateAsync(id, options);
public Task<Subscription> CancelSubscriptionAsync(string id, SubscriptionCancelOptions options = null) =>
_subscriptionService.CancelAsync(id, options);
/*************
** INVOICE **
*************/
public Task<Invoice> GetInvoiceAsync(string id, InvoiceGetOptions options) =>
_invoiceService.GetAsync(id, options);
public async Task<List<Invoice>> ListInvoicesAsync(StripeInvoiceListOptions options)
{
if (!options.SelectAll)
{
return (await _invoiceService.ListAsync(options.ToInvoiceListOptions())).Data;
}
options.Limit = 100;
var invoices = new List<Invoice>();
await foreach (var invoice in _invoiceService.ListAutoPagingAsync(options.ToInvoiceListOptions()))
{
invoices.Add(invoice);
}
return invoices;
}
public Task<Invoice> CreateInvoicePreviewAsync(InvoiceCreatePreviewOptions options) =>
_invoiceService.CreatePreviewAsync(options);
public async Task<List<Invoice>> SearchInvoiceAsync(InvoiceSearchOptions options) =>
(await _invoiceService.SearchAsync(options)).Data;
public Task<Invoice> UpdateInvoiceAsync(string id, InvoiceUpdateOptions options) =>
_invoiceService.UpdateAsync(id, options);
public Task<Invoice> FinalizeInvoiceAsync(string id, InvoiceFinalizeOptions options) =>
_invoiceService.FinalizeInvoiceAsync(id, options);
public Task<Invoice> SendInvoiceAsync(string id, InvoiceSendOptions options) =>
_invoiceService.SendInvoiceAsync(id, options);
public Task<Invoice> PayInvoiceAsync(string id, InvoicePayOptions options = null) =>
_invoiceService.PayAsync(id, options);
public Task<Invoice> DeleteInvoiceAsync(string id, InvoiceDeleteOptions options = null) =>
_invoiceService.DeleteAsync(id, options);
public Task<Invoice> VoidInvoiceAsync(string id, InvoiceVoidOptions options = null) =>
_invoiceService.VoidInvoiceAsync(id, options);
/********************
** PAYMENT METHOD **
********************/
public IEnumerable<PaymentMethod> ListPaymentMethodsAutoPaging(PaymentMethodListOptions options) =>
_paymentMethodService.ListAutoPaging(options);
public IAsyncEnumerable<PaymentMethod> ListPaymentMethodsAutoPagingAsync(PaymentMethodListOptions options)
=> _paymentMethodService.ListAutoPagingAsync(options);
public Task<PaymentMethod> AttachPaymentMethodAsync(string id, PaymentMethodAttachOptions options = null) =>
_paymentMethodService.AttachAsync(id, options);
public Task<PaymentMethod> DetachPaymentMethodAsync(string id, PaymentMethodDetachOptions options = null) =>
_paymentMethodService.DetachAsync(id, options);
/************
** TAX ID **
************/
public Task<TaxId> CreateTaxIdAsync(string id, TaxIdCreateOptions options) =>
_taxIdService.CreateAsync(id, options);
public Task<TaxId> DeleteTaxIdAsync(string customerId, string taxIdId,
TaxIdDeleteOptions options = null) =>
_taxIdService.DeleteAsync(customerId, taxIdId, options);
/******************
** BANK ACCOUNT **
******************/
public Task<BankAccount> DeleteBankAccountAsync(string customerId, string bankAccount, BankAccountDeleteOptions options = null) =>
_bankAccountService.DeleteAsync(customerId, bankAccount, options);
/***********
** PRICE **
***********/
public Task<Price> GetPriceAsync(string id, PriceGetOptions options = null) =>
_priceService.GetAsync(id, options);
/******************
** SETUP INTENT **
******************/
public Task<SetupIntent> CreateSetupIntentAsync(SetupIntentCreateOptions options) =>
_setupIntentService.CreateAsync(options);
public async Task<List<SetupIntent>> ListSetupIntentsAsync(SetupIntentListOptions options) =>
(await _setupIntentService.ListAsync(options)).Data;
public Task CancelSetupIntentAsync(string id, SetupIntentCancelOptions options = null) =>
_setupIntentService.CancelAsync(id, options);
public Task<SetupIntent> GetSetupIntentAsync(string id, SetupIntentGetOptions options = null) =>
_setupIntentService.GetAsync(id, options);
/*******************
** MISCELLANEOUS **
*******************/
public Task<StripeList<Charge>> ListChargesAsync(ChargeListOptions options) =>
_chargeService.ListAsync(options);
public Task<StripeList<Registration>> ListTaxRegistrationsAsync(RegistrationListOptions options = null) =>
_taxRegistrationService.ListAsync(options);
public Task<Refund> CreateRefundAsync(RefundCreateOptions options) =>
_refundService.CreateAsync(options);
public Task<Card> DeleteCardAsync(string customerId, string cardId, CardDeleteOptions options = null) =>
_cardService.DeleteAsync(customerId, cardId, options);
}

View File

@@ -21,9 +21,9 @@ using Stripe;
using PaymentMethod = Stripe.PaymentMethod;
using StaticStore = Bit.Core.Models.StaticStore;
namespace Bit.Core.Services;
namespace Bit.Core.Billing.Services.Implementations;
public class StripePaymentService : IPaymentService
public class StripePaymentService : IStripePaymentService
{
private const string SecretsManagerStandaloneDiscountId = "sm-standalone";
@@ -64,7 +64,7 @@ public class StripePaymentService : IPaymentService
await FinalizeSubscriptionChangeAsync(org, subscriptionUpdate, true);
var sub = await _stripeAdapter.SubscriptionGetAsync(org.GatewaySubscriptionId);
var sub = await _stripeAdapter.GetSubscriptionAsync(org.GatewaySubscriptionId);
org.ExpirationDate = sub.GetCurrentPeriodEnd();
if (sponsorship is not null)
@@ -84,7 +84,7 @@ public class StripePaymentService : IPaymentService
{
// remember, when in doubt, throw
var subGetOptions = new SubscriptionGetOptions { Expand = ["customer.tax", "customer.tax_ids"] };
var sub = await _stripeAdapter.SubscriptionGetAsync(subscriber.GatewaySubscriptionId, subGetOptions);
var sub = await _stripeAdapter.GetSubscriptionAsync(subscriber.GatewaySubscriptionId, subGetOptions);
if (sub == null)
{
throw new GatewayException("Subscription not found.");
@@ -107,7 +107,7 @@ public class StripePaymentService : IPaymentService
var subUpdateOptions = new SubscriptionUpdateOptions
{
Items = updatedItemOptions,
ProrationBehavior = invoiceNow ? Constants.AlwaysInvoice : Constants.CreateProrations,
ProrationBehavior = invoiceNow ? Core.Constants.AlwaysInvoice : Core.Constants.CreateProrations,
DaysUntilDue = daysUntilDue ?? 1,
CollectionMethod = "send_invoice"
};
@@ -121,11 +121,11 @@ public class StripePaymentService : IPaymentService
{
if (sub.Customer is
{
Address.Country: not Constants.CountryAbbreviations.UnitedStates,
Address.Country: not Core.Constants.CountryAbbreviations.UnitedStates,
TaxExempt: not StripeConstants.TaxExempt.Reverse
})
{
await _stripeAdapter.CustomerUpdateAsync(sub.CustomerId,
await _stripeAdapter.UpdateCustomerAsync(sub.CustomerId,
new CustomerUpdateOptions { TaxExempt = StripeConstants.TaxExempt.Reverse });
}
@@ -141,9 +141,9 @@ public class StripePaymentService : IPaymentService
string paymentIntentClientSecret = null;
try
{
var subResponse = await _stripeAdapter.SubscriptionUpdateAsync(sub.Id, subUpdateOptions);
var subResponse = await _stripeAdapter.UpdateSubscriptionAsync(sub.Id, subUpdateOptions);
var invoice = await _stripeAdapter.InvoiceGetAsync(subResponse?.LatestInvoiceId, new InvoiceGetOptions());
var invoice = await _stripeAdapter.GetInvoiceAsync(subResponse?.LatestInvoiceId, new InvoiceGetOptions());
if (invoice == null)
{
throw new BadRequestException("Unable to locate draft invoice for subscription update.");
@@ -162,9 +162,9 @@ public class StripePaymentService : IPaymentService
}
else
{
invoice = await _stripeAdapter.InvoiceFinalizeInvoiceAsync(subResponse.LatestInvoiceId,
invoice = await _stripeAdapter.FinalizeInvoiceAsync(subResponse.LatestInvoiceId,
new InvoiceFinalizeOptions { AutoAdvance = false, });
await _stripeAdapter.InvoiceSendInvoiceAsync(invoice.Id, new InvoiceSendOptions());
await _stripeAdapter.SendInvoiceAsync(invoice.Id, new InvoiceSendOptions());
paymentIntentClientSecret = null;
}
}
@@ -172,7 +172,7 @@ public class StripePaymentService : IPaymentService
catch
{
// Need to revert the subscription
await _stripeAdapter.SubscriptionUpdateAsync(sub.Id, new SubscriptionUpdateOptions
await _stripeAdapter.UpdateSubscriptionAsync(sub.Id, new SubscriptionUpdateOptions
{
Items = subscriptionUpdate.RevertItemsOptions(sub),
// This proration behavior prevents a false "credit" from
@@ -187,7 +187,7 @@ public class StripePaymentService : IPaymentService
else if (invoice.Status != StripeConstants.InvoiceStatus.Paid)
{
// Pay invoice with no charge to the customer this completes the invoice immediately without waiting the scheduled 1h
invoice = await _stripeAdapter.InvoicePayAsync(subResponse.LatestInvoiceId);
invoice = await _stripeAdapter.PayInvoiceAsync(subResponse.LatestInvoiceId);
paymentIntentClientSecret = null;
}
}
@@ -196,7 +196,7 @@ public class StripePaymentService : IPaymentService
// Change back the subscription collection method and/or days until due
if (collectionMethod != "send_invoice" || daysUntilDue == null)
{
await _stripeAdapter.SubscriptionUpdateAsync(sub.Id,
await _stripeAdapter.UpdateSubscriptionAsync(sub.Id,
new SubscriptionUpdateOptions
{
CollectionMethod = collectionMethod,
@@ -204,14 +204,14 @@ public class StripePaymentService : IPaymentService
});
}
var customer = await _stripeAdapter.CustomerGetAsync(sub.CustomerId);
var customer = await _stripeAdapter.GetCustomerAsync(sub.CustomerId);
var newCoupon = customer.Discount?.Coupon?.Id;
if (!string.IsNullOrEmpty(existingCoupon) && string.IsNullOrEmpty(newCoupon))
{
// Re-add the lost coupon due to the update.
await _stripeAdapter.SubscriptionUpdateAsync(sub.Id, new SubscriptionUpdateOptions
await _stripeAdapter.UpdateSubscriptionAsync(sub.Id, new SubscriptionUpdateOptions
{
Discounts =
[
@@ -284,7 +284,7 @@ public class StripePaymentService : IPaymentService
{
if (!string.IsNullOrWhiteSpace(subscriber.GatewaySubscriptionId))
{
await _stripeAdapter.SubscriptionCancelAsync(subscriber.GatewaySubscriptionId,
await _stripeAdapter.CancelSubscriptionAsync(subscriber.GatewaySubscriptionId,
new SubscriptionCancelOptions());
}
@@ -293,7 +293,7 @@ public class StripePaymentService : IPaymentService
return;
}
var customer = await _stripeAdapter.CustomerGetAsync(subscriber.GatewayCustomerId);
var customer = await _stripeAdapter.GetCustomerAsync(subscriber.GatewayCustomerId);
if (customer == null)
{
return;
@@ -318,7 +318,7 @@ public class StripePaymentService : IPaymentService
}
else
{
var charges = await _stripeAdapter.ChargeListAsync(new ChargeListOptions
var charges = await _stripeAdapter.ListChargesAsync(new ChargeListOptions
{
Customer = subscriber.GatewayCustomerId
});
@@ -327,12 +327,12 @@ public class StripePaymentService : IPaymentService
{
foreach (var charge in charges.Data.Where(c => c.Captured && !c.Refunded))
{
await _stripeAdapter.RefundCreateAsync(new RefundCreateOptions { Charge = charge.Id });
await _stripeAdapter.CreateRefundAsync(new RefundCreateOptions { Charge = charge.Id });
}
}
}
await _stripeAdapter.CustomerDeleteAsync(subscriber.GatewayCustomerId);
await _stripeAdapter.DeleteCustomerAsync(subscriber.GatewayCustomerId);
}
public async Task<string> PayInvoiceAfterSubscriptionChangeAsync(ISubscriber subscriber, Invoice invoice)
@@ -340,7 +340,7 @@ public class StripePaymentService : IPaymentService
var customerOptions = new CustomerGetOptions();
customerOptions.AddExpand("default_source");
customerOptions.AddExpand("invoice_settings.default_payment_method");
var customer = await _stripeAdapter.CustomerGetAsync(subscriber.GatewayCustomerId, customerOptions);
var customer = await _stripeAdapter.GetCustomerAsync(subscriber.GatewayCustomerId, customerOptions);
string paymentIntentClientSecret = null;
@@ -360,13 +360,13 @@ public class StripePaymentService : IPaymentService
// We're going to delete this draft invoice, it can't be paid
try
{
await _stripeAdapter.InvoiceDeleteAsync(invoice.Id);
await _stripeAdapter.DeleteInvoiceAsync(invoice.Id);
}
catch
{
await _stripeAdapter.InvoiceFinalizeInvoiceAsync(invoice.Id,
await _stripeAdapter.FinalizeInvoiceAsync(invoice.Id,
new InvoiceFinalizeOptions { AutoAdvance = false });
await _stripeAdapter.InvoiceVoidInvoiceAsync(invoice.Id);
await _stripeAdapter.VoidInvoiceAsync(invoice.Id);
}
throw new BadRequestException("No payment method is available.");
@@ -379,7 +379,7 @@ public class StripePaymentService : IPaymentService
{
// Finalize the invoice (from Draft) w/o auto-advance so we
// can attempt payment manually.
invoice = await _stripeAdapter.InvoiceFinalizeInvoiceAsync(invoice.Id,
invoice = await _stripeAdapter.FinalizeInvoiceAsync(invoice.Id,
new InvoiceFinalizeOptions { AutoAdvance = false, });
var invoicePayOptions = new InvoicePayOptions { PaymentMethod = cardPaymentMethodId, };
if (customer?.Metadata?.ContainsKey("btCustomerId") ?? false)
@@ -414,7 +414,7 @@ public class StripePaymentService : IPaymentService
}
braintreeTransaction = transactionResult.Target;
invoice = await _stripeAdapter.InvoiceUpdateAsync(invoice.Id, new InvoiceUpdateOptions
invoice = await _stripeAdapter.UpdateInvoiceAsync(invoice.Id, new InvoiceUpdateOptions
{
Metadata = new Dictionary<string, string>
{
@@ -428,7 +428,7 @@ public class StripePaymentService : IPaymentService
try
{
invoice = await _stripeAdapter.InvoicePayAsync(invoice.Id, invoicePayOptions);
invoice = await _stripeAdapter.PayInvoiceAsync(invoice.Id, invoicePayOptions);
}
catch (StripeException e)
{
@@ -438,7 +438,7 @@ public class StripePaymentService : IPaymentService
// SCA required, get intent client secret
var invoiceGetOptions = new InvoiceGetOptions();
invoiceGetOptions.AddExpand("confirmation_secret");
invoice = await _stripeAdapter.InvoiceGetAsync(invoice.Id, invoiceGetOptions);
invoice = await _stripeAdapter.GetInvoiceAsync(invoice.Id, invoiceGetOptions);
paymentIntentClientSecret = invoice?.ConfirmationSecret?.ClientSecret;
}
else
@@ -462,7 +462,7 @@ public class StripePaymentService : IPaymentService
return paymentIntentClientSecret;
}
invoice = await _stripeAdapter.InvoiceVoidInvoiceAsync(invoice.Id, new InvoiceVoidOptions());
invoice = await _stripeAdapter.VoidInvoiceAsync(invoice.Id, new InvoiceVoidOptions());
// HACK: Workaround for customer balance credit
if (invoice.StartingBalance < 0)
@@ -470,12 +470,12 @@ public class StripePaymentService : IPaymentService
// Customer had a balance applied to this invoice. Since we can't fully trust Stripe to
// credit it back to the customer (even though their docs claim they will), we need to
// check that balance against the current customer balance and determine if it needs to be re-applied
customer = await _stripeAdapter.CustomerGetAsync(subscriber.GatewayCustomerId, customerOptions);
customer = await _stripeAdapter.GetCustomerAsync(subscriber.GatewayCustomerId, customerOptions);
// Assumption: Customer balance should now be $0, otherwise payment would not have failed.
if (customer.Balance == 0)
{
await _stripeAdapter.CustomerUpdateAsync(customer.Id,
await _stripeAdapter.UpdateCustomerAsync(customer.Id,
new CustomerUpdateOptions { Balance = invoice.StartingBalance });
}
}
@@ -506,7 +506,7 @@ public class StripePaymentService : IPaymentService
throw new GatewayException("No subscription.");
}
var sub = await _stripeAdapter.SubscriptionGetAsync(subscriber.GatewaySubscriptionId);
var sub = await _stripeAdapter.GetSubscriptionAsync(subscriber.GatewaySubscriptionId);
if (sub == null)
{
throw new GatewayException("Subscription was not found.");
@@ -522,9 +522,9 @@ public class StripePaymentService : IPaymentService
try
{
var canceledSub = endOfPeriod
? await _stripeAdapter.SubscriptionUpdateAsync(sub.Id,
? await _stripeAdapter.UpdateSubscriptionAsync(sub.Id,
new SubscriptionUpdateOptions { CancelAtPeriodEnd = true })
: await _stripeAdapter.SubscriptionCancelAsync(sub.Id, new SubscriptionCancelOptions());
: await _stripeAdapter.CancelSubscriptionAsync(sub.Id, new SubscriptionCancelOptions());
if (!canceledSub.CanceledAt.HasValue)
{
throw new GatewayException("Unable to cancel subscription.");
@@ -551,7 +551,7 @@ public class StripePaymentService : IPaymentService
throw new GatewayException("No subscription.");
}
var sub = await _stripeAdapter.SubscriptionGetAsync(subscriber.GatewaySubscriptionId);
var sub = await _stripeAdapter.GetSubscriptionAsync(subscriber.GatewaySubscriptionId);
if (sub == null)
{
throw new GatewayException("Subscription was not found.");
@@ -563,7 +563,7 @@ public class StripePaymentService : IPaymentService
throw new GatewayException("Subscription is not marked for cancellation.");
}
var updatedSub = await _stripeAdapter.SubscriptionUpdateAsync(sub.Id,
var updatedSub = await _stripeAdapter.UpdateSubscriptionAsync(sub.Id,
new SubscriptionUpdateOptions { CancelAtPeriodEnd = false });
if (updatedSub.CanceledAt.HasValue)
{
@@ -578,11 +578,11 @@ public class StripePaymentService : IPaymentService
!string.IsNullOrWhiteSpace(subscriber.GatewayCustomerId);
if (customerExists)
{
customer = await _stripeAdapter.CustomerGetAsync(subscriber.GatewayCustomerId);
customer = await _stripeAdapter.GetCustomerAsync(subscriber.GatewayCustomerId);
}
else
{
customer = await _stripeAdapter.CustomerCreateAsync(new CustomerCreateOptions
customer = await _stripeAdapter.CreateCustomerAsync(new CustomerCreateOptions
{
Email = subscriber.BillingEmailAddress(),
Description = subscriber.BillingName(),
@@ -591,9 +591,8 @@ public class StripePaymentService : IPaymentService
subscriber.GatewayCustomerId = customer.Id;
}
await _stripeAdapter.CustomerUpdateAsync(customer.Id,
await _stripeAdapter.UpdateCustomerAsync(customer.Id,
new CustomerUpdateOptions { Balance = customer.Balance - (long)(creditAmount * 100) });
return !customerExists;
}
@@ -630,7 +629,7 @@ public class StripePaymentService : IPaymentService
return subscriptionInfo;
}
var subscription = await _stripeAdapter.SubscriptionGetAsync(subscriber.GatewaySubscriptionId,
var subscription = await _stripeAdapter.GetSubscriptionAsync(subscriber.GatewaySubscriptionId,
new SubscriptionGetOptions { Expand = ["customer.discount.coupon.applies_to", "discounts.coupon.applies_to", "test_clock"] });
if (subscription == null)
@@ -675,7 +674,7 @@ public class StripePaymentService : IPaymentService
Subscription = subscriber.GatewaySubscriptionId
};
var upcomingInvoice = await _stripeAdapter.InvoiceCreatePreviewAsync(invoiceCreatePreviewOptions);
var upcomingInvoice = await _stripeAdapter.CreateInvoicePreviewAsync(invoiceCreatePreviewOptions);
if (upcomingInvoice != null)
{
@@ -726,7 +725,7 @@ public class StripePaymentService : IPaymentService
return false;
}
var customer = await _stripeAdapter.CustomerGetAsync(gatewayCustomerId);
var customer = await _stripeAdapter.GetCustomerAsync(gatewayCustomerId);
return customer?.Discount?.Coupon?.Id == SecretsManagerStandaloneDiscountId;
}
@@ -738,7 +737,7 @@ public class StripePaymentService : IPaymentService
return (null, null);
}
var openInvoices = await _stripeAdapter.InvoiceSearchAsync(new InvoiceSearchOptions
var openInvoices = await _stripeAdapter.SearchInvoiceAsync(new InvoiceSearchOptions
{
Query = $"subscription:'{subscription.Id}' status:'open'"
});
@@ -774,7 +773,7 @@ public class StripePaymentService : IPaymentService
private PaymentMethod GetLatestCardPaymentMethod(string customerId)
{
var cardPaymentMethods = _stripeAdapter.PaymentMethodListAutoPaging(
var cardPaymentMethods = _stripeAdapter.ListPaymentMethodsAutoPaging(
new PaymentMethodListOptions { Customer = customerId, Type = "card" });
return cardPaymentMethods.OrderByDescending(m => m.Created).FirstOrDefault();
}
@@ -837,7 +836,7 @@ public class StripePaymentService : IPaymentService
Customer customer = null;
try
{
customer = await _stripeAdapter.CustomerGetAsync(gatewayCustomerId, options);
customer = await _stripeAdapter.GetCustomerAsync(gatewayCustomerId, options);
}
catch (StripeException)
{
@@ -870,21 +869,21 @@ public class StripePaymentService : IPaymentService
try
{
var paidInvoicesTask = _stripeAdapter.InvoiceListAsync(new StripeInvoiceListOptions
var paidInvoicesTask = _stripeAdapter.ListInvoicesAsync(new StripeInvoiceListOptions
{
Customer = customer.Id,
SelectAll = !limit.HasValue,
Limit = limit,
Status = "paid"
});
var openInvoicesTask = _stripeAdapter.InvoiceListAsync(new StripeInvoiceListOptions
var openInvoicesTask = _stripeAdapter.ListInvoicesAsync(new StripeInvoiceListOptions
{
Customer = customer.Id,
SelectAll = !limit.HasValue,
Limit = limit,
Status = "open"
});
var uncollectibleInvoicesTask = _stripeAdapter.InvoiceListAsync(new StripeInvoiceListOptions
var uncollectibleInvoicesTask = _stripeAdapter.ListInvoicesAsync(new StripeInvoiceListOptions
{
Customer = customer.Id,
SelectAll = !limit.HasValue,

View File

@@ -1,6 +1,6 @@
using Bit.Core.Exceptions;
namespace Bit.Core.Services;
namespace Bit.Core.Billing.Services.Implementations;
public class StripeSyncService : IStripeSyncService
{
@@ -11,7 +11,7 @@ public class StripeSyncService : IStripeSyncService
_stripeAdapter = stripeAdapter;
}
public async Task UpdateCustomerEmailAddress(string gatewayCustomerId, string emailAddress)
public async Task UpdateCustomerEmailAddressAsync(string gatewayCustomerId, string emailAddress)
{
if (string.IsNullOrWhiteSpace(gatewayCustomerId))
{
@@ -23,9 +23,9 @@ public class StripeSyncService : IStripeSyncService
throw new InvalidEmailException();
}
var customer = await _stripeAdapter.CustomerGetAsync(gatewayCustomerId);
var customer = await _stripeAdapter.GetCustomerAsync(gatewayCustomerId);
await _stripeAdapter.CustomerUpdateAsync(customer.Id,
await _stripeAdapter.UpdateCustomerAsync(customer.Id,
new Stripe.CustomerUpdateOptions { Email = emailAddress });
}
}

View File

@@ -15,7 +15,6 @@ using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Settings;
using Bit.Core.Utilities;
using Braintree;
@@ -78,7 +77,7 @@ public class SubscriberService(
{
if (subscription.Metadata != null && subscription.Metadata.ContainsKey("organizationId"))
{
await stripeAdapter.SubscriptionUpdateAsync(subscription.Id, new SubscriptionUpdateOptions
await stripeAdapter.UpdateSubscriptionAsync(subscription.Id, new SubscriptionUpdateOptions
{
Metadata = metadata
});
@@ -97,7 +96,7 @@ public class SubscriberService(
options.CancellationDetails.Feedback = offboardingSurveyResponse.Reason;
}
await stripeAdapter.SubscriptionCancelAsync(subscription.Id, options);
await stripeAdapter.CancelSubscriptionAsync(subscription.Id, options);
}
else
{
@@ -116,7 +115,7 @@ public class SubscriberService(
options.CancellationDetails.Feedback = offboardingSurveyResponse.Reason;
}
await stripeAdapter.SubscriptionUpdateAsync(subscription.Id, options);
await stripeAdapter.UpdateSubscriptionAsync(subscription.Id, options);
}
}
@@ -227,7 +226,7 @@ public class SubscriberService(
_ => throw new ArgumentOutOfRangeException(nameof(subscriber))
};
var customer = await stripeAdapter.CustomerCreateAsync(options);
var customer = await stripeAdapter.CreateCustomerAsync(options);
switch (subscriber)
{
@@ -270,7 +269,7 @@ public class SubscriberService(
try
{
var customer = await stripeAdapter.CustomerGetAsync(subscriber.GatewayCustomerId, customerGetOptions);
var customer = await stripeAdapter.GetCustomerAsync(subscriber.GatewayCustomerId, customerGetOptions);
if (customer != null)
{
@@ -306,7 +305,7 @@ public class SubscriberService(
try
{
var customer = await stripeAdapter.CustomerGetAsync(subscriber.GatewayCustomerId, customerGetOptions);
var customer = await stripeAdapter.GetCustomerAsync(subscriber.GatewayCustomerId, customerGetOptions);
if (customer != null)
{
@@ -357,7 +356,7 @@ public class SubscriberService(
try
{
var subscription = await stripeAdapter.SubscriptionGetAsync(subscriber.GatewaySubscriptionId, subscriptionGetOptions);
var subscription = await stripeAdapter.GetSubscriptionAsync(subscriber.GatewaySubscriptionId, subscriptionGetOptions);
if (subscription != null)
{
@@ -393,7 +392,7 @@ public class SubscriberService(
try
{
var subscription = await stripeAdapter.SubscriptionGetAsync(subscriber.GatewaySubscriptionId, subscriptionGetOptions);
var subscription = await stripeAdapter.GetSubscriptionAsync(subscriber.GatewaySubscriptionId, subscriptionGetOptions);
if (subscription != null)
{
@@ -487,23 +486,23 @@ public class SubscriberService(
switch (source)
{
case BankAccount:
await stripeAdapter.BankAccountDeleteAsync(stripeCustomer.Id, source.Id);
await stripeAdapter.DeleteBankAccountAsync(stripeCustomer.Id, source.Id);
break;
case Card:
await stripeAdapter.CardDeleteAsync(stripeCustomer.Id, source.Id);
await stripeAdapter.DeleteCardAsync(stripeCustomer.Id, source.Id);
break;
}
}
}
var paymentMethods = stripeAdapter.PaymentMethodListAutoPagingAsync(new PaymentMethodListOptions
var paymentMethods = stripeAdapter.ListPaymentMethodsAutoPagingAsync(new PaymentMethodListOptions
{
Customer = stripeCustomer.Id
});
await foreach (var paymentMethod in paymentMethods)
{
await stripeAdapter.PaymentMethodDetachAsync(paymentMethod.Id);
await stripeAdapter.DetachPaymentMethodAsync(paymentMethod.Id);
}
}
}
@@ -532,7 +531,7 @@ public class SubscriberService(
{
case PaymentMethodType.BankAccount:
{
var getSetupIntentsForUpdatedPaymentMethod = stripeAdapter.SetupIntentList(new SetupIntentListOptions
var getSetupIntentsForUpdatedPaymentMethod = stripeAdapter.ListSetupIntentsAsync(new SetupIntentListOptions
{
PaymentMethod = token
});
@@ -569,7 +568,7 @@ public class SubscriberService(
await RemoveStripePaymentMethodsAsync(customer);
// Attach the incoming payment method.
await stripeAdapter.PaymentMethodAttachAsync(token,
await stripeAdapter.AttachPaymentMethodAsync(token,
new PaymentMethodAttachOptions { Customer = subscriber.GatewayCustomerId });
var metadata = customer.Metadata;
@@ -581,7 +580,7 @@ public class SubscriberService(
}
// Set the customer's default payment method in Stripe and remove their Braintree customer ID.
await stripeAdapter.CustomerUpdateAsync(subscriber.GatewayCustomerId, new CustomerUpdateOptions
await stripeAdapter.UpdateCustomerAsync(subscriber.GatewayCustomerId, new CustomerUpdateOptions
{
InvoiceSettings = new CustomerInvoiceSettingsOptions
{
@@ -644,7 +643,7 @@ public class SubscriberService(
Expand = ["subscriptions", "tax", "tax_ids"]
});
customer = await stripeAdapter.CustomerUpdateAsync(customer.Id, new CustomerUpdateOptions
customer = await stripeAdapter.UpdateCustomerAsync(customer.Id, new CustomerUpdateOptions
{
Address = new AddressOptions
{
@@ -662,7 +661,7 @@ public class SubscriberService(
if (taxId != null)
{
await stripeAdapter.TaxIdDeleteAsync(customer.Id, taxId.Id);
await stripeAdapter.DeleteTaxIdAsync(customer.Id, taxId.Id);
}
if (!string.IsNullOrWhiteSpace(taxInformation.TaxId))
@@ -685,12 +684,12 @@ public class SubscriberService(
try
{
await stripeAdapter.TaxIdCreateAsync(customer.Id,
await stripeAdapter.CreateTaxIdAsync(customer.Id,
new TaxIdCreateOptions { Type = taxIdType, Value = taxInformation.TaxId });
if (taxIdType == StripeConstants.TaxIdType.SpanishNIF)
{
await stripeAdapter.TaxIdCreateAsync(customer.Id,
await stripeAdapter.CreateTaxIdAsync(customer.Id,
new TaxIdCreateOptions { Type = StripeConstants.TaxIdType.EUVAT, Value = $"ES{taxInformation.TaxId}" });
}
}
@@ -736,7 +735,7 @@ public class SubscriberService(
Address.Country: not Core.Constants.CountryAbbreviations.UnitedStates,
TaxExempt: not TaxExempt.Reverse
}:
await stripeAdapter.CustomerUpdateAsync(customer.Id,
await stripeAdapter.UpdateCustomerAsync(customer.Id,
new CustomerUpdateOptions { TaxExempt = TaxExempt.Reverse });
break;
case
@@ -744,14 +743,14 @@ public class SubscriberService(
Address.Country: Core.Constants.CountryAbbreviations.UnitedStates,
TaxExempt: TaxExempt.Reverse
}:
await stripeAdapter.CustomerUpdateAsync(customer.Id,
await stripeAdapter.UpdateCustomerAsync(customer.Id,
new CustomerUpdateOptions { TaxExempt = TaxExempt.None });
break;
}
if (!subscription.AutomaticTax.Enabled)
{
await stripeAdapter.SubscriptionUpdateAsync(subscription.Id,
await stripeAdapter.UpdateSubscriptionAsync(subscription.Id,
new SubscriptionUpdateOptions
{
AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true }
@@ -771,7 +770,7 @@ public class SubscriberService(
if (automaticTaxShouldBeEnabled && !subscription.AutomaticTax.Enabled)
{
await stripeAdapter.SubscriptionUpdateAsync(subscription.Id,
await stripeAdapter.UpdateSubscriptionAsync(subscription.Id,
new SubscriptionUpdateOptions
{
AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true }
@@ -790,7 +789,7 @@ public class SubscriberService(
}
try
{
await stripeAdapter.CustomerGetAsync(subscriber.GatewayCustomerId);
await stripeAdapter.GetCustomerAsync(subscriber.GatewayCustomerId);
return true;
}
catch (StripeException e) when (e.StripeError.Code == "resource_missing")
@@ -809,7 +808,7 @@ public class SubscriberService(
}
try
{
await stripeAdapter.SubscriptionGetAsync(subscriber.GatewaySubscriptionId);
await stripeAdapter.GetSubscriptionAsync(subscriber.GatewaySubscriptionId);
return true;
}
catch (StripeException e) when (e.StripeError.Code == "resource_missing")
@@ -828,7 +827,7 @@ public class SubscriberService(
metadata[BraintreeCustomerIdKey] = braintreeCustomerId;
await stripeAdapter.CustomerUpdateAsync(customer.Id, new CustomerUpdateOptions
await stripeAdapter.UpdateCustomerAsync(customer.Id, new CustomerUpdateOptions
{
Metadata = metadata
});
@@ -868,7 +867,7 @@ public class SubscriberService(
return null;
}
var setupIntent = await stripeAdapter.SetupIntentGet(setupIntentId, new SetupIntentGetOptions
var setupIntent = await stripeAdapter.GetSetupIntentAsync(setupIntentId, new SetupIntentGetOptions
{
Expand = ["payment_method"]
});
@@ -886,7 +885,7 @@ public class SubscriberService(
metadata[BraintreeCustomerIdOldKey] = value;
metadata[BraintreeCustomerIdKey] = null;
await stripeAdapter.CustomerUpdateAsync(customer.Id, new CustomerUpdateOptions
await stripeAdapter.UpdateCustomerAsync(customer.Id, new CustomerUpdateOptions
{
Metadata = metadata
});
@@ -903,18 +902,18 @@ public class SubscriberService(
switch (source)
{
case BankAccount:
await stripeAdapter.BankAccountDeleteAsync(customer.Id, source.Id);
await stripeAdapter.DeleteBankAccountAsync(customer.Id, source.Id);
break;
case Card:
await stripeAdapter.CardDeleteAsync(customer.Id, source.Id);
await stripeAdapter.DeleteCardAsync(customer.Id, source.Id);
break;
}
}
}
var paymentMethods = await stripeAdapter.CustomerListPaymentMethods(customer.Id);
var paymentMethods = await stripeAdapter.ListCustomerPaymentMethodsAsync(customer.Id);
await Task.WhenAll(paymentMethods.Select(pm => stripeAdapter.PaymentMethodDetachAsync(pm.Id)));
await Task.WhenAll(paymentMethods.Select(pm => stripeAdapter.DetachPaymentMethodAsync(pm.Id)));
}
private async Task ReplaceBraintreePaymentMethodAsync(

View File

@@ -7,7 +7,6 @@ using Bit.Core.Billing.Extensions;
using Bit.Core.Billing.Services;
using Bit.Core.Entities;
using Bit.Core.Repositories;
using Bit.Core.Services;
using OneOf.Types;
using Stripe;
@@ -53,7 +52,7 @@ public class RestartSubscriptionCommand(
TrialPeriodDays = 0
};
var subscription = await stripeAdapter.SubscriptionCreateAsync(options);
var subscription = await stripeAdapter.CreateSubscriptionAsync(options);
await EnableAsync(subscriber, subscription);
return new None();
}

View File

@@ -2,8 +2,8 @@
#nullable disable
using Bit.Core.Billing.Models;
using Bit.Core.Billing.Services;
using Bit.Core.Billing.Tax.Models;
using Bit.Core.Services;
using Stripe;
namespace Bit.Core.Billing;
@@ -22,7 +22,7 @@ public static class Utilities
return null;
}
var openInvoices = await stripeAdapter.InvoiceSearchAsync(new InvoiceSearchOptions
var openInvoices = await stripeAdapter.SearchInvoiceAsync(new InvoiceSearchOptions
{
Query = $"subscription:'{subscription.Id}' status:'open'"
});

View File

@@ -1,11 +1,11 @@
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Billing.Extensions;
using Bit.Core.Billing.Models;
using Bit.Core.Billing.Services;
using Bit.Core.Entities;
using Bit.Core.Exceptions;
using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.Interfaces;
using Bit.Core.Repositories;
using Bit.Core.Services;
namespace Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.Cloud;
@@ -13,9 +13,9 @@ public class SetUpSponsorshipCommand : ISetUpSponsorshipCommand
{
private readonly IOrganizationSponsorshipRepository _organizationSponsorshipRepository;
private readonly IOrganizationRepository _organizationRepository;
private readonly IPaymentService _paymentService;
private readonly IStripePaymentService _paymentService;
public SetUpSponsorshipCommand(IOrganizationSponsorshipRepository organizationSponsorshipRepository, IOrganizationRepository organizationRepository, IPaymentService paymentService)
public SetUpSponsorshipCommand(IOrganizationSponsorshipRepository organizationSponsorshipRepository, IOrganizationRepository organizationRepository, IStripePaymentService paymentService)
{
_organizationSponsorshipRepository = organizationSponsorshipRepository;
_organizationRepository = organizationRepository;

View File

@@ -4,6 +4,7 @@
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Billing.Extensions;
using Bit.Core.Billing.Models;
using Bit.Core.Billing.Services;
using Bit.Core.Entities;
using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.Interfaces;
using Bit.Core.Repositories;
@@ -14,14 +15,14 @@ namespace Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnte
public class ValidateSponsorshipCommand : CancelSponsorshipCommand, IValidateSponsorshipCommand
{
private readonly IPaymentService _paymentService;
private readonly IStripePaymentService _paymentService;
private readonly IMailService _mailService;
private readonly ILogger<ValidateSponsorshipCommand> _logger;
public ValidateSponsorshipCommand(
IOrganizationSponsorshipRepository organizationSponsorshipRepository,
IOrganizationRepository organizationRepository,
IPaymentService paymentService,
IStripePaymentService paymentService,
IMailService mailService,
ILogger<ValidateSponsorshipCommand> logger) : base(organizationSponsorshipRepository, organizationRepository)
{

View File

@@ -3,6 +3,7 @@ using Bit.Core.AdminConsole.Enums.Provider;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Pricing;
using Bit.Core.Billing.Services;
using Bit.Core.Exceptions;
using Bit.Core.Models.Business;
using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
@@ -12,13 +13,13 @@ namespace Bit.Core.OrganizationFeatures.OrganizationSubscriptions;
public class AddSecretsManagerSubscriptionCommand : IAddSecretsManagerSubscriptionCommand
{
private readonly IPaymentService _paymentService;
private readonly IStripePaymentService _paymentService;
private readonly IOrganizationService _organizationService;
private readonly IProviderRepository _providerRepository;
private readonly IPricingClient _pricingClient;
public AddSecretsManagerSubscriptionCommand(
IPaymentService paymentService,
IStripePaymentService paymentService,
IOrganizationService organizationService,
IProviderRepository providerRepository,
IPricingClient pricingClient)

View File

@@ -3,6 +3,7 @@
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Services;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.Business;
@@ -18,7 +19,7 @@ namespace Bit.Core.OrganizationFeatures.OrganizationSubscriptions;
public class UpdateSecretsManagerSubscriptionCommand : IUpdateSecretsManagerSubscriptionCommand
{
private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly IPaymentService _paymentService;
private readonly IStripePaymentService _paymentService;
private readonly IMailService _mailService;
private readonly ILogger<UpdateSecretsManagerSubscriptionCommand> _logger;
private readonly IServiceAccountRepository _serviceAccountRepository;
@@ -29,7 +30,7 @@ public class UpdateSecretsManagerSubscriptionCommand : IUpdateSecretsManagerSubs
public UpdateSecretsManagerSubscriptionCommand(
IOrganizationUserRepository organizationUserRepository,
IPaymentService paymentService,
IStripePaymentService paymentService,
IMailService mailService,
ILogger<UpdateSecretsManagerSubscriptionCommand> logger,
IServiceAccountRepository serviceAccountRepository,

View File

@@ -11,6 +11,7 @@ using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Organizations.Models;
using Bit.Core.Billing.Organizations.Services;
using Bit.Core.Billing.Pricing;
using Bit.Core.Billing.Services;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.Business;
@@ -26,7 +27,7 @@ public class UpgradeOrganizationPlanCommand : IUpgradeOrganizationPlanCommand
private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly ICollectionRepository _collectionRepository;
private readonly IGroupRepository _groupRepository;
private readonly IPaymentService _paymentService;
private readonly IStripePaymentService _paymentService;
private readonly IPolicyRepository _policyRepository;
private readonly ISsoConfigRepository _ssoConfigRepository;
private readonly IOrganizationConnectionRepository _organizationConnectionRepository;
@@ -41,7 +42,7 @@ public class UpgradeOrganizationPlanCommand : IUpgradeOrganizationPlanCommand
IOrganizationUserRepository organizationUserRepository,
ICollectionRepository collectionRepository,
IGroupRepository groupRepository,
IPaymentService paymentService,
IStripePaymentService paymentService,
IPolicyRepository policyRepository,
ISsoConfigRepository ssoConfigRepository,
IOrganizationConnectionRepository organizationConnectionRepository,

View File

@@ -1,54 +0,0 @@
// FIXME: Update this file to be null safe and then delete the line below
#nullable disable
using Bit.Core.Models.BitStripe;
using Stripe;
using Stripe.Tax;
namespace Bit.Core.Services;
public interface IStripeAdapter
{
Task<Customer> CustomerCreateAsync(CustomerCreateOptions customerCreateOptions);
Task CustomerDeleteDiscountAsync(string customerId, CustomerDeleteDiscountOptions options = null);
Task<Customer> CustomerGetAsync(string id, CustomerGetOptions options = null);
Task<Customer> CustomerUpdateAsync(string id, CustomerUpdateOptions options = null);
Task<Customer> CustomerDeleteAsync(string id);
Task<List<PaymentMethod>> CustomerListPaymentMethods(string id, CustomerPaymentMethodListOptions options = null);
Task<CustomerBalanceTransaction> CustomerBalanceTransactionCreate(string customerId,
CustomerBalanceTransactionCreateOptions options);
Task<Subscription> SubscriptionCreateAsync(SubscriptionCreateOptions subscriptionCreateOptions);
Task<Subscription> SubscriptionGetAsync(string id, SubscriptionGetOptions options = null);
Task<Subscription> SubscriptionUpdateAsync(string id, SubscriptionUpdateOptions options = null);
Task<Subscription> SubscriptionCancelAsync(string Id, SubscriptionCancelOptions options = null);
Task<Invoice> InvoiceGetAsync(string id, InvoiceGetOptions options);
Task<List<Invoice>> InvoiceListAsync(StripeInvoiceListOptions options);
Task<Invoice> InvoiceCreatePreviewAsync(InvoiceCreatePreviewOptions options);
Task<List<Invoice>> InvoiceSearchAsync(InvoiceSearchOptions options);
Task<Invoice> InvoiceUpdateAsync(string id, InvoiceUpdateOptions options);
Task<Invoice> InvoiceFinalizeInvoiceAsync(string id, InvoiceFinalizeOptions options);
Task<Invoice> InvoiceSendInvoiceAsync(string id, InvoiceSendOptions options);
Task<Invoice> InvoicePayAsync(string id, InvoicePayOptions options = null);
Task<Invoice> InvoiceDeleteAsync(string id, InvoiceDeleteOptions options = null);
Task<Invoice> InvoiceVoidInvoiceAsync(string id, InvoiceVoidOptions options = null);
IEnumerable<PaymentMethod> PaymentMethodListAutoPaging(PaymentMethodListOptions options);
IAsyncEnumerable<PaymentMethod> PaymentMethodListAutoPagingAsync(PaymentMethodListOptions options);
Task<PaymentMethod> PaymentMethodAttachAsync(string id, PaymentMethodAttachOptions options = null);
Task<PaymentMethod> PaymentMethodDetachAsync(string id, PaymentMethodDetachOptions options = null);
Task<TaxId> TaxIdCreateAsync(string id, TaxIdCreateOptions options);
Task<TaxId> TaxIdDeleteAsync(string customerId, string taxIdId, TaxIdDeleteOptions options = null);
Task<StripeList<Registration>> TaxRegistrationsListAsync(RegistrationListOptions options = null);
Task<StripeList<Charge>> ChargeListAsync(ChargeListOptions options);
Task<Refund> RefundCreateAsync(RefundCreateOptions options);
Task<Card> CardDeleteAsync(string customerId, string cardId, CardDeleteOptions options = null);
Task<BankAccount> BankAccountCreateAsync(string customerId, BankAccountCreateOptions options = null);
Task<BankAccount> BankAccountDeleteAsync(string customerId, string bankAccount, BankAccountDeleteOptions options = null);
Task<StripeList<Price>> PriceListAsync(PriceListOptions options = null);
Task<SetupIntent> SetupIntentCreate(SetupIntentCreateOptions options);
Task<List<SetupIntent>> SetupIntentList(SetupIntentListOptions options);
Task SetupIntentCancel(string id, SetupIntentCancelOptions options = null);
Task<SetupIntent> SetupIntentGet(string id, SetupIntentGetOptions options = null);
Task SetupIntentVerifyMicroDeposit(string id, SetupIntentVerifyMicrodepositsOptions options);
Task<List<Stripe.TestHelpers.TestClock>> TestClockListAsync();
Task<Price> PriceGetAsync(string id, PriceGetOptions options = null);
}

View File

@@ -1,6 +0,0 @@
namespace Bit.Core.Services;
public interface IStripeSyncService
{
Task UpdateCustomerEmailAddress(string gatewayCustomerId, string emailAddress);
}

View File

@@ -1,284 +0,0 @@
// FIXME: Update this file to be null safe and then delete the line below
#nullable disable
using Bit.Core.Models.BitStripe;
using Stripe;
using Stripe.Tax;
namespace Bit.Core.Services;
public class StripeAdapter : IStripeAdapter
{
private readonly CustomerService _customerService;
private readonly SubscriptionService _subscriptionService;
private readonly InvoiceService _invoiceService;
private readonly PaymentMethodService _paymentMethodService;
private readonly TaxIdService _taxIdService;
private readonly ChargeService _chargeService;
private readonly RefundService _refundService;
private readonly CardService _cardService;
private readonly BankAccountService _bankAccountService;
private readonly PlanService _planService;
private readonly PriceService _priceService;
private readonly SetupIntentService _setupIntentService;
private readonly Stripe.TestHelpers.TestClockService _testClockService;
private readonly CustomerBalanceTransactionService _customerBalanceTransactionService;
private readonly Stripe.Tax.RegistrationService _taxRegistrationService;
private readonly CalculationService _calculationService;
public StripeAdapter()
{
_customerService = new CustomerService();
_subscriptionService = new SubscriptionService();
_invoiceService = new InvoiceService();
_paymentMethodService = new PaymentMethodService();
_taxIdService = new TaxIdService();
_chargeService = new ChargeService();
_refundService = new RefundService();
_cardService = new CardService();
_bankAccountService = new BankAccountService();
_priceService = new PriceService();
_planService = new PlanService();
_setupIntentService = new SetupIntentService();
_testClockService = new Stripe.TestHelpers.TestClockService();
_customerBalanceTransactionService = new CustomerBalanceTransactionService();
_taxRegistrationService = new Stripe.Tax.RegistrationService();
_calculationService = new CalculationService();
}
public Task<Customer> CustomerCreateAsync(CustomerCreateOptions options)
{
return _customerService.CreateAsync(options);
}
public Task CustomerDeleteDiscountAsync(string customerId, CustomerDeleteDiscountOptions options = null) =>
_customerService.DeleteDiscountAsync(customerId, options);
public Task<Customer> CustomerGetAsync(string id, CustomerGetOptions options = null)
{
return _customerService.GetAsync(id, options);
}
public Task<Customer> CustomerUpdateAsync(string id, CustomerUpdateOptions options = null)
{
return _customerService.UpdateAsync(id, options);
}
public Task<Customer> CustomerDeleteAsync(string id)
{
return _customerService.DeleteAsync(id);
}
public async Task<List<PaymentMethod>> CustomerListPaymentMethods(string id,
CustomerPaymentMethodListOptions options = null)
{
var paymentMethods = await _customerService.ListPaymentMethodsAsync(id, options);
return paymentMethods.Data;
}
public async Task<CustomerBalanceTransaction> CustomerBalanceTransactionCreate(string customerId,
CustomerBalanceTransactionCreateOptions options)
=> await _customerBalanceTransactionService.CreateAsync(customerId, options);
public Task<Subscription> SubscriptionCreateAsync(SubscriptionCreateOptions options)
{
return _subscriptionService.CreateAsync(options);
}
public Task<Subscription> SubscriptionGetAsync(string id, SubscriptionGetOptions options = null)
{
return _subscriptionService.GetAsync(id, options);
}
public async Task<Subscription> ProviderSubscriptionGetAsync(
string id,
Guid providerId,
SubscriptionGetOptions options = null)
{
var subscription = await _subscriptionService.GetAsync(id, options);
if (subscription.Metadata.TryGetValue("providerId", out var value) && value == providerId.ToString())
{
return subscription;
}
throw new InvalidOperationException("Subscription does not belong to the provider.");
}
public Task<Subscription> SubscriptionUpdateAsync(string id,
SubscriptionUpdateOptions options = null)
{
return _subscriptionService.UpdateAsync(id, options);
}
public Task<Subscription> SubscriptionCancelAsync(string Id, SubscriptionCancelOptions options = null)
{
return _subscriptionService.CancelAsync(Id, options);
}
public Task<Invoice> InvoiceGetAsync(string id, InvoiceGetOptions options)
{
return _invoiceService.GetAsync(id, options);
}
public async Task<List<Invoice>> InvoiceListAsync(StripeInvoiceListOptions options)
{
if (!options.SelectAll)
{
return (await _invoiceService.ListAsync(options.ToInvoiceListOptions())).Data;
}
options.Limit = 100;
var invoices = new List<Invoice>();
await foreach (var invoice in _invoiceService.ListAutoPagingAsync(options.ToInvoiceListOptions()))
{
invoices.Add(invoice);
}
return invoices;
}
public Task<Invoice> InvoiceCreatePreviewAsync(InvoiceCreatePreviewOptions options)
{
return _invoiceService.CreatePreviewAsync(options);
}
public async Task<List<Invoice>> InvoiceSearchAsync(InvoiceSearchOptions options)
=> (await _invoiceService.SearchAsync(options)).Data;
public Task<Invoice> InvoiceUpdateAsync(string id, InvoiceUpdateOptions options)
{
return _invoiceService.UpdateAsync(id, options);
}
public Task<Invoice> InvoiceFinalizeInvoiceAsync(string id, InvoiceFinalizeOptions options)
{
return _invoiceService.FinalizeInvoiceAsync(id, options);
}
public Task<Invoice> InvoiceSendInvoiceAsync(string id, InvoiceSendOptions options)
{
return _invoiceService.SendInvoiceAsync(id, options);
}
public Task<Invoice> InvoicePayAsync(string id, InvoicePayOptions options = null)
{
return _invoiceService.PayAsync(id, options);
}
public Task<Invoice> InvoiceDeleteAsync(string id, InvoiceDeleteOptions options = null)
{
return _invoiceService.DeleteAsync(id, options);
}
public Task<Invoice> InvoiceVoidInvoiceAsync(string id, InvoiceVoidOptions options = null)
{
return _invoiceService.VoidInvoiceAsync(id, options);
}
public IEnumerable<PaymentMethod> PaymentMethodListAutoPaging(PaymentMethodListOptions options)
{
return _paymentMethodService.ListAutoPaging(options);
}
public IAsyncEnumerable<PaymentMethod> PaymentMethodListAutoPagingAsync(PaymentMethodListOptions options)
=> _paymentMethodService.ListAutoPagingAsync(options);
public Task<PaymentMethod> PaymentMethodAttachAsync(string id, PaymentMethodAttachOptions options = null)
{
return _paymentMethodService.AttachAsync(id, options);
}
public Task<PaymentMethod> PaymentMethodDetachAsync(string id, PaymentMethodDetachOptions options = null)
{
return _paymentMethodService.DetachAsync(id, options);
}
public Task<Plan> PlanGetAsync(string id, PlanGetOptions options = null)
{
return _planService.GetAsync(id, options);
}
public Task<TaxId> TaxIdCreateAsync(string id, TaxIdCreateOptions options)
{
return _taxIdService.CreateAsync(id, options);
}
public Task<TaxId> TaxIdDeleteAsync(string customerId, string taxIdId,
TaxIdDeleteOptions options = null)
{
return _taxIdService.DeleteAsync(customerId, taxIdId);
}
public Task<StripeList<Registration>> TaxRegistrationsListAsync(RegistrationListOptions options = null)
{
return _taxRegistrationService.ListAsync(options);
}
public Task<StripeList<Charge>> ChargeListAsync(ChargeListOptions options)
{
return _chargeService.ListAsync(options);
}
public Task<Refund> RefundCreateAsync(RefundCreateOptions options)
{
return _refundService.CreateAsync(options);
}
public Task<Card> CardDeleteAsync(string customerId, string cardId, CardDeleteOptions options = null)
{
return _cardService.DeleteAsync(customerId, cardId, options);
}
public Task<BankAccount> BankAccountCreateAsync(string customerId, BankAccountCreateOptions options = null)
{
return _bankAccountService.CreateAsync(customerId, options);
}
public Task<BankAccount> BankAccountDeleteAsync(string customerId, string bankAccount, BankAccountDeleteOptions options = null)
{
return _bankAccountService.DeleteAsync(customerId, bankAccount, options);
}
public async Task<StripeList<Price>> PriceListAsync(PriceListOptions options = null)
{
return await _priceService.ListAsync(options);
}
public Task<SetupIntent> SetupIntentCreate(SetupIntentCreateOptions options)
=> _setupIntentService.CreateAsync(options);
public async Task<List<SetupIntent>> SetupIntentList(SetupIntentListOptions options)
{
var setupIntents = await _setupIntentService.ListAsync(options);
return setupIntents.Data;
}
public Task SetupIntentCancel(string id, SetupIntentCancelOptions options = null)
=> _setupIntentService.CancelAsync(id, options);
public Task<SetupIntent> SetupIntentGet(string id, SetupIntentGetOptions options = null)
=> _setupIntentService.GetAsync(id, options);
public Task SetupIntentVerifyMicroDeposit(string id, SetupIntentVerifyMicrodepositsOptions options)
=> _setupIntentService.VerifyMicrodepositsAsync(id, options);
public async Task<List<Stripe.TestHelpers.TestClock>> TestClockListAsync()
{
var items = new List<Stripe.TestHelpers.TestClock>();
var options = new Stripe.TestHelpers.TestClockListOptions()
{
Limit = 100
};
await foreach (var i in _testClockService.ListAutoPagingAsync(options))
{
items.Add(i);
}
return items;
}
public Task<Price> PriceGetAsync(string id, PriceGetOptions options = null)
=> _priceService.GetAsync(id, options);
}

View File

@@ -57,7 +57,7 @@ public class UserService : UserManager<User>, IUserService
private readonly ILicensingService _licenseService;
private readonly IEventService _eventService;
private readonly IApplicationCacheService _applicationCacheService;
private readonly IPaymentService _paymentService;
private readonly IStripePaymentService _paymentService;
private readonly IPolicyRepository _policyRepository;
private readonly IPolicyService _policyService;
private readonly IFido2 _fido2;
@@ -93,7 +93,7 @@ public class UserService : UserManager<User>, IUserService
ILicensingService licenseService,
IEventService eventService,
IApplicationCacheService applicationCacheService,
IPaymentService paymentService,
IStripePaymentService paymentService,
IPolicyRepository policyRepository,
IPolicyService policyService,
IFido2 fido2,
@@ -534,7 +534,7 @@ public class UserService : UserManager<User>, IUserService
try
{
await _stripeSyncService.UpdateCustomerEmailAddress(user.GatewayCustomerId,
await _stripeSyncService.UpdateCustomerEmailAddressAsync(user.GatewayCustomerId,
user.BillingEmailAddress());
}
catch (Exception ex)
@@ -867,7 +867,7 @@ public class UserService : UserManager<User>, IUserService
}
string paymentIntentClientSecret = null;
IPaymentService paymentService = null;
IStripePaymentService paymentService = null;
if (_globalSettings.SelfHosted)
{
if (license == null || !_licenseService.VerifyLicense(license))

View File

@@ -1,12 +1,12 @@
using Bit.Core.Entities;
using Bit.Core.Billing.Services;
using Bit.Core.Entities;
using Bit.Core.Exceptions;
using Bit.Core.Services;
namespace Bit.Core.Utilities;
public static class BillingHelpers
{
internal static async Task<string> AdjustStorageAsync(IPaymentService paymentService, IStorableSubscriber storableSubscriber,
internal static async Task<string> AdjustStorageAsync(IStripePaymentService paymentService, IStorableSubscriber storableSubscriber,
short storageAdjustmentGb, string storagePlanId, short baseStorageGb)
{
if (storableSubscriber == null)

View File

@@ -238,7 +238,7 @@ public static class ServiceCollectionExtensions
PrivateKey = globalSettings.Braintree.PrivateKey
};
});
services.AddScoped<IPaymentService, StripePaymentService>();
services.AddScoped<IStripePaymentService, StripePaymentService>();
services.AddScoped<IPaymentHistoryService, PaymentHistoryService>();
services.AddScoped<ITwoFactorEmailService, TwoFactorEmailService>();
// Legacy mailer service

View File

@@ -28,7 +28,7 @@ public class AccountsControllerTests : IDisposable
private readonly IUserService _userService;
private readonly IFeatureService _featureService;
private readonly IPaymentService _paymentService;
private readonly IStripePaymentService _paymentService;
private readonly ITwoFactorIsEnabledQuery _twoFactorIsEnabledQuery;
private readonly IUserAccountKeysQuery _userAccountKeysQuery;
private readonly ILicensingService _licensingService;
@@ -39,7 +39,7 @@ public class AccountsControllerTests : IDisposable
{
_userService = Substitute.For<IUserService>();
_featureService = Substitute.For<IFeatureService>();
_paymentService = Substitute.For<IPaymentService>();
_paymentService = Substitute.For<IStripePaymentService>();
_twoFactorIsEnabledQuery = Substitute.For<ITwoFactorIsEnabledQuery>();
_userAccountKeysQuery = Substitute.For<IUserAccountKeysQuery>();
_licensingService = Substitute.For<ILicensingService>();

View File

@@ -3,9 +3,9 @@ using Bit.Core.AdminConsole.Entities;
using Bit.Core.Billing.Models;
using Bit.Core.Billing.Organizations.Models;
using Bit.Core.Billing.Organizations.Services;
using Bit.Core.Billing.Services;
using Bit.Core.Context;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
using Microsoft.AspNetCore.Http.HttpResults;
@@ -103,7 +103,7 @@ public class OrganizationBillingControllerTests
// Manually create a BillingHistoryInfo object to avoid requiring AutoFixture to create HttpResponseHeaders
var billingInfo = new BillingHistoryInfo();
sutProvider.GetDependency<IPaymentService>().GetBillingHistoryAsync(organization).Returns(billingInfo);
sutProvider.GetDependency<IStripePaymentService>().GetBillingHistoryAsync(organization).Returns(billingInfo);
// Act
var result = await sutProvider.Sut.GetHistoryAsync(organizationId);

View File

@@ -37,7 +37,7 @@ public class OrganizationsControllerTests : IDisposable
private readonly IOrganizationRepository _organizationRepository;
private readonly IOrganizationService _organizationService;
private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly IPaymentService _paymentService;
private readonly IStripePaymentService _paymentService;
private readonly ISsoConfigRepository _ssoConfigRepository;
private readonly IUserService _userService;
private readonly IGetCloudOrganizationLicenseQuery _getCloudOrganizationLicenseQuery;
@@ -59,7 +59,7 @@ public class OrganizationsControllerTests : IDisposable
_organizationRepository = Substitute.For<IOrganizationRepository>();
_organizationService = Substitute.For<IOrganizationService>();
_organizationUserRepository = Substitute.For<IOrganizationUserRepository>();
_paymentService = Substitute.For<IPaymentService>();
_paymentService = Substitute.For<IStripePaymentService>();
Substitute.For<IPolicyRepository>();
_ssoConfigRepository = Substitute.For<ISsoConfigRepository>();
Substitute.For<ISsoConfigService>();

View File

@@ -10,10 +10,10 @@ using Bit.Core.Billing.Pricing;
using Bit.Core.Billing.Providers.Entities;
using Bit.Core.Billing.Providers.Repositories;
using Bit.Core.Billing.Providers.Services;
using Bit.Core.Billing.Services;
using Bit.Core.Context;
using Bit.Core.Models.Api;
using Bit.Core.Models.BitStripe;
using Bit.Core.Services;
using Bit.Core.Test.Billing.Mocks;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
@@ -121,7 +121,7 @@ public class ProviderBillingControllerTests
}
};
sutProvider.GetDependency<IStripeAdapter>().InvoiceListAsync(Arg.Is<StripeInvoiceListOptions>(
sutProvider.GetDependency<IStripeAdapter>().ListInvoicesAsync(Arg.Is<StripeInvoiceListOptions>(
options =>
options.Customer == provider.GatewayCustomerId)).Returns(invoices);
@@ -301,7 +301,7 @@ public class ProviderBillingControllerTests
Status = "unpaid"
};
stripeAdapter.SubscriptionGetAsync(provider.GatewaySubscriptionId, Arg.Is<SubscriptionGetOptions>(
stripeAdapter.GetSubscriptionAsync(provider.GatewaySubscriptionId, Arg.Is<SubscriptionGetOptions>(
options =>
options.Expand.Contains("customer.tax_ids") &&
options.Expand.Contains("discounts") &&
@@ -318,7 +318,7 @@ public class ProviderBillingControllerTests
Attempted = true
};
stripeAdapter.InvoiceSearchAsync(Arg.Is<InvoiceSearchOptions>(
stripeAdapter.SearchInvoiceAsync(Arg.Is<InvoiceSearchOptions>(
options => options.Query == $"subscription:'{subscription.Id}' status:'open'"))
.Returns([overdueInvoice]);
@@ -351,7 +351,7 @@ public class ProviderBillingControllerTests
var plan = MockPlans.Get(providerPlan.PlanType);
sutProvider.GetDependency<IPricingClient>().GetPlanOrThrow(providerPlan.PlanType).Returns(plan);
var priceId = ProviderPriceAdapter.GetPriceId(provider, subscription, providerPlan.PlanType);
sutProvider.GetDependency<IStripeAdapter>().PriceGetAsync(priceId)
sutProvider.GetDependency<IStripeAdapter>().GetPriceAsync(priceId)
.Returns(new Price
{
UnitAmountDecimal = plan.PasswordManager.ProviderPortalSeatPrice * 100
@@ -459,13 +459,13 @@ public class ProviderBillingControllerTests
Status = "active"
};
stripeAdapter.SubscriptionGetAsync(provider.GatewaySubscriptionId, Arg.Is<SubscriptionGetOptions>(
stripeAdapter.GetSubscriptionAsync(provider.GatewaySubscriptionId, Arg.Is<SubscriptionGetOptions>(
options =>
options.Expand.Contains("customer.tax_ids") &&
options.Expand.Contains("discounts") &&
options.Expand.Contains("test_clock"))).Returns(subscription);
stripeAdapter.InvoiceSearchAsync(Arg.Is<InvoiceSearchOptions>(
stripeAdapter.SearchInvoiceAsync(Arg.Is<InvoiceSearchOptions>(
options => options.Query == $"subscription:'{subscription.Id}' status:'open'"))
.Returns([]);
@@ -498,7 +498,7 @@ public class ProviderBillingControllerTests
var plan = MockPlans.Get(providerPlan.PlanType);
sutProvider.GetDependency<IPricingClient>().GetPlanOrThrow(providerPlan.PlanType).Returns(plan);
var priceId = ProviderPriceAdapter.GetPriceId(provider, subscription, providerPlan.PlanType);
sutProvider.GetDependency<IStripeAdapter>().PriceGetAsync(priceId)
sutProvider.GetDependency<IStripeAdapter>().GetPriceAsync(priceId)
.Returns(new Price
{
UnitAmountDecimal = plan.PasswordManager.ProviderPortalSeatPrice * 100

View File

@@ -31,7 +31,7 @@ public class BitPayControllerTests
private readonly IUserRepository _userRepository = Substitute.For<IUserRepository>();
private readonly IProviderRepository _providerRepository = Substitute.For<IProviderRepository>();
private readonly IMailService _mailService = Substitute.For<IMailService>();
private readonly IPaymentService _paymentService = Substitute.For<IPaymentService>();
private readonly IStripePaymentService _paymentService = Substitute.For<IStripePaymentService>();
private readonly IPremiumUserBillingService _premiumUserBillingService =
Substitute.For<IPremiumUserBillingService>();

View File

@@ -28,7 +28,7 @@ public class PayPalControllerTests(ITestOutputHelper testOutputHelper)
private readonly IOptions<BillingSettings> _billingSettings = Substitute.For<IOptions<BillingSettings>>();
private readonly IMailService _mailService = Substitute.For<IMailService>();
private readonly IOrganizationRepository _organizationRepository = Substitute.For<IOrganizationRepository>();
private readonly IPaymentService _paymentService = Substitute.For<IPaymentService>();
private readonly IStripePaymentService _paymentService = Substitute.For<IStripePaymentService>();
private readonly ITransactionRepository _transactionRepository = Substitute.For<ITransactionRepository>();
private readonly IUserRepository _userRepository = Substitute.For<IUserRepository>();
private readonly IProviderRepository _providerRepository = Substitute.For<IProviderRepository>();

View File

@@ -4,8 +4,8 @@ using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Entities.Provider;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Billing.Caches;
using Bit.Core.Billing.Services;
using Bit.Core.Repositories;
using Bit.Core.Services;
using NSubstitute;
using Stripe;
using Xunit;
@@ -61,7 +61,7 @@ public class SetupIntentSucceededHandlerTests
// Assert
await _setupIntentCache.DidNotReceiveWithAnyArgs().GetSubscriberIdForSetupIntent(Arg.Any<string>());
await _stripeAdapter.DidNotReceiveWithAnyArgs().PaymentMethodAttachAsync(
await _stripeAdapter.DidNotReceiveWithAnyArgs().AttachPaymentMethodAsync(
Arg.Any<string>(), Arg.Any<PaymentMethodAttachOptions>());
await _pushNotificationAdapter.DidNotReceiveWithAnyArgs().NotifyBankAccountVerifiedAsync(Arg.Any<Organization>());
await _pushNotificationAdapter.DidNotReceiveWithAnyArgs().NotifyBankAccountVerifiedAsync(Arg.Any<Provider>());
@@ -86,7 +86,7 @@ public class SetupIntentSucceededHandlerTests
await _handler.HandleAsync(_mockEvent);
// Assert
await _stripeAdapter.DidNotReceiveWithAnyArgs().PaymentMethodAttachAsync(
await _stripeAdapter.DidNotReceiveWithAnyArgs().AttachPaymentMethodAsync(
Arg.Any<string>(), Arg.Any<PaymentMethodAttachOptions>());
await _pushNotificationAdapter.DidNotReceiveWithAnyArgs().NotifyBankAccountVerifiedAsync(Arg.Any<Organization>());
await _pushNotificationAdapter.DidNotReceiveWithAnyArgs().NotifyBankAccountVerifiedAsync(Arg.Any<Provider>());
@@ -116,7 +116,7 @@ public class SetupIntentSucceededHandlerTests
await _handler.HandleAsync(_mockEvent);
// Assert
await _stripeAdapter.Received(1).PaymentMethodAttachAsync(
await _stripeAdapter.Received(1).AttachPaymentMethodAsync(
"pm_test",
Arg.Is<PaymentMethodAttachOptions>(o => o.Customer == organization.GatewayCustomerId));
@@ -151,7 +151,7 @@ public class SetupIntentSucceededHandlerTests
await _handler.HandleAsync(_mockEvent);
// Assert
await _stripeAdapter.Received(1).PaymentMethodAttachAsync(
await _stripeAdapter.Received(1).AttachPaymentMethodAsync(
"pm_test",
Arg.Is<PaymentMethodAttachOptions>(o => o.Customer == provider.GatewayCustomerId));
@@ -183,7 +183,7 @@ public class SetupIntentSucceededHandlerTests
await _handler.HandleAsync(_mockEvent);
// Assert
await _stripeAdapter.DidNotReceiveWithAnyArgs().PaymentMethodAttachAsync(
await _stripeAdapter.DidNotReceiveWithAnyArgs().AttachPaymentMethodAsync(
Arg.Any<string>(), Arg.Any<PaymentMethodAttachOptions>());
await _pushNotificationAdapter.DidNotReceiveWithAnyArgs().NotifyBankAccountVerifiedAsync(Arg.Any<Organization>());
await _pushNotificationAdapter.DidNotReceiveWithAnyArgs().NotifyBankAccountVerifiedAsync(Arg.Any<Provider>());
@@ -216,7 +216,7 @@ public class SetupIntentSucceededHandlerTests
await _handler.HandleAsync(_mockEvent);
// Assert
await _stripeAdapter.DidNotReceiveWithAnyArgs().PaymentMethodAttachAsync(
await _stripeAdapter.DidNotReceiveWithAnyArgs().AttachPaymentMethodAsync(
Arg.Any<string>(), Arg.Any<PaymentMethodAttachOptions>());
await _pushNotificationAdapter.DidNotReceiveWithAnyArgs().NotifyBankAccountVerifiedAsync(Arg.Any<Organization>());
await _pushNotificationAdapter.DidNotReceiveWithAnyArgs().NotifyBankAccountVerifiedAsync(Arg.Any<Provider>());

View File

@@ -1,6 +1,7 @@
using Bit.Core.AdminConsole.Models.Business;
using Bit.Core.AdminConsole.OrganizationFeatures.Import;
using Bit.Core.Auth.Models.Business.Tokenables;
using Bit.Core.Billing.Services;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
@@ -57,7 +58,7 @@ public class ImportOrganizationUsersAndGroupsCommandTests
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
SetupOrgUserRepositoryCreateManyAsyncMock(organizationUserRepository);
sutProvider.GetDependency<IPaymentService>().HasSecretsManagerStandalone(org).Returns(true);
sutProvider.GetDependency<IStripePaymentService>().HasSecretsManagerStandalone(org).Returns(true);
sutProvider.GetDependency<IOrganizationUserRepository>().GetManyDetailsByOrganizationAsync(org.Id).Returns(existingUsers);
sutProvider.GetDependency<IOrganizationRepository>().GetOccupiedSeatCountByOrganizationIdAsync(org.Id).Returns(
new OrganizationSeatCounts

View File

@@ -3,11 +3,11 @@ using Bit.Core.AdminConsole.Models.Business;
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models;
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation;
using Bit.Core.AdminConsole.Utilities.Validation;
using Bit.Core.Billing.Services;
using Bit.Core.Exceptions;
using Bit.Core.Models.Business;
using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Test.Billing.Mocks.Plans;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
@@ -50,7 +50,7 @@ public class InviteOrganizationUsersValidatorTests
OccupiedSmSeats = 9
};
sutProvider.GetDependency<IPaymentService>()
sutProvider.GetDependency<IStripePaymentService>()
.HasSecretsManagerStandalone(request.InviteOrganization)
.Returns(true);
@@ -96,7 +96,7 @@ public class InviteOrganizationUsersValidatorTests
OccupiedSmSeats = 9
};
sutProvider.GetDependency<IPaymentService>()
sutProvider.GetDependency<IStripePaymentService>()
.HasSecretsManagerStandalone(request.InviteOrganization)
.Returns(true);
@@ -140,7 +140,7 @@ public class InviteOrganizationUsersValidatorTests
OccupiedSmSeats = 4
};
sutProvider.GetDependency<IPaymentService>()
sutProvider.GetDependency<IStripePaymentService>()
.HasSecretsManagerStandalone(request.InviteOrganization)
.Returns(true);

View File

@@ -2,6 +2,7 @@
using Bit.Core.AdminConsole.OrganizationFeatures.Organizations;
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers;
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models;
using Bit.Core.Billing.Services;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Repositories;
@@ -172,7 +173,7 @@ public class ResellerClientOrganizationSignUpCommandTests
private static async Task AssertCleanupIsPerformed(SutProvider<ResellerClientOrganizationSignUpCommand> sutProvider)
{
await sutProvider.GetDependency<IPaymentService>()
await sutProvider.GetDependency<IStripePaymentService>()
.Received(1)
.CancelAndRecoverChargesAsync(Arg.Any<Organization>());
await sutProvider.GetDependency<IOrganizationRepository>()

View File

@@ -2,9 +2,9 @@
using Bit.Core.AdminConsole.Models.Data.Organizations;
using Bit.Core.AdminConsole.OrganizationFeatures.Organizations;
using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Services;
using Bit.Core.Models.StaticStore;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Test.Billing.Mocks.Plans;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
@@ -28,7 +28,7 @@ public class UpdateOrganizationSubscriptionCommandTests
// Act
await sutProvider.Sut.UpdateOrganizationSubscriptionAsync(subscriptionsToUpdate);
await sutProvider.GetDependency<IPaymentService>()
await sutProvider.GetDependency<IStripePaymentService>()
.DidNotReceive()
.AdjustSeatsAsync(Arg.Any<Organization>(), Arg.Any<Plan>(), Arg.Any<int>());
@@ -53,7 +53,7 @@ public class UpdateOrganizationSubscriptionCommandTests
// Act
await sutProvider.Sut.UpdateOrganizationSubscriptionAsync(subscriptionsToUpdate);
await sutProvider.GetDependency<IPaymentService>()
await sutProvider.GetDependency<IStripePaymentService>()
.Received(1)
.AdjustSeatsAsync(
Arg.Is<Organization>(x => x.Id == organization.Id),
@@ -81,7 +81,7 @@ public class UpdateOrganizationSubscriptionCommandTests
OrganizationSubscriptionUpdate[] subscriptionsToUpdate =
[new() { Organization = organization, Plan = new Enterprise2023Plan(true) }];
sutProvider.GetDependency<IPaymentService>()
sutProvider.GetDependency<IStripePaymentService>()
.AdjustSeatsAsync(
Arg.Is<Organization>(x => x.Id == organization.Id),
Arg.Is<Plan>(x => x.Type == organization.PlanType),
@@ -115,7 +115,7 @@ public class UpdateOrganizationSubscriptionCommandTests
new() { Organization = failedOrganization, Plan = new Enterprise2023Plan(true) }
];
sutProvider.GetDependency<IPaymentService>()
sutProvider.GetDependency<IStripePaymentService>()
.AdjustSeatsAsync(
Arg.Is<Organization>(x => x.Id == failedOrganization.Id),
Arg.Is<Plan>(x => x.Type == failedOrganization.PlanType),
@@ -124,7 +124,7 @@ public class UpdateOrganizationSubscriptionCommandTests
// Act
await sutProvider.Sut.UpdateOrganizationSubscriptionAsync(subscriptionsToUpdate);
await sutProvider.GetDependency<IPaymentService>()
await sutProvider.GetDependency<IStripePaymentService>()
.Received(1)
.AdjustSeatsAsync(
Arg.Is<Organization>(x => x.Id == successfulOrganization.Id),

View File

@@ -9,6 +9,7 @@ using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Auth.Models.Business.Tokenables;
using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Pricing;
using Bit.Core.Billing.Services;
using Bit.Core.Context;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
@@ -1142,7 +1143,7 @@ public class OrganizationServiceTests
.GetByIdentifierAsync(Arg.Is<string>(id => id == organization.Identifier));
await stripeAdapter
.Received(1)
.CustomerUpdateAsync(
.UpdateCustomerAsync(
Arg.Is<string>(id => id == organization.GatewayCustomerId),
Arg.Is<CustomerUpdateOptions>(options => options.Email == requestOptionsReturned.Email
&& options.Description == requestOptionsReturned.Description
@@ -1182,7 +1183,7 @@ public class OrganizationServiceTests
.GetByIdentifierAsync(Arg.Is<string>(id => id == organization.Identifier));
await stripeAdapter
.DidNotReceiveWithAnyArgs()
.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>());
.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>());
await organizationRepository
.Received(1)
.ReplaceAsync(Arg.Is<Organization>(org => org == organization));

View File

@@ -4,7 +4,7 @@ using Bit.Core.Billing.Organizations.Commands;
using Bit.Core.Billing.Organizations.Models;
using Bit.Core.Billing.Payment.Models;
using Bit.Core.Billing.Pricing;
using Bit.Core.Services;
using Bit.Core.Billing.Services;
using Bit.Core.Test.Billing.Mocks.Plans;
using Microsoft.Extensions.Logging;
using NSubstitute;
@@ -58,7 +58,7 @@ public class PreviewOrganizationTaxCommandTests
Total = 5500
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(purchase, billingAddress);
@@ -68,7 +68,7 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal(55.00m, total);
// Verify the correct Stripe API call for sponsored subscription
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "US" &&
@@ -116,7 +116,7 @@ public class PreviewOrganizationTaxCommandTests
Total = 8250
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(purchase, billingAddress);
@@ -126,7 +126,7 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal(82.50m, total);
// Verify the correct Stripe API call for standalone secrets manager
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "CA" &&
@@ -179,7 +179,7 @@ public class PreviewOrganizationTaxCommandTests
Total = 12200
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(purchase, billingAddress);
@@ -189,7 +189,7 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal(122.00m, total);
// Verify the correct Stripe API call for comprehensive purchase with storage and service accounts
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "GB" &&
@@ -240,7 +240,7 @@ public class PreviewOrganizationTaxCommandTests
Total = 3300
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(purchase, billingAddress);
@@ -250,7 +250,7 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal(33.00m, total);
// Verify the correct Stripe API call for Families tier (non-seat-based plan)
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "US" &&
@@ -292,7 +292,7 @@ public class PreviewOrganizationTaxCommandTests
Total = 2700
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(purchase, billingAddress);
@@ -302,7 +302,7 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal(27.00m, total);
// Verify the correct Stripe API call for business use in non-US country (tax exempt reverse)
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "DE" &&
@@ -345,7 +345,7 @@ public class PreviewOrganizationTaxCommandTests
Total = 12100
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(purchase, billingAddress);
@@ -355,7 +355,7 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal(121.00m, total);
// Verify the correct Stripe API call for Spanish NIF that adds both Spanish NIF and EU VAT tax IDs
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "ES" &&
@@ -405,7 +405,7 @@ public class PreviewOrganizationTaxCommandTests
Total = 1320
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(organization, planChange, billingAddress);
@@ -415,7 +415,7 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal(13.20m, total);
// Verify the correct Stripe API call for free organization upgrade to Teams
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "US" &&
@@ -458,7 +458,7 @@ public class PreviewOrganizationTaxCommandTests
Total = 4400
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(organization, planChange, billingAddress);
@@ -468,7 +468,7 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal(44.00m, total);
// Verify the correct Stripe API call for free organization upgrade to Families (no SM for Families)
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "CA" &&
@@ -522,7 +522,7 @@ public class PreviewOrganizationTaxCommandTests
Customer = new Customer { Discount = null }
};
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
var invoice = new Invoice
{
@@ -534,7 +534,7 @@ public class PreviewOrganizationTaxCommandTests
Total = 9900
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(organization, planChange, billingAddress);
@@ -543,7 +543,7 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal(9.00m, tax);
Assert.Equal(99.00m, total);
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "US" &&
@@ -597,7 +597,7 @@ public class PreviewOrganizationTaxCommandTests
Customer = new Customer { Discount = null }
};
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
var invoice = new Invoice
{
@@ -609,7 +609,7 @@ public class PreviewOrganizationTaxCommandTests
Total = 13200
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(organization, planChange, billingAddress);
@@ -618,7 +618,7 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal(12.00m, tax);
Assert.Equal(132.00m, total);
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "US" &&
@@ -661,7 +661,7 @@ public class PreviewOrganizationTaxCommandTests
Total = 8800
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(organization, planChange, billingAddress);
@@ -671,7 +671,7 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal(88.00m, total);
// Verify the correct Stripe API call for free organization with SM to Enterprise
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "GB" &&
@@ -730,7 +730,7 @@ public class PreviewOrganizationTaxCommandTests
Customer = new Customer { Discount = null }
};
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
var invoice = new Invoice
{
@@ -738,7 +738,7 @@ public class PreviewOrganizationTaxCommandTests
Total = 16500
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(organization, planChange, billingAddress);
@@ -748,7 +748,7 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal(165.00m, total);
// Verify the correct Stripe API call for existing subscription upgrade
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "DE" &&
@@ -814,7 +814,7 @@ public class PreviewOrganizationTaxCommandTests
}
};
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
var invoice = new Invoice
{
@@ -822,7 +822,7 @@ public class PreviewOrganizationTaxCommandTests
Total = 6600
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(organization, planChange, billingAddress);
@@ -832,7 +832,7 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal(66.00m, total);
// Verify the correct Stripe API call preserves existing discount
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "US" &&
@@ -876,8 +876,8 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal("Organization does not have a subscription.", badRequest.Response);
// Verify no Stripe API calls were made
await _stripeAdapter.DidNotReceive().InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>());
await _stripeAdapter.DidNotReceive().SubscriptionGetAsync(Arg.Any<string>(), Arg.Any<SubscriptionGetOptions>());
await _stripeAdapter.DidNotReceive().CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>());
await _stripeAdapter.DidNotReceive().GetSubscriptionAsync(Arg.Any<string>(), Arg.Any<SubscriptionGetOptions>());
}
#endregion
@@ -919,7 +919,7 @@ public class PreviewOrganizationTaxCommandTests
Customer = customer
};
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
var invoice = new Invoice
{
@@ -927,7 +927,7 @@ public class PreviewOrganizationTaxCommandTests
Total = 6600
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(organization, update);
@@ -937,7 +937,7 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal(66.00m, total);
// Verify the correct Stripe API call for PM seats only
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "US" &&
@@ -984,7 +984,7 @@ public class PreviewOrganizationTaxCommandTests
Customer = customer
};
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
var invoice = new Invoice
{
@@ -992,7 +992,7 @@ public class PreviewOrganizationTaxCommandTests
Total = 13200
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(organization, update);
@@ -1002,7 +1002,7 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal(132.00m, total);
// Verify the correct Stripe API call for PM seats + storage
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "CA" &&
@@ -1051,7 +1051,7 @@ public class PreviewOrganizationTaxCommandTests
Customer = customer
};
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
var invoice = new Invoice
{
@@ -1059,7 +1059,7 @@ public class PreviewOrganizationTaxCommandTests
Total = 8800
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(organization, update);
@@ -1069,7 +1069,7 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal(88.00m, total);
// Verify the correct Stripe API call for SM seats only
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "DE" &&
@@ -1119,7 +1119,7 @@ public class PreviewOrganizationTaxCommandTests
Customer = customer
};
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
var invoice = new Invoice
{
@@ -1127,7 +1127,7 @@ public class PreviewOrganizationTaxCommandTests
Total = 16500
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(organization, update);
@@ -1137,7 +1137,7 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal(165.00m, total);
// Verify the correct Stripe API call for SM seats + service accounts with tax ID
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "GB" &&
@@ -1200,7 +1200,7 @@ public class PreviewOrganizationTaxCommandTests
Customer = customer
};
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
var invoice = new Invoice
{
@@ -1208,7 +1208,7 @@ public class PreviewOrganizationTaxCommandTests
Total = 27500
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(organization, update);
@@ -1218,7 +1218,7 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal(275.00m, total);
// Verify the correct Stripe API call for comprehensive update with discount and Spanish tax ID
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "ES" &&
@@ -1276,7 +1276,7 @@ public class PreviewOrganizationTaxCommandTests
Customer = customer
};
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
var invoice = new Invoice
{
@@ -1284,7 +1284,7 @@ public class PreviewOrganizationTaxCommandTests
Total = 5500
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(organization, update);
@@ -1294,7 +1294,7 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal(55.00m, total);
// Verify the correct Stripe API call for Families tier (personal usage, no business tax exemption)
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "AU" &&
@@ -1334,8 +1334,8 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal("Organization does not have a subscription.", badRequest.Response);
// Verify no Stripe API calls were made
await _stripeAdapter.DidNotReceive().InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>());
await _stripeAdapter.DidNotReceive().SubscriptionGetAsync(Arg.Any<string>(), Arg.Any<SubscriptionGetOptions>());
await _stripeAdapter.DidNotReceive().CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>());
await _stripeAdapter.DidNotReceive().GetSubscriptionAsync(Arg.Any<string>(), Arg.Any<SubscriptionGetOptions>());
}
[Fact]
@@ -1378,7 +1378,7 @@ public class PreviewOrganizationTaxCommandTests
Customer = customer
};
_stripeAdapter.SubscriptionGetAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
_stripeAdapter.GetSubscriptionAsync("sub_test123", Arg.Any<SubscriptionGetOptions>()).Returns(subscription);
var invoice = new Invoice
{
@@ -1386,7 +1386,7 @@ public class PreviewOrganizationTaxCommandTests
Total = 3300
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(organization, update);
@@ -1396,7 +1396,7 @@ public class PreviewOrganizationTaxCommandTests
Assert.Equal(33.00m, total);
// Verify only PM seats are included (storage=0 excluded, SM seats=0 so entire SM excluded)
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "US" &&

View File

@@ -8,7 +8,6 @@ using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.Business;
using Bit.Core.Platform.Installations;
using Bit.Core.Services;
using Bit.Core.Test.AutoFixture;
using Bit.Core.Test.Billing.AutoFixture;
using Bit.Test.Common.AutoFixture;
@@ -59,7 +58,7 @@ public class GetCloudOrganizationLicenseQueryTests
{
installation.Enabled = true;
sutProvider.GetDependency<IInstallationRepository>().GetByIdAsync(installationId).Returns(installation);
sutProvider.GetDependency<IPaymentService>().GetSubscriptionAsync(organization).Returns(subInfo);
sutProvider.GetDependency<IStripePaymentService>().GetSubscriptionAsync(organization).Returns(subInfo);
sutProvider.GetDependency<ILicensingService>().SignLicense(Arg.Any<ILicense>()).Returns(licenseSignature);
var result = await sutProvider.Sut.GetLicenseAsync(organization, installationId);
@@ -80,7 +79,7 @@ public class GetCloudOrganizationLicenseQueryTests
{
installation.Enabled = true;
sutProvider.GetDependency<IInstallationRepository>().GetByIdAsync(installationId).Returns(installation);
sutProvider.GetDependency<IPaymentService>().GetSubscriptionAsync(organization).Returns(subInfo);
sutProvider.GetDependency<IStripePaymentService>().GetSubscriptionAsync(organization).Returns(subInfo);
sutProvider.GetDependency<ILicensingService>().SignLicense(Arg.Any<ILicense>()).Returns(licenseSignature);
sutProvider.GetDependency<ILicensingService>()
.CreateOrganizationTokenAsync(organization, installationId, subInfo)
@@ -119,7 +118,7 @@ public class GetCloudOrganizationLicenseQueryTests
installation.Enabled = true;
sutProvider.GetDependency<IInstallationRepository>().GetByIdAsync(installationId).Returns(installation);
sutProvider.GetDependency<IProviderRepository>().GetByOrganizationIdAsync(organization.Id).Returns(provider);
sutProvider.GetDependency<IPaymentService>().GetSubscriptionAsync(provider).Returns(subInfo);
sutProvider.GetDependency<IStripePaymentService>().GetSubscriptionAsync(provider).Returns(subInfo);
sutProvider.GetDependency<ILicensingService>().SignLicense(Arg.Any<ILicense>()).Returns(licenseSignature);
var result = await sutProvider.Sut.GetLicenseAsync(organization, installationId);

View File

@@ -8,7 +8,6 @@ using Bit.Core.Billing.Organizations.Queries;
using Bit.Core.Billing.Payment.Queries;
using Bit.Core.Billing.Services;
using Bit.Core.Context;
using Bit.Core.Services;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
using NSubstitute;
@@ -382,7 +381,7 @@ public class GetOrganizationWarningsQueryTests
var dueDate = now.AddDays(-10);
sutProvider.GetDependency<IStripeAdapter>().InvoiceSearchAsync(Arg.Is<InvoiceSearchOptions>(options =>
sutProvider.GetDependency<IStripeAdapter>().SearchInvoiceAsync(Arg.Is<InvoiceSearchOptions>(options =>
options.Query == $"subscription:'{subscriptionId}' status:'open'")).Returns([
new Invoice { DueDate = dueDate, Created = dueDate.AddDays(-30) }
]);
@@ -542,7 +541,7 @@ public class GetOrganizationWarningsQueryTests
.Returns(true);
sutProvider.GetDependency<IStripeAdapter>()
.TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
.ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
.Returns(new StripeList<Registration>
{
Data = new List<Registration>
@@ -583,7 +582,7 @@ public class GetOrganizationWarningsQueryTests
.Returns(true);
sutProvider.GetDependency<IStripeAdapter>()
.TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
.ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
.Returns(new StripeList<Registration>
{
Data = new List<Registration>
@@ -635,7 +634,7 @@ public class GetOrganizationWarningsQueryTests
.Returns(true);
sutProvider.GetDependency<IStripeAdapter>()
.TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
.ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
.Returns(new StripeList<Registration>
{
Data = new List<Registration>
@@ -687,7 +686,7 @@ public class GetOrganizationWarningsQueryTests
.Returns(true);
sutProvider.GetDependency<IStripeAdapter>()
.TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
.ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
.Returns(new StripeList<Registration>
{
Data = new List<Registration>
@@ -739,7 +738,7 @@ public class GetOrganizationWarningsQueryTests
.Returns(true);
sutProvider.GetDependency<IStripeAdapter>()
.TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
.ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
.Returns(new StripeList<Registration>
{
Data = new List<Registration>
@@ -785,7 +784,7 @@ public class GetOrganizationWarningsQueryTests
.Returns(true);
sutProvider.GetDependency<IStripeAdapter>()
.TaxRegistrationsListAsync(Arg.Any<RegistrationListOptions>())
.ListTaxRegistrationsAsync(Arg.Any<RegistrationListOptions>())
.Returns(new StripeList<Registration>
{
Data = new List<Registration>

View File

@@ -4,7 +4,6 @@ using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Payment.Commands;
using Bit.Core.Billing.Payment.Models;
using Bit.Core.Billing.Services;
using Bit.Core.Services;
using Bit.Core.Test.Billing.Extensions;
using Microsoft.Extensions.Logging;
using NSubstitute;
@@ -73,7 +72,7 @@ public class UpdateBillingAddressCommandTests
}
};
_stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
_stripeAdapter.UpdateCustomerAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
options.Address.Matches(input) &&
options.HasExpansions("subscriptions")
)).Returns(customer);
@@ -84,7 +83,7 @@ public class UpdateBillingAddressCommandTests
var output = result.AsT0;
Assert.Equivalent(input, output);
await _stripeAdapter.Received(1).SubscriptionUpdateAsync(organization.GatewaySubscriptionId,
await _stripeAdapter.Received(1).UpdateSubscriptionAsync(organization.GatewaySubscriptionId,
Arg.Is<SubscriptionUpdateOptions>(options => options.AutomaticTax.Enabled == true));
}
@@ -131,7 +130,7 @@ public class UpdateBillingAddressCommandTests
}
};
_stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
_stripeAdapter.UpdateCustomerAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
options.Address.Matches(input) &&
options.HasExpansions("subscriptions")
)).Returns(customer);
@@ -144,7 +143,7 @@ public class UpdateBillingAddressCommandTests
await _subscriberService.Received(1).CreateStripeCustomer(organization);
await _stripeAdapter.Received(1).SubscriptionUpdateAsync(organization.GatewaySubscriptionId,
await _stripeAdapter.Received(1).UpdateSubscriptionAsync(organization.GatewaySubscriptionId,
Arg.Is<SubscriptionUpdateOptions>(options => options.AutomaticTax.Enabled == true));
}
@@ -192,7 +191,7 @@ public class UpdateBillingAddressCommandTests
}
};
_stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
_stripeAdapter.UpdateCustomerAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
options.Address.Matches(input) &&
options.HasExpansions("subscriptions", "tax_ids") &&
options.TaxExempt == TaxExempt.None
@@ -204,7 +203,7 @@ public class UpdateBillingAddressCommandTests
var output = result.AsT0;
Assert.Equivalent(input, output);
await _stripeAdapter.Received(1).SubscriptionUpdateAsync(organization.GatewaySubscriptionId,
await _stripeAdapter.Received(1).UpdateSubscriptionAsync(organization.GatewaySubscriptionId,
Arg.Is<SubscriptionUpdateOptions>(options => options.AutomaticTax.Enabled == true));
}
@@ -260,7 +259,7 @@ public class UpdateBillingAddressCommandTests
}
};
_stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
_stripeAdapter.UpdateCustomerAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
options.Address.Matches(input) &&
options.HasExpansions("subscriptions", "tax_ids") &&
options.TaxExempt == TaxExempt.None
@@ -272,10 +271,10 @@ public class UpdateBillingAddressCommandTests
var output = result.AsT0;
Assert.Equivalent(input, output);
await _stripeAdapter.Received(1).SubscriptionUpdateAsync(organization.GatewaySubscriptionId,
await _stripeAdapter.Received(1).UpdateSubscriptionAsync(organization.GatewaySubscriptionId,
Arg.Is<SubscriptionUpdateOptions>(options => options.AutomaticTax.Enabled == true));
await _stripeAdapter.Received(1).TaxIdDeleteAsync(customer.Id, "tax_id_123");
await _stripeAdapter.Received(1).DeleteTaxIdAsync(customer.Id, "tax_id_123");
}
[Fact]
@@ -322,7 +321,7 @@ public class UpdateBillingAddressCommandTests
}
};
_stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
_stripeAdapter.UpdateCustomerAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
options.Address.Matches(input) &&
options.HasExpansions("subscriptions", "tax_ids") &&
options.TaxExempt == TaxExempt.Reverse
@@ -334,7 +333,7 @@ public class UpdateBillingAddressCommandTests
var output = result.AsT0;
Assert.Equivalent(input, output);
await _stripeAdapter.Received(1).SubscriptionUpdateAsync(organization.GatewaySubscriptionId,
await _stripeAdapter.Received(1).UpdateSubscriptionAsync(organization.GatewaySubscriptionId,
Arg.Is<SubscriptionUpdateOptions>(options => options.AutomaticTax.Enabled == true));
}
@@ -384,14 +383,14 @@ public class UpdateBillingAddressCommandTests
}
};
_stripeAdapter.CustomerUpdateAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
_stripeAdapter.UpdateCustomerAsync(organization.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(options =>
options.Address.Matches(input) &&
options.HasExpansions("subscriptions", "tax_ids") &&
options.TaxExempt == TaxExempt.Reverse
)).Returns(customer);
_stripeAdapter
.TaxIdCreateAsync(customer.Id,
.CreateTaxIdAsync(customer.Id,
Arg.Is<TaxIdCreateOptions>(options => options.Type == TaxIdType.EUVAT))
.Returns(new TaxId { Type = TaxIdType.EUVAT, Value = "ESA12345678" });
@@ -401,10 +400,10 @@ public class UpdateBillingAddressCommandTests
var output = result.AsT0;
Assert.Equivalent(input with { TaxId = new TaxID(TaxIdType.EUVAT, "ESA12345678") }, output);
await _stripeAdapter.Received(1).SubscriptionUpdateAsync(organization.GatewaySubscriptionId,
await _stripeAdapter.Received(1).UpdateSubscriptionAsync(organization.GatewaySubscriptionId,
Arg.Is<SubscriptionUpdateOptions>(options => options.AutomaticTax.Enabled == true));
await _stripeAdapter.Received(1).TaxIdCreateAsync(organization.GatewayCustomerId, Arg.Is<TaxIdCreateOptions>(
await _stripeAdapter.Received(1).CreateTaxIdAsync(organization.GatewayCustomerId, Arg.Is<TaxIdCreateOptions>(
options => options.Type == TaxIdType.SpanishNIF &&
options.Value == input.TaxId.Value));
}

View File

@@ -4,7 +4,6 @@ using Bit.Core.Billing.Constants;
using Bit.Core.Billing.Payment.Commands;
using Bit.Core.Billing.Payment.Models;
using Bit.Core.Billing.Services;
using Bit.Core.Services;
using Bit.Core.Settings;
using Bit.Core.Test.Billing.Extensions;
using Braintree;
@@ -82,7 +81,7 @@ public class UpdatePaymentMethodCommandTests
Status = "requires_action"
};
_stripeAdapter.SetupIntentList(Arg.Is<SetupIntentListOptions>(options =>
_stripeAdapter.ListSetupIntentsAsync(Arg.Is<SetupIntentListOptions>(options =>
options.PaymentMethod == token && options.HasExpansions("data.payment_method"))).Returns([setupIntent]);
var result = await _command.Run(organization,
@@ -144,7 +143,7 @@ public class UpdatePaymentMethodCommandTests
Status = "requires_action"
};
_stripeAdapter.SetupIntentList(Arg.Is<SetupIntentListOptions>(options =>
_stripeAdapter.ListSetupIntentsAsync(Arg.Is<SetupIntentListOptions>(options =>
options.PaymentMethod == token && options.HasExpansions("data.payment_method"))).Returns([setupIntent]);
var result = await _command.Run(organization,
@@ -213,7 +212,7 @@ public class UpdatePaymentMethodCommandTests
Status = "requires_action"
};
_stripeAdapter.SetupIntentList(Arg.Is<SetupIntentListOptions>(options =>
_stripeAdapter.ListSetupIntentsAsync(Arg.Is<SetupIntentListOptions>(options =>
options.PaymentMethod == token && options.HasExpansions("data.payment_method"))).Returns([setupIntent]);
var result = await _command.Run(organization,
@@ -232,7 +231,7 @@ public class UpdatePaymentMethodCommandTests
Assert.Equal("https://example.com", maskedBankAccount.HostedVerificationUrl);
await _setupIntentCache.Received(1).Set(organization.Id, setupIntent.Id);
await _stripeAdapter.Received(1).CustomerUpdateAsync(customer.Id, Arg.Is<CustomerUpdateOptions>(options =>
await _stripeAdapter.Received(1).UpdateCustomerAsync(customer.Id, Arg.Is<CustomerUpdateOptions>(options =>
options.Metadata[MetadataKeys.BraintreeCustomerId] == string.Empty &&
options.Metadata[MetadataKeys.RetiredBraintreeCustomerId] == "braintree_customer_id"));
}
@@ -262,7 +261,7 @@ public class UpdatePaymentMethodCommandTests
const string token = "TOKEN";
_stripeAdapter
.PaymentMethodAttachAsync(token,
.AttachPaymentMethodAsync(token,
Arg.Is<PaymentMethodAttachOptions>(options => options.Customer == customer.Id))
.Returns(new PaymentMethod
{
@@ -291,7 +290,7 @@ public class UpdatePaymentMethodCommandTests
Assert.Equal("9999", maskedCard.Last4);
Assert.Equal("01/2028", maskedCard.Expiration);
await _stripeAdapter.Received(1).CustomerUpdateAsync(customer.Id,
await _stripeAdapter.Received(1).UpdateCustomerAsync(customer.Id,
Arg.Is<CustomerUpdateOptions>(options => options.InvoiceSettings.DefaultPaymentMethod == token));
}
@@ -315,7 +314,7 @@ public class UpdatePaymentMethodCommandTests
const string token = "TOKEN";
_stripeAdapter
.PaymentMethodAttachAsync(token,
.AttachPaymentMethodAsync(token,
Arg.Is<PaymentMethodAttachOptions>(options => options.Customer == customer.Id))
.Returns(new PaymentMethod
{
@@ -344,10 +343,10 @@ public class UpdatePaymentMethodCommandTests
Assert.Equal("9999", maskedCard.Last4);
Assert.Equal("01/2028", maskedCard.Expiration);
await _stripeAdapter.Received(1).CustomerUpdateAsync(customer.Id,
await _stripeAdapter.Received(1).UpdateCustomerAsync(customer.Id,
Arg.Is<CustomerUpdateOptions>(options => options.InvoiceSettings.DefaultPaymentMethod == token));
await _stripeAdapter.Received(1).CustomerUpdateAsync(customer.Id,
await _stripeAdapter.Received(1).UpdateCustomerAsync(customer.Id,
Arg.Is<CustomerUpdateOptions>(options => options.Address.Country == "US" && options.Address.PostalCode == "12345"));
}
@@ -468,7 +467,7 @@ public class UpdatePaymentMethodCommandTests
var maskedPayPalAccount = maskedPaymentMethod.AsT2;
Assert.Equal("user@gmail.com", maskedPayPalAccount.Email);
await _stripeAdapter.Received(1).CustomerUpdateAsync(customer.Id,
await _stripeAdapter.Received(1).UpdateCustomerAsync(customer.Id,
Arg.Is<CustomerUpdateOptions>(options =>
options.Metadata[MetadataKeys.BraintreeCustomerId] == "braintree_customer_id"));
}

View File

@@ -3,7 +3,6 @@ using Bit.Core.Billing.Caches;
using Bit.Core.Billing.Constants;
using Bit.Core.Billing.Payment.Queries;
using Bit.Core.Billing.Services;
using Bit.Core.Services;
using Bit.Core.Test.Billing.Extensions;
using Braintree;
using Microsoft.Extensions.Logging;
@@ -166,7 +165,7 @@ public class GetPaymentMethodQueryTests
_setupIntentCache.GetSetupIntentIdForSubscriber(organization.Id).Returns("seti_123");
_stripeAdapter
.SetupIntentGet("seti_123",
.GetSetupIntentAsync("seti_123",
Arg.Is<SetupIntentGetOptions>(options => options.HasExpansions("payment_method"))).Returns(
new SetupIntent
{

View File

@@ -3,7 +3,6 @@ using Bit.Core.Billing.Caches;
using Bit.Core.Billing.Constants;
using Bit.Core.Billing.Payment.Queries;
using Bit.Core.Billing.Services;
using Bit.Core.Services;
using Bit.Core.Test.Billing.Extensions;
using NSubstitute;
using NSubstitute.ReturnsExtensions;
@@ -57,7 +56,7 @@ public class HasPaymentMethodQueryTests
_setupIntentCache.GetSetupIntentIdForSubscriber(organization.Id).Returns("seti_123");
_stripeAdapter
.SetupIntentGet("seti_123",
.GetSetupIntentAsync("seti_123",
Arg.Is<SetupIntentGetOptions>(options => options.HasExpansions("payment_method")))
.Returns(new SetupIntent
{
@@ -162,7 +161,7 @@ public class HasPaymentMethodQueryTests
_setupIntentCache.GetSetupIntentIdForSubscriber(organization.Id).Returns("seti_123");
_stripeAdapter
.SetupIntentGet("seti_123",
.GetSetupIntentAsync("seti_123",
Arg.Is<SetupIntentGetOptions>(options => options.HasExpansions("payment_method")))
.Returns(new SetupIntent
{
@@ -246,7 +245,7 @@ public class HasPaymentMethodQueryTests
_setupIntentCache.GetSetupIntentIdForSubscriber(organization.Id).Returns("seti_123");
_stripeAdapter
.SetupIntentGet("seti_123",
.GetSetupIntentAsync("seti_123",
Arg.Is<SetupIntentGetOptions>(options => options.HasExpansions("payment_method")))
.Returns(new SetupIntent
{

View File

@@ -146,11 +146,11 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
var mockSetupIntent = Substitute.For<SetupIntent>();
mockSetupIntent.Id = "seti_123";
_stripeAdapter.CustomerCreateAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
_stripeAdapter.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
_stripeAdapter.SetupIntentList(Arg.Any<SetupIntentListOptions>()).Returns(Task.FromResult(new List<SetupIntent> { mockSetupIntent }));
_stripeAdapter.CreateCustomerAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
_stripeAdapter.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
_stripeAdapter.ListSetupIntentsAsync(Arg.Any<SetupIntentListOptions>()).Returns(Task.FromResult(new List<SetupIntent> { mockSetupIntent }));
_subscriberService.GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>()).Returns(mockCustomer);
// Act
@@ -158,8 +158,8 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
// Assert
Assert.True(result.IsT0);
await _stripeAdapter.Received(1).CustomerCreateAsync(Arg.Any<CustomerCreateOptions>());
await _stripeAdapter.Received(1).SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
await _stripeAdapter.Received(1).CreateCustomerAsync(Arg.Any<CustomerCreateOptions>());
await _stripeAdapter.Received(1).CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
await _userService.Received(1).SaveUserAsync(user);
await _pushNotificationService.Received(1).PushSyncVaultAsync(user.Id);
}
@@ -200,10 +200,10 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
var mockInvoice = Substitute.For<Invoice>();
_stripeAdapter.CustomerCreateAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
_stripeAdapter.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
_stripeAdapter.CreateCustomerAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
_stripeAdapter.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
_subscriberService.GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>()).Returns(mockCustomer);
// Act
@@ -211,8 +211,8 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
// Assert
Assert.True(result.IsT0);
await _stripeAdapter.Received(1).CustomerCreateAsync(Arg.Any<CustomerCreateOptions>());
await _stripeAdapter.Received(1).SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
await _stripeAdapter.Received(1).CreateCustomerAsync(Arg.Any<CustomerCreateOptions>());
await _stripeAdapter.Received(1).CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
await _userService.Received(1).SaveUserAsync(user);
await _pushNotificationService.Received(1).PushSyncVaultAsync(user.Id);
}
@@ -243,10 +243,10 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
var mockInvoice = Substitute.For<Invoice>();
_stripeAdapter.CustomerCreateAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
_stripeAdapter.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
_stripeAdapter.CreateCustomerAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
_stripeAdapter.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
_subscriberService.GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>()).Returns(mockCustomer);
_subscriberService.CreateBraintreeCustomer(Arg.Any<User>(), Arg.Any<string>()).Returns("bt_customer_123");
@@ -255,8 +255,8 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
// Assert
Assert.True(result.IsT0);
await _stripeAdapter.Received(1).CustomerCreateAsync(Arg.Any<CustomerCreateOptions>());
await _stripeAdapter.Received(1).SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
await _stripeAdapter.Received(1).CreateCustomerAsync(Arg.Any<CustomerCreateOptions>());
await _stripeAdapter.Received(1).CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
await _subscriberService.Received(1).CreateBraintreeCustomer(user, paymentMethod.Token);
await _userService.Received(1).SaveUserAsync(user);
await _pushNotificationService.Received(1).PushSyncVaultAsync(user.Id);
@@ -299,10 +299,10 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
var mockInvoice = Substitute.For<Invoice>();
_stripeAdapter.CustomerCreateAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
_stripeAdapter.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
_stripeAdapter.CreateCustomerAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
_stripeAdapter.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
_subscriberService.GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>()).Returns(mockCustomer);
// Act
@@ -356,8 +356,8 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
// Mock that the user has a payment method (this is the key difference from the credit purchase case)
_hasPaymentMethodQuery.Run(Arg.Any<User>()).Returns(true);
_subscriberService.GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>()).Returns(mockCustomer);
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
// Act
var result = await _command.Run(user, paymentMethod, billingAddress, 0);
@@ -365,7 +365,7 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
// Assert
Assert.True(result.IsT0);
await _subscriberService.Received(1).GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>());
await _stripeAdapter.DidNotReceive().CustomerCreateAsync(Arg.Any<CustomerCreateOptions>());
await _stripeAdapter.DidNotReceive().CreateCustomerAsync(Arg.Any<CustomerCreateOptions>());
await _updatePaymentMethodCommand.DidNotReceive().Run(Arg.Any<User>(), Arg.Any<TokenizedPaymentMethod>(), Arg.Any<BillingAddress>());
}
@@ -415,8 +415,8 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
_updatePaymentMethodCommand.Run(Arg.Any<User>(), Arg.Any<TokenizedPaymentMethod>(), Arg.Any<BillingAddress>())
.Returns(mockMaskedPaymentMethod);
_subscriberService.GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>()).Returns(mockCustomer);
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
// Act
var result = await _command.Run(user, paymentMethod, billingAddress, 0);
@@ -428,9 +428,9 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
// Verify GetCustomerOrThrow was called after updating payment method
await _subscriberService.Received(1).GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>());
// Verify no new customer was created
await _stripeAdapter.DidNotReceive().CustomerCreateAsync(Arg.Any<CustomerCreateOptions>());
await _stripeAdapter.DidNotReceive().CreateCustomerAsync(Arg.Any<CustomerCreateOptions>());
// Verify subscription was created
await _stripeAdapter.Received(1).SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
await _stripeAdapter.Received(1).CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
// Verify user was updated correctly
Assert.True(user.Premium);
await _userService.Received(1).SaveUserAsync(user);
@@ -474,10 +474,10 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
var mockInvoice = Substitute.For<Invoice>();
_stripeAdapter.CustomerCreateAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
_stripeAdapter.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
_stripeAdapter.CreateCustomerAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
_stripeAdapter.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
_subscriberService.CreateBraintreeCustomer(Arg.Any<User>(), Arg.Any<string>()).Returns("bt_customer_123");
// Act
@@ -525,10 +525,10 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
var mockInvoice = Substitute.For<Invoice>();
_stripeAdapter.CustomerCreateAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
_stripeAdapter.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
_stripeAdapter.CreateCustomerAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
_stripeAdapter.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
_subscriberService.GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>()).Returns(mockCustomer);
// Act
@@ -577,10 +577,10 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
var mockInvoice = Substitute.For<Invoice>();
_stripeAdapter.CustomerCreateAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
_stripeAdapter.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
_stripeAdapter.CreateCustomerAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
_stripeAdapter.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
_subscriberService.CreateBraintreeCustomer(Arg.Any<User>(), Arg.Any<string>()).Returns("bt_customer_123");
// Act
@@ -628,13 +628,13 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
var mockInvoice = Substitute.For<Invoice>();
_stripeAdapter.CustomerCreateAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
_stripeAdapter.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
_stripeAdapter.CreateCustomerAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
_stripeAdapter.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>()).Returns(mockCustomer);
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
_subscriberService.GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>()).Returns(mockCustomer);
_stripeAdapter.SetupIntentList(Arg.Any<SetupIntentListOptions>())
_stripeAdapter.ListSetupIntentsAsync(Arg.Any<SetupIntentListOptions>())
.Returns(Task.FromResult(new List<SetupIntent>())); // Empty list - no setup intent found
// Act
@@ -681,8 +681,8 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
var mockInvoice = Substitute.For<Invoice>();
_subscriberService.GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>()).Returns(mockCustomer);
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.InvoiceUpdateAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.UpdateInvoiceAsync(Arg.Any<string>(), Arg.Any<InvoiceUpdateOptions>()).Returns(mockInvoice);
// Act
var result = await _command.Run(user, paymentMethod, billingAddress, 0);
@@ -690,7 +690,7 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
// Assert
Assert.True(result.IsT0);
await _subscriberService.Received(1).GetCustomerOrThrow(Arg.Any<User>(), Arg.Any<CustomerGetOptions>());
await _stripeAdapter.DidNotReceive().CustomerCreateAsync(Arg.Any<CustomerCreateOptions>());
await _stripeAdapter.DidNotReceive().CreateCustomerAsync(Arg.Any<CustomerCreateOptions>());
Assert.True(user.Premium);
Assert.Equal(mockSubscription.GetCurrentPeriodEnd(), user.PremiumExpirationDate);
}
@@ -716,8 +716,8 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
Assert.True(result.IsT3); // Assuming T3 is the Unhandled result
Assert.IsType<BillingException>(result.AsT3.Exception);
// Verify no customer was created or subscription attempted
await _stripeAdapter.DidNotReceive().CustomerCreateAsync(Arg.Any<CustomerCreateOptions>());
await _stripeAdapter.DidNotReceive().SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
await _stripeAdapter.DidNotReceive().CreateCustomerAsync(Arg.Any<CustomerCreateOptions>());
await _stripeAdapter.DidNotReceive().CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
await _userService.DidNotReceive().SaveUserAsync(Arg.Any<User>());
}
@@ -767,8 +767,8 @@ public class CreatePremiumCloudHostedSubscriptionCommandTests
]
};
_stripeAdapter.CustomerCreateAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
_stripeAdapter.CreateCustomerAsync(Arg.Any<CustomerCreateOptions>()).Returns(mockCustomer);
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(mockSubscription);
// Act
var result = await _command.Run(user, paymentMethod, billingAddress, additionalStorage);

View File

@@ -1,7 +1,7 @@
using Bit.Core.Billing.Payment.Models;
using Bit.Core.Billing.Premium.Commands;
using Bit.Core.Billing.Pricing;
using Bit.Core.Services;
using Bit.Core.Billing.Services;
using Microsoft.Extensions.Logging;
using NSubstitute;
using Stripe;
@@ -50,7 +50,7 @@ public class PreviewPremiumTaxCommandTests
Total = 3300
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(0, billingAddress);
@@ -59,7 +59,7 @@ public class PreviewPremiumTaxCommandTests
Assert.Equal(3.00m, tax);
Assert.Equal(33.00m, total);
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "US" &&
@@ -84,7 +84,7 @@ public class PreviewPremiumTaxCommandTests
Total = 5500
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(5, billingAddress);
@@ -93,7 +93,7 @@ public class PreviewPremiumTaxCommandTests
Assert.Equal(5.00m, tax);
Assert.Equal(55.00m, total);
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "CA" &&
@@ -120,7 +120,7 @@ public class PreviewPremiumTaxCommandTests
Total = 2750
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(0, billingAddress);
@@ -129,7 +129,7 @@ public class PreviewPremiumTaxCommandTests
Assert.Equal(2.50m, tax);
Assert.Equal(27.50m, total);
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "GB" &&
@@ -154,7 +154,7 @@ public class PreviewPremiumTaxCommandTests
Total = 8800
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(20, billingAddress);
@@ -163,7 +163,7 @@ public class PreviewPremiumTaxCommandTests
Assert.Equal(8.00m, tax);
Assert.Equal(88.00m, total);
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "DE" &&
@@ -190,7 +190,7 @@ public class PreviewPremiumTaxCommandTests
Total = 4950
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(10, billingAddress);
@@ -199,7 +199,7 @@ public class PreviewPremiumTaxCommandTests
Assert.Equal(4.50m, tax);
Assert.Equal(49.50m, total);
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "AU" &&
@@ -226,7 +226,7 @@ public class PreviewPremiumTaxCommandTests
Total = 3000
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(0, billingAddress);
@@ -235,7 +235,7 @@ public class PreviewPremiumTaxCommandTests
Assert.Equal(0.00m, tax);
Assert.Equal(30.00m, total);
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "US" &&
@@ -260,7 +260,7 @@ public class PreviewPremiumTaxCommandTests
Total = 6600
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(-5, billingAddress);
@@ -269,7 +269,7 @@ public class PreviewPremiumTaxCommandTests
Assert.Equal(6.00m, tax);
Assert.Equal(66.00m, total);
await _stripeAdapter.Received(1).InvoiceCreatePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
await _stripeAdapter.Received(1).CreateInvoicePreviewAsync(Arg.Is<InvoiceCreatePreviewOptions>(options =>
options.AutomaticTax.Enabled == true &&
options.Currency == "usd" &&
options.CustomerDetails.Address.Country == "FR" &&
@@ -295,7 +295,7 @@ public class PreviewPremiumTaxCommandTests
Total = 3123 // $31.23
};
_stripeAdapter.InvoiceCreatePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
_stripeAdapter.CreateInvoicePreviewAsync(Arg.Any<InvoiceCreatePreviewOptions>()).Returns(invoice);
var result = await _command.Run(0, billingAddress);

View File

@@ -10,7 +10,6 @@ using Bit.Core.Billing.Pricing;
using Bit.Core.Billing.Services;
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Test.Billing.Mocks;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
@@ -179,7 +178,7 @@ public class OrganizationBillingServiceTests
SubscriptionCreateOptions capturedOptions = null;
sutProvider.GetDependency<IStripeAdapter>()
.SubscriptionCreateAsync(Arg.Do<SubscriptionCreateOptions>(options => capturedOptions = options))
.CreateSubscriptionAsync(Arg.Do<SubscriptionCreateOptions>(options => capturedOptions = options))
.Returns(new Subscription
{
Id = "sub_test123",
@@ -196,7 +195,7 @@ public class OrganizationBillingServiceTests
// Assert
await sutProvider.GetDependency<IStripeAdapter>()
.Received(1)
.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
Assert.NotNull(capturedOptions);
Assert.Equal(7, capturedOptions.TrialPeriodDays);
@@ -255,7 +254,7 @@ public class OrganizationBillingServiceTests
SubscriptionCreateOptions capturedOptions = null;
sutProvider.GetDependency<IStripeAdapter>()
.SubscriptionCreateAsync(Arg.Do<SubscriptionCreateOptions>(options => capturedOptions = options))
.CreateSubscriptionAsync(Arg.Do<SubscriptionCreateOptions>(options => capturedOptions = options))
.Returns(new Subscription
{
Id = "sub_test123",
@@ -272,7 +271,7 @@ public class OrganizationBillingServiceTests
// Assert
await sutProvider.GetDependency<IStripeAdapter>()
.Received(1)
.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
Assert.NotNull(capturedOptions);
Assert.Equal(0, capturedOptions.TrialPeriodDays);
@@ -329,7 +328,7 @@ public class OrganizationBillingServiceTests
SubscriptionCreateOptions capturedOptions = null;
sutProvider.GetDependency<IStripeAdapter>()
.SubscriptionCreateAsync(Arg.Do<SubscriptionCreateOptions>(options => capturedOptions = options))
.CreateSubscriptionAsync(Arg.Do<SubscriptionCreateOptions>(options => capturedOptions = options))
.Returns(new Subscription
{
Id = "sub_test123",
@@ -346,7 +345,7 @@ public class OrganizationBillingServiceTests
// Assert
await sutProvider.GetDependency<IStripeAdapter>()
.Received(1)
.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
Assert.NotNull(capturedOptions);
Assert.Equal(7, capturedOptions.TrialPeriodDays);
@@ -364,7 +363,7 @@ public class OrganizationBillingServiceTests
CustomerUpdateOptions capturedOptions = null;
sutProvider.GetDependency<IStripeAdapter>()
.CustomerUpdateAsync(
.UpdateCustomerAsync(
Arg.Is<string>(id => id == organization.GatewayCustomerId),
Arg.Do<CustomerUpdateOptions>(options => capturedOptions = options))
.Returns(new Customer());
@@ -375,7 +374,7 @@ public class OrganizationBillingServiceTests
// Assert
await sutProvider.GetDependency<IStripeAdapter>()
.Received(1)
.CustomerUpdateAsync(
.UpdateCustomerAsync(
organization.GatewayCustomerId,
Arg.Any<CustomerUpdateOptions>());
@@ -401,7 +400,7 @@ public class OrganizationBillingServiceTests
CustomerUpdateOptions capturedOptions = null;
sutProvider.GetDependency<IStripeAdapter>()
.CustomerUpdateAsync(
.UpdateCustomerAsync(
Arg.Is<string>(id => id == organization.GatewayCustomerId),
Arg.Do<CustomerUpdateOptions>(options => capturedOptions = options))
.Returns(new Customer());
@@ -412,7 +411,7 @@ public class OrganizationBillingServiceTests
// Assert
await sutProvider.GetDependency<IStripeAdapter>()
.Received(1)
.CustomerUpdateAsync(
.UpdateCustomerAsync(
organization.GatewayCustomerId,
Arg.Any<CustomerUpdateOptions>());
@@ -445,6 +444,6 @@ public class OrganizationBillingServiceTests
await sutProvider.GetDependency<IStripeAdapter>()
.DidNotReceiveWithAnyArgs()
.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>());
.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>());
}
}

View File

@@ -1,9 +1,9 @@
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Billing.Services;
using Bit.Core.Billing.Services.Implementations;
using Bit.Core.Entities;
using Bit.Core.Models.BitStripe;
using Bit.Core.Repositories;
using Bit.Core.Services;
using NSubstitute;
using Stripe;
using Xunit;
@@ -19,7 +19,7 @@ public class PaymentHistoryServiceTests
var subscriber = new Organization { GatewayCustomerId = "cus_id", GatewaySubscriptionId = "sub_id" };
var invoices = new List<Invoice> { new() { Id = "in_id" } };
var stripeAdapter = Substitute.For<IStripeAdapter>();
stripeAdapter.InvoiceListAsync(Arg.Any<StripeInvoiceListOptions>()).Returns(invoices);
stripeAdapter.ListInvoicesAsync(Arg.Any<StripeInvoiceListOptions>()).Returns(invoices);
var transactionRepository = Substitute.For<ITransactionRepository>();
var paymentHistoryService = new PaymentHistoryService(stripeAdapter, transactionRepository);
@@ -29,7 +29,7 @@ public class PaymentHistoryServiceTests
// Assert
Assert.NotEmpty(result);
Assert.Single(result);
await stripeAdapter.Received(1).InvoiceListAsync(Arg.Any<StripeInvoiceListOptions>());
await stripeAdapter.Received(1).ListInvoicesAsync(Arg.Any<StripeInvoiceListOptions>());
}
[Fact]

View File

@@ -1,7 +1,8 @@
using Bit.Core.Billing.Constants;
using Bit.Core.Billing.Services;
using Bit.Core.Billing.Services.Implementations;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Services;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
using NSubstitute;
@@ -49,7 +50,7 @@ public class StripePaymentServiceTests
};
sutProvider.GetDependency<IStripeAdapter>()
.SubscriptionGetAsync(
.GetSubscriptionAsync(
subscriber.GatewaySubscriptionId,
Arg.Any<SubscriptionGetOptions>())
.Returns(subscription);
@@ -100,7 +101,7 @@ public class StripePaymentServiceTests
};
sutProvider.GetDependency<IStripeAdapter>()
.SubscriptionGetAsync(
.GetSubscriptionAsync(
subscriber.GatewaySubscriptionId,
Arg.Any<SubscriptionGetOptions>())
.Returns(subscription);
@@ -159,7 +160,7 @@ public class StripePaymentServiceTests
};
sutProvider.GetDependency<IStripeAdapter>()
.SubscriptionGetAsync(
.GetSubscriptionAsync(
subscriber.GatewaySubscriptionId,
Arg.Any<SubscriptionGetOptions>())
.Returns(subscription);
@@ -198,7 +199,7 @@ public class StripePaymentServiceTests
};
sutProvider.GetDependency<IStripeAdapter>()
.SubscriptionGetAsync(
.GetSubscriptionAsync(
subscriber.GatewaySubscriptionId,
Arg.Any<SubscriptionGetOptions>())
.Returns(subscription);
@@ -256,7 +257,7 @@ public class StripePaymentServiceTests
};
sutProvider.GetDependency<IStripeAdapter>()
.SubscriptionGetAsync(
.GetSubscriptionAsync(
subscriber.GatewaySubscriptionId,
Arg.Any<SubscriptionGetOptions>())
.Returns(subscription);
@@ -295,7 +296,7 @@ public class StripePaymentServiceTests
};
sutProvider.GetDependency<IStripeAdapter>()
.SubscriptionGetAsync(
.GetSubscriptionAsync(
subscriber.GatewaySubscriptionId,
Arg.Any<SubscriptionGetOptions>())
.Returns(subscription);
@@ -332,7 +333,7 @@ public class StripePaymentServiceTests
};
sutProvider.GetDependency<IStripeAdapter>()
.SubscriptionGetAsync(
.GetSubscriptionAsync(
subscriber.GatewaySubscriptionId,
Arg.Any<SubscriptionGetOptions>())
.Returns(subscription);
@@ -367,7 +368,7 @@ public class StripePaymentServiceTests
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
stripeAdapter
.SubscriptionGetAsync(
.GetSubscriptionAsync(
Arg.Any<string>(),
Arg.Any<SubscriptionGetOptions>())
.Returns(subscription);
@@ -376,7 +377,7 @@ public class StripePaymentServiceTests
await sutProvider.Sut.GetSubscriptionAsync(subscriber);
// Assert - Verify expand options are correct
await stripeAdapter.Received(1).SubscriptionGetAsync(
await stripeAdapter.Received(1).GetSubscriptionAsync(
subscriber.GatewaySubscriptionId,
Arg.Is<SubscriptionGetOptions>(o =>
o.Expand.Contains("customer.discount.coupon.applies_to") &&
@@ -405,6 +406,6 @@ public class StripePaymentServiceTests
// Verify no Stripe API calls were made
await sutProvider.GetDependency<IStripeAdapter>()
.DidNotReceive()
.SubscriptionGetAsync(Arg.Any<string>(), Arg.Any<SubscriptionGetOptions>());
.GetSubscriptionAsync(Arg.Any<string>(), Arg.Any<SubscriptionGetOptions>());
}
}

View File

@@ -3,10 +3,10 @@ using Bit.Core.AdminConsole.Entities.Provider;
using Bit.Core.Billing.Caches;
using Bit.Core.Billing.Constants;
using Bit.Core.Billing.Models;
using Bit.Core.Billing.Services;
using Bit.Core.Billing.Services.Implementations;
using Bit.Core.Billing.Tax.Models;
using Bit.Core.Enums;
using Bit.Core.Services;
using Bit.Core.Settings;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
@@ -44,7 +44,7 @@ public class SubscriberServiceTests
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
stripeAdapter
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
.GetSubscriptionAsync(organization.GatewaySubscriptionId)
.Returns(subscription);
await ThrowsBillingExceptionAsync(() =>
@@ -52,11 +52,11 @@ public class SubscriberServiceTests
await stripeAdapter
.DidNotReceiveWithAnyArgs()
.SubscriptionUpdateAsync(Arg.Any<string>(), Arg.Any<SubscriptionUpdateOptions>());
.UpdateSubscriptionAsync(Arg.Any<string>(), Arg.Any<SubscriptionUpdateOptions>());
await stripeAdapter
.DidNotReceiveWithAnyArgs()
.SubscriptionCancelAsync(Arg.Any<string>(), Arg.Any<SubscriptionCancelOptions>());
.CancelSubscriptionAsync(Arg.Any<string>(), Arg.Any<SubscriptionCancelOptions>());
}
[Theory, BitAutoData]
@@ -81,7 +81,7 @@ public class SubscriberServiceTests
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
stripeAdapter
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
.GetSubscriptionAsync(organization.GatewaySubscriptionId)
.Returns(subscription);
var offboardingSurveyResponse = new OffboardingSurveyResponse
@@ -95,12 +95,12 @@ public class SubscriberServiceTests
await stripeAdapter
.Received(1)
.SubscriptionUpdateAsync(subscriptionId, Arg.Is<SubscriptionUpdateOptions>(
.UpdateSubscriptionAsync(subscriptionId, Arg.Is<SubscriptionUpdateOptions>(
options => options.Metadata["cancellingUserId"] == userId.ToString()));
await stripeAdapter
.Received(1)
.SubscriptionCancelAsync(subscriptionId, Arg.Is<SubscriptionCancelOptions>(options =>
.CancelSubscriptionAsync(subscriptionId, Arg.Is<SubscriptionCancelOptions>(options =>
options.CancellationDetails.Comment == offboardingSurveyResponse.Feedback &&
options.CancellationDetails.Feedback == offboardingSurveyResponse.Reason));
}
@@ -127,7 +127,7 @@ public class SubscriberServiceTests
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
stripeAdapter
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
.GetSubscriptionAsync(organization.GatewaySubscriptionId)
.Returns(subscription);
var offboardingSurveyResponse = new OffboardingSurveyResponse
@@ -141,11 +141,11 @@ public class SubscriberServiceTests
await stripeAdapter
.DidNotReceiveWithAnyArgs()
.SubscriptionUpdateAsync(Arg.Any<string>(), Arg.Any<SubscriptionUpdateOptions>());
.UpdateSubscriptionAsync(Arg.Any<string>(), Arg.Any<SubscriptionUpdateOptions>());
await stripeAdapter
.Received(1)
.SubscriptionCancelAsync(subscriptionId, Arg.Is<SubscriptionCancelOptions>(options =>
.CancelSubscriptionAsync(subscriptionId, Arg.Is<SubscriptionCancelOptions>(options =>
options.CancellationDetails.Comment == offboardingSurveyResponse.Feedback &&
options.CancellationDetails.Feedback == offboardingSurveyResponse.Reason));
}
@@ -170,7 +170,7 @@ public class SubscriberServiceTests
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
stripeAdapter
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
.GetSubscriptionAsync(organization.GatewaySubscriptionId)
.Returns(subscription);
var offboardingSurveyResponse = new OffboardingSurveyResponse
@@ -184,7 +184,7 @@ public class SubscriberServiceTests
await stripeAdapter
.Received(1)
.SubscriptionUpdateAsync(subscriptionId, Arg.Is<SubscriptionUpdateOptions>(options =>
.UpdateSubscriptionAsync(subscriptionId, Arg.Is<SubscriptionUpdateOptions>(options =>
options.CancelAtPeriodEnd == true &&
options.CancellationDetails.Comment == offboardingSurveyResponse.Feedback &&
options.CancellationDetails.Feedback == offboardingSurveyResponse.Reason &&
@@ -192,7 +192,7 @@ public class SubscriberServiceTests
await stripeAdapter
.DidNotReceiveWithAnyArgs()
.SubscriptionCancelAsync(Arg.Any<string>(), Arg.Any<SubscriptionCancelOptions>());
.CancelSubscriptionAsync(Arg.Any<string>(), Arg.Any<SubscriptionCancelOptions>());
}
#endregion
@@ -223,7 +223,7 @@ public class SubscriberServiceTests
SutProvider<SubscriberService> sutProvider)
{
sutProvider.GetDependency<IStripeAdapter>()
.CustomerGetAsync(organization.GatewayCustomerId)
.GetCustomerAsync(organization.GatewayCustomerId)
.ReturnsNull();
var customer = await sutProvider.Sut.GetCustomer(organization);
@@ -237,7 +237,7 @@ public class SubscriberServiceTests
SutProvider<SubscriberService> sutProvider)
{
sutProvider.GetDependency<IStripeAdapter>()
.CustomerGetAsync(organization.GatewayCustomerId)
.GetCustomerAsync(organization.GatewayCustomerId)
.ThrowsAsync<StripeException>();
var customer = await sutProvider.Sut.GetCustomer(organization);
@@ -253,7 +253,7 @@ public class SubscriberServiceTests
var customer = new Customer();
sutProvider.GetDependency<IStripeAdapter>()
.CustomerGetAsync(organization.GatewayCustomerId)
.GetCustomerAsync(organization.GatewayCustomerId)
.Returns(customer);
var gotCustomer = await sutProvider.Sut.GetCustomer(organization);
@@ -287,7 +287,7 @@ public class SubscriberServiceTests
SutProvider<SubscriberService> sutProvider)
{
sutProvider.GetDependency<IStripeAdapter>()
.CustomerGetAsync(organization.GatewayCustomerId)
.GetCustomerAsync(organization.GatewayCustomerId)
.ReturnsNull();
await ThrowsBillingExceptionAsync(async () => await sutProvider.Sut.GetCustomerOrThrow(organization));
@@ -301,7 +301,7 @@ public class SubscriberServiceTests
var stripeException = new StripeException();
sutProvider.GetDependency<IStripeAdapter>()
.CustomerGetAsync(organization.GatewayCustomerId)
.GetCustomerAsync(organization.GatewayCustomerId)
.ThrowsAsync(stripeException);
await ThrowsBillingExceptionAsync(
@@ -318,7 +318,7 @@ public class SubscriberServiceTests
var customer = new Customer();
sutProvider.GetDependency<IStripeAdapter>()
.CustomerGetAsync(organization.GatewayCustomerId)
.GetCustomerAsync(organization.GatewayCustomerId)
.Returns(customer);
var gotCustomer = await sutProvider.Sut.GetCustomerOrThrow(organization);
@@ -351,7 +351,7 @@ public class SubscriberServiceTests
}
};
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId,
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId,
Arg.Is<CustomerGetOptions>(
options => options.Expand.Contains("default_source") &&
options.Expand.Contains("invoice_settings.default_payment_method")))
@@ -388,7 +388,7 @@ public class SubscriberServiceTests
}
};
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId,
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId,
Arg.Is<CustomerGetOptions>(
options => options.Expand.Contains("default_source") &&
options.Expand.Contains("invoice_settings.default_payment_method")))
@@ -442,7 +442,7 @@ public class SubscriberServiceTests
}
};
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId,
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId,
Arg.Is<CustomerGetOptions>(
options => options.Expand.Contains("default_source") &&
options.Expand.Contains("invoice_settings.default_payment_method")))
@@ -478,7 +478,7 @@ public class SubscriberServiceTests
}
};
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId,
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId,
Arg.Is<CustomerGetOptions>(
options => options.Expand.Contains("default_source") &&
options.Expand.Contains("invoice_settings.default_payment_method")))
@@ -498,7 +498,7 @@ public class SubscriberServiceTests
{
var customer = new Customer { Id = provider.GatewayCustomerId };
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId,
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId,
Arg.Is<CustomerGetOptions>(options => options.Expand.Contains("default_source") &&
options.Expand.Contains(
"invoice_settings.default_payment_method")))
@@ -521,7 +521,7 @@ public class SubscriberServiceTests
sutProvider.GetDependency<ISetupIntentCache>().GetSetupIntentIdForSubscriber(provider.Id).Returns(setupIntent.Id);
sutProvider.GetDependency<IStripeAdapter>().SetupIntentGet(setupIntent.Id,
sutProvider.GetDependency<IStripeAdapter>().GetSetupIntentAsync(setupIntent.Id,
Arg.Is<SetupIntentGetOptions>(options => options.Expand.Contains("payment_method"))).Returns(setupIntent);
var paymentMethod = await sutProvider.Sut.GetPaymentSource(provider);
@@ -541,7 +541,7 @@ public class SubscriberServiceTests
DefaultSource = new BankAccount { Status = "verified", BankName = "Chase", Last4 = "9999" }
};
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId,
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId,
Arg.Is<CustomerGetOptions>(options => options.Expand.Contains("default_source") &&
options.Expand.Contains(
"invoice_settings.default_payment_method")))
@@ -564,7 +564,7 @@ public class SubscriberServiceTests
DefaultSource = new Card { Brand = "Visa", Last4 = "9999", ExpMonth = 9, ExpYear = 2028 }
};
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId,
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId,
Arg.Is<CustomerGetOptions>(options => options.Expand.Contains("default_source") &&
options.Expand.Contains(
"invoice_settings.default_payment_method")))
@@ -596,7 +596,7 @@ public class SubscriberServiceTests
}
};
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId,
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId,
Arg.Is<CustomerGetOptions>(
options => options.Expand.Contains("default_source") &&
options.Expand.Contains("invoice_settings.default_payment_method")))
@@ -636,7 +636,7 @@ public class SubscriberServiceTests
SutProvider<SubscriberService> sutProvider)
{
sutProvider.GetDependency<IStripeAdapter>()
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
.GetSubscriptionAsync(organization.GatewaySubscriptionId)
.ReturnsNull();
var subscription = await sutProvider.Sut.GetSubscription(organization);
@@ -650,7 +650,7 @@ public class SubscriberServiceTests
SutProvider<SubscriberService> sutProvider)
{
sutProvider.GetDependency<IStripeAdapter>()
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
.GetSubscriptionAsync(organization.GatewaySubscriptionId)
.ThrowsAsync<StripeException>();
var subscription = await sutProvider.Sut.GetSubscription(organization);
@@ -666,7 +666,7 @@ public class SubscriberServiceTests
var subscription = new Subscription();
sutProvider.GetDependency<IStripeAdapter>()
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
.GetSubscriptionAsync(organization.GatewaySubscriptionId)
.Returns(subscription);
var gotSubscription = await sutProvider.Sut.GetSubscription(organization);
@@ -698,7 +698,7 @@ public class SubscriberServiceTests
SutProvider<SubscriberService> sutProvider)
{
sutProvider.GetDependency<IStripeAdapter>()
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
.GetSubscriptionAsync(organization.GatewaySubscriptionId)
.ReturnsNull();
await ThrowsBillingExceptionAsync(async () => await sutProvider.Sut.GetSubscriptionOrThrow(organization));
@@ -712,7 +712,7 @@ public class SubscriberServiceTests
var stripeException = new StripeException();
sutProvider.GetDependency<IStripeAdapter>()
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
.GetSubscriptionAsync(organization.GatewaySubscriptionId)
.ThrowsAsync(stripeException);
await ThrowsBillingExceptionAsync(
@@ -729,7 +729,7 @@ public class SubscriberServiceTests
var subscription = new Subscription();
sutProvider.GetDependency<IStripeAdapter>()
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
.GetSubscriptionAsync(organization.GatewaySubscriptionId)
.Returns(subscription);
var gotSubscription = await sutProvider.Sut.GetSubscriptionOrThrow(organization);
@@ -760,7 +760,7 @@ public class SubscriberServiceTests
};
sutProvider.GetDependency<IStripeAdapter>()
.CustomerGetAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
.GetCustomerAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
.Returns(stripeCustomer);
var (braintreeGateway, customerGateway, paymentMethodGateway) = SetupBraintree(sutProvider.GetDependency<IBraintreeGateway>());
@@ -795,7 +795,7 @@ public class SubscriberServiceTests
};
sutProvider.GetDependency<IStripeAdapter>()
.CustomerGetAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
.GetCustomerAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
.Returns(stripeCustomer);
var (_, customerGateway, paymentMethodGateway) = SetupBraintree(sutProvider.GetDependency<IBraintreeGateway>());
@@ -832,7 +832,7 @@ public class SubscriberServiceTests
};
sutProvider.GetDependency<IStripeAdapter>()
.CustomerGetAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
.GetCustomerAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
.Returns(stripeCustomer);
var (_, customerGateway, paymentMethodGateway) = SetupBraintree(sutProvider.GetDependency<IBraintreeGateway>());
@@ -887,7 +887,7 @@ public class SubscriberServiceTests
};
sutProvider.GetDependency<IStripeAdapter>()
.CustomerGetAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
.GetCustomerAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
.Returns(stripeCustomer);
var (_, customerGateway, paymentMethodGateway) = SetupBraintree(sutProvider.GetDependency<IBraintreeGateway>());
@@ -946,21 +946,21 @@ public class SubscriberServiceTests
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
stripeAdapter
.CustomerGetAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
.GetCustomerAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
.Returns(stripeCustomer);
stripeAdapter
.PaymentMethodListAutoPagingAsync(Arg.Any<PaymentMethodListOptions>())
.ListPaymentMethodsAutoPagingAsync(Arg.Any<PaymentMethodListOptions>())
.Returns(GetPaymentMethodsAsync(new List<PaymentMethod>()));
await sutProvider.Sut.RemovePaymentSource(organization);
await stripeAdapter.Received(1).BankAccountDeleteAsync(stripeCustomer.Id, bankAccountId);
await stripeAdapter.Received(1).DeleteBankAccountAsync(stripeCustomer.Id, bankAccountId);
await stripeAdapter.Received(1).CardDeleteAsync(stripeCustomer.Id, cardId);
await stripeAdapter.Received(1).DeleteCardAsync(stripeCustomer.Id, cardId);
await stripeAdapter.DidNotReceiveWithAnyArgs()
.PaymentMethodDetachAsync(Arg.Any<string>(), Arg.Any<PaymentMethodDetachOptions>());
.DetachPaymentMethodAsync(Arg.Any<string>(), Arg.Any<PaymentMethodDetachOptions>());
}
[Theory, BitAutoData]
@@ -978,11 +978,11 @@ public class SubscriberServiceTests
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
stripeAdapter
.CustomerGetAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
.GetCustomerAsync(organization.GatewayCustomerId, Arg.Any<CustomerGetOptions>())
.Returns(stripeCustomer);
stripeAdapter
.PaymentMethodListAutoPagingAsync(Arg.Any<PaymentMethodListOptions>())
.ListPaymentMethodsAutoPagingAsync(Arg.Any<PaymentMethodListOptions>())
.Returns(GetPaymentMethodsAsync(new List<PaymentMethod>
{
new ()
@@ -997,15 +997,15 @@ public class SubscriberServiceTests
await sutProvider.Sut.RemovePaymentSource(organization);
await stripeAdapter.DidNotReceiveWithAnyArgs().BankAccountDeleteAsync(Arg.Any<string>(), Arg.Any<string>());
await stripeAdapter.DidNotReceiveWithAnyArgs().DeleteBankAccountAsync(Arg.Any<string>(), Arg.Any<string>());
await stripeAdapter.DidNotReceiveWithAnyArgs().CardDeleteAsync(Arg.Any<string>(), Arg.Any<string>());
await stripeAdapter.DidNotReceiveWithAnyArgs().DeleteCardAsync(Arg.Any<string>(), Arg.Any<string>());
await stripeAdapter.Received(1)
.PaymentMethodDetachAsync(bankAccountId);
.DetachPaymentMethodAsync(bankAccountId);
await stripeAdapter.Received(1)
.PaymentMethodDetachAsync(cardId);
.DetachPaymentMethodAsync(cardId);
}
private static async IAsyncEnumerable<PaymentMethod> GetPaymentMethodsAsync(
@@ -1050,7 +1050,7 @@ public class SubscriberServiceTests
Provider provider,
SutProvider<SubscriberService> sutProvider)
{
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId)
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId)
.Returns(new Customer());
await ThrowsBillingExceptionAsync(() =>
@@ -1062,7 +1062,7 @@ public class SubscriberServiceTests
Provider provider,
SutProvider<SubscriberService> sutProvider)
{
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId)
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId)
.Returns(new Customer());
await ThrowsBillingExceptionAsync(() =>
@@ -1076,10 +1076,10 @@ public class SubscriberServiceTests
{
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
stripeAdapter.CustomerGetAsync(provider.GatewayCustomerId)
stripeAdapter.GetCustomerAsync(provider.GatewayCustomerId)
.Returns(new Customer());
stripeAdapter.SetupIntentList(Arg.Is<SetupIntentListOptions>(options => options.PaymentMethod == "TOKEN"))
stripeAdapter.ListSetupIntentsAsync(Arg.Is<SetupIntentListOptions>(options => options.PaymentMethod == "TOKEN"))
.Returns([new SetupIntent(), new SetupIntent()]);
await ThrowsBillingExceptionAsync(() =>
@@ -1093,7 +1093,7 @@ public class SubscriberServiceTests
{
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
stripeAdapter.CustomerGetAsync(
stripeAdapter.GetCustomerAsync(
provider.GatewayCustomerId,
Arg.Is<CustomerGetOptions>(p => p.Expand.Contains("tax") || p.Expand.Contains("tax_ids")))
.Returns(new Customer
@@ -1107,10 +1107,10 @@ public class SubscriberServiceTests
var matchingSetupIntent = new SetupIntent { Id = "setup_intent_1" };
stripeAdapter.SetupIntentList(Arg.Is<SetupIntentListOptions>(options => options.PaymentMethod == "TOKEN"))
stripeAdapter.ListSetupIntentsAsync(Arg.Is<SetupIntentListOptions>(options => options.PaymentMethod == "TOKEN"))
.Returns([matchingSetupIntent]);
stripeAdapter.CustomerListPaymentMethods(provider.GatewayCustomerId).Returns([
stripeAdapter.ListCustomerPaymentMethodsAsync(provider.GatewayCustomerId).Returns([
new PaymentMethod { Id = "payment_method_1" }
]);
@@ -1119,12 +1119,12 @@ public class SubscriberServiceTests
await sutProvider.GetDependency<ISetupIntentCache>().Received(1).Set(provider.Id, "setup_intent_1");
await stripeAdapter.DidNotReceive().SetupIntentCancel(Arg.Any<string>(),
await stripeAdapter.DidNotReceive().CancelSetupIntentAsync(Arg.Any<string>(),
Arg.Any<SetupIntentCancelOptions>());
await stripeAdapter.Received(1).PaymentMethodDetachAsync("payment_method_1");
await stripeAdapter.Received(1).DetachPaymentMethodAsync("payment_method_1");
await stripeAdapter.Received(1).CustomerUpdateAsync(provider.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(
await stripeAdapter.Received(1).UpdateCustomerAsync(provider.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(
options => options.Metadata[Core.Billing.Utilities.BraintreeCustomerIdKey] == null));
}
@@ -1135,7 +1135,7 @@ public class SubscriberServiceTests
{
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
stripeAdapter.CustomerGetAsync(
stripeAdapter.GetCustomerAsync(
provider.GatewayCustomerId,
Arg.Is<CustomerGetOptions>(p => p.Expand.Contains("tax") || p.Expand.Contains("tax_ids"))
)
@@ -1148,22 +1148,22 @@ public class SubscriberServiceTests
}
});
stripeAdapter.CustomerListPaymentMethods(provider.GatewayCustomerId).Returns([
stripeAdapter.ListCustomerPaymentMethodsAsync(provider.GatewayCustomerId).Returns([
new PaymentMethod { Id = "payment_method_1" }
]);
await sutProvider.Sut.UpdatePaymentSource(provider,
new TokenizedPaymentSource(PaymentMethodType.Card, "TOKEN"));
await stripeAdapter.DidNotReceive().SetupIntentCancel(Arg.Any<string>(),
await stripeAdapter.DidNotReceive().CancelSetupIntentAsync(Arg.Any<string>(),
Arg.Any<SetupIntentCancelOptions>());
await stripeAdapter.Received(1).PaymentMethodDetachAsync("payment_method_1");
await stripeAdapter.Received(1).DetachPaymentMethodAsync("payment_method_1");
await stripeAdapter.Received(1).PaymentMethodAttachAsync("TOKEN", Arg.Is<PaymentMethodAttachOptions>(
await stripeAdapter.Received(1).AttachPaymentMethodAsync("TOKEN", Arg.Is<PaymentMethodAttachOptions>(
options => options.Customer == provider.GatewayCustomerId));
await stripeAdapter.Received(1).CustomerUpdateAsync(provider.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(
await stripeAdapter.Received(1).UpdateCustomerAsync(provider.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(
options =>
options.InvoiceSettings.DefaultPaymentMethod == "TOKEN" &&
options.Metadata[Core.Billing.Utilities.BraintreeCustomerIdKey] == null));
@@ -1176,7 +1176,7 @@ public class SubscriberServiceTests
{
const string braintreeCustomerId = "braintree_customer_id";
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId)
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId)
.Returns(new Customer
{
Id = provider.GatewayCustomerId,
@@ -1202,7 +1202,7 @@ public class SubscriberServiceTests
{
const string braintreeCustomerId = "braintree_customer_id";
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId)
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId)
.Returns(new Customer
{
Id = provider.GatewayCustomerId,
@@ -1240,7 +1240,7 @@ public class SubscriberServiceTests
{
const string braintreeCustomerId = "braintree_customer_id";
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(
provider.GatewayCustomerId,
Arg.Is<CustomerGetOptions>(p => p.Expand.Contains("tax") || p.Expand.Contains("tax_ids")))
.Returns(new Customer
@@ -1294,7 +1294,7 @@ public class SubscriberServiceTests
{
const string braintreeCustomerId = "braintree_customer_id";
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(
provider.GatewayCustomerId,
Arg.Is<CustomerGetOptions>(p => p.Expand.Contains("tax") || p.Expand.Contains("tax_ids")))
.Returns(new Customer
@@ -1363,7 +1363,7 @@ public class SubscriberServiceTests
{
const string braintreeCustomerId = "braintree_customer_id";
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(provider.GatewayCustomerId)
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(provider.GatewayCustomerId)
.Returns(new Customer
{
Id = provider.GatewayCustomerId
@@ -1395,7 +1395,7 @@ public class SubscriberServiceTests
new TokenizedPaymentSource(PaymentMethodType.PayPal, "TOKEN")));
await sutProvider.GetDependency<IStripeAdapter>().DidNotReceiveWithAnyArgs()
.CustomerUpdateAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>());
.UpdateCustomerAsync(Arg.Any<string>(), Arg.Any<CustomerUpdateOptions>());
}
[Theory, BitAutoData]
@@ -1405,7 +1405,7 @@ public class SubscriberServiceTests
{
const string braintreeCustomerId = "braintree_customer_id";
sutProvider.GetDependency<IStripeAdapter>().CustomerGetAsync(
sutProvider.GetDependency<IStripeAdapter>().GetCustomerAsync(
provider.GatewayCustomerId,
Arg.Is<CustomerGetOptions>(p => p.Expand.Contains("tax") || p.Expand.Contains("tax_ids")))
.Returns(new Customer
@@ -1442,7 +1442,7 @@ public class SubscriberServiceTests
await sutProvider.Sut.UpdatePaymentSource(provider,
new TokenizedPaymentSource(PaymentMethodType.PayPal, "TOKEN"));
await sutProvider.GetDependency<IStripeAdapter>().Received(1).CustomerUpdateAsync(provider.GatewayCustomerId,
await sutProvider.GetDependency<IStripeAdapter>().Received(1).UpdateCustomerAsync(provider.GatewayCustomerId,
Arg.Is<CustomerUpdateOptions>(
options => options.Metadata[Core.Billing.Utilities.BraintreeCustomerIdKey] == braintreeCustomerId));
}
@@ -1473,7 +1473,7 @@ public class SubscriberServiceTests
var customer = new Customer { Id = provider.GatewayCustomerId, TaxIds = new StripeList<TaxId> { Data = [new TaxId { Id = "tax_id_1", Type = "us_ein" }] } };
stripeAdapter.CustomerGetAsync(provider.GatewayCustomerId, Arg.Is<CustomerGetOptions>(
stripeAdapter.GetCustomerAsync(provider.GatewayCustomerId, Arg.Is<CustomerGetOptions>(
options => options.Expand.Contains("tax_ids"))).Returns(customer);
var taxInformation = new TaxInformation(
@@ -1487,7 +1487,7 @@ public class SubscriberServiceTests
"NY");
sutProvider.GetDependency<IStripeAdapter>()
.CustomerUpdateAsync(
.UpdateCustomerAsync(
Arg.Is<string>(p => p == provider.GatewayCustomerId),
Arg.Is<CustomerUpdateOptions>(options =>
options.Address.Country == "US" &&
@@ -1522,12 +1522,12 @@ public class SubscriberServiceTests
});
var subscription = new Subscription { Items = new StripeList<SubscriptionItem>() };
sutProvider.GetDependency<IStripeAdapter>().SubscriptionGetAsync(Arg.Any<string>())
sutProvider.GetDependency<IStripeAdapter>().GetSubscriptionAsync(Arg.Any<string>())
.Returns(subscription);
await sutProvider.Sut.UpdateTaxInformation(provider, taxInformation);
await stripeAdapter.Received(1).CustomerUpdateAsync(provider.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(
await stripeAdapter.Received(1).UpdateCustomerAsync(provider.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(
options =>
options.Address.Country == taxInformation.Country &&
options.Address.PostalCode == taxInformation.PostalCode &&
@@ -1536,13 +1536,13 @@ public class SubscriberServiceTests
options.Address.City == taxInformation.City &&
options.Address.State == taxInformation.State));
await stripeAdapter.Received(1).TaxIdDeleteAsync(provider.GatewayCustomerId, "tax_id_1");
await stripeAdapter.Received(1).DeleteTaxIdAsync(provider.GatewayCustomerId, "tax_id_1");
await stripeAdapter.Received(1).TaxIdCreateAsync(provider.GatewayCustomerId, Arg.Is<TaxIdCreateOptions>(
await stripeAdapter.Received(1).CreateTaxIdAsync(provider.GatewayCustomerId, Arg.Is<TaxIdCreateOptions>(
options => options.Type == "us_ein" &&
options.Value == taxInformation.TaxId));
await stripeAdapter.Received(1).SubscriptionUpdateAsync(provider.GatewaySubscriptionId,
await stripeAdapter.Received(1).UpdateSubscriptionAsync(provider.GatewaySubscriptionId,
Arg.Is<SubscriptionUpdateOptions>(options => options.AutomaticTax.Enabled == true));
}
@@ -1555,7 +1555,7 @@ public class SubscriberServiceTests
var customer = new Customer { Id = provider.GatewayCustomerId, TaxIds = new StripeList<TaxId> { Data = [new TaxId { Id = "tax_id_1", Type = "us_ein" }] } };
stripeAdapter.CustomerGetAsync(provider.GatewayCustomerId, Arg.Is<CustomerGetOptions>(
stripeAdapter.GetCustomerAsync(provider.GatewayCustomerId, Arg.Is<CustomerGetOptions>(
options => options.Expand.Contains("tax_ids"))).Returns(customer);
var taxInformation = new TaxInformation(
@@ -1569,7 +1569,7 @@ public class SubscriberServiceTests
"NY");
sutProvider.GetDependency<IStripeAdapter>()
.CustomerUpdateAsync(
.UpdateCustomerAsync(
Arg.Is<string>(p => p == provider.GatewayCustomerId),
Arg.Is<CustomerUpdateOptions>(options =>
options.Address.Country == "CA" &&
@@ -1605,12 +1605,12 @@ public class SubscriberServiceTests
});
var subscription = new Subscription { Items = new StripeList<SubscriptionItem>() };
sutProvider.GetDependency<IStripeAdapter>().SubscriptionGetAsync(Arg.Any<string>())
sutProvider.GetDependency<IStripeAdapter>().GetSubscriptionAsync(Arg.Any<string>())
.Returns(subscription);
await sutProvider.Sut.UpdateTaxInformation(provider, taxInformation);
await stripeAdapter.Received(1).CustomerUpdateAsync(provider.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(
await stripeAdapter.Received(1).UpdateCustomerAsync(provider.GatewayCustomerId, Arg.Is<CustomerUpdateOptions>(
options =>
options.Address.Country == taxInformation.Country &&
options.Address.PostalCode == taxInformation.PostalCode &&
@@ -1619,16 +1619,16 @@ public class SubscriberServiceTests
options.Address.City == taxInformation.City &&
options.Address.State == taxInformation.State));
await stripeAdapter.Received(1).TaxIdDeleteAsync(provider.GatewayCustomerId, "tax_id_1");
await stripeAdapter.Received(1).DeleteTaxIdAsync(provider.GatewayCustomerId, "tax_id_1");
await stripeAdapter.Received(1).TaxIdCreateAsync(provider.GatewayCustomerId, Arg.Is<TaxIdCreateOptions>(
await stripeAdapter.Received(1).CreateTaxIdAsync(provider.GatewayCustomerId, Arg.Is<TaxIdCreateOptions>(
options => options.Type == "us_ein" &&
options.Value == taxInformation.TaxId));
await stripeAdapter.Received(1).CustomerUpdateAsync(provider.GatewayCustomerId,
await stripeAdapter.Received(1).UpdateCustomerAsync(provider.GatewayCustomerId,
Arg.Is<CustomerUpdateOptions>(options => options.TaxExempt == StripeConstants.TaxExempt.Reverse));
await stripeAdapter.Received(1).SubscriptionUpdateAsync(provider.GatewaySubscriptionId,
await stripeAdapter.Received(1).UpdateSubscriptionAsync(provider.GatewaySubscriptionId,
Arg.Is<SubscriptionUpdateOptions>(options => options.AutomaticTax.Enabled == true));
}
@@ -1655,7 +1655,7 @@ public class SubscriberServiceTests
Assert.True(result);
await sutProvider.GetDependency<IStripeAdapter>().DidNotReceiveWithAnyArgs()
.CustomerGetAsync(Arg.Any<string>());
.GetCustomerAsync(Arg.Any<string>());
}
[Theory, BitAutoData]
@@ -1669,7 +1669,7 @@ public class SubscriberServiceTests
Assert.True(result);
await sutProvider.GetDependency<IStripeAdapter>().DidNotReceiveWithAnyArgs()
.CustomerGetAsync(Arg.Any<string>());
.GetCustomerAsync(Arg.Any<string>());
}
[Theory, BitAutoData]
@@ -1678,12 +1678,12 @@ public class SubscriberServiceTests
SutProvider<SubscriberService> sutProvider)
{
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
stripeAdapter.CustomerGetAsync(organization.GatewayCustomerId).Returns(new Customer());
stripeAdapter.GetCustomerAsync(organization.GatewayCustomerId).Returns(new Customer());
var result = await sutProvider.Sut.IsValidGatewayCustomerIdAsync(organization);
Assert.True(result);
await stripeAdapter.Received(1).CustomerGetAsync(organization.GatewayCustomerId);
await stripeAdapter.Received(1).GetCustomerAsync(organization.GatewayCustomerId);
}
[Theory, BitAutoData]
@@ -1693,12 +1693,12 @@ public class SubscriberServiceTests
{
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
var stripeException = new StripeException { StripeError = new StripeError { Code = "resource_missing" } };
stripeAdapter.CustomerGetAsync(organization.GatewayCustomerId).Throws(stripeException);
stripeAdapter.GetCustomerAsync(organization.GatewayCustomerId).Throws(stripeException);
var result = await sutProvider.Sut.IsValidGatewayCustomerIdAsync(organization);
Assert.False(result);
await stripeAdapter.Received(1).CustomerGetAsync(organization.GatewayCustomerId);
await stripeAdapter.Received(1).GetCustomerAsync(organization.GatewayCustomerId);
}
#endregion
@@ -1724,7 +1724,7 @@ public class SubscriberServiceTests
Assert.True(result);
await sutProvider.GetDependency<IStripeAdapter>().DidNotReceiveWithAnyArgs()
.SubscriptionGetAsync(Arg.Any<string>());
.GetSubscriptionAsync(Arg.Any<string>());
}
[Theory, BitAutoData]
@@ -1738,7 +1738,7 @@ public class SubscriberServiceTests
Assert.True(result);
await sutProvider.GetDependency<IStripeAdapter>().DidNotReceiveWithAnyArgs()
.SubscriptionGetAsync(Arg.Any<string>());
.GetSubscriptionAsync(Arg.Any<string>());
}
[Theory, BitAutoData]
@@ -1747,12 +1747,12 @@ public class SubscriberServiceTests
SutProvider<SubscriberService> sutProvider)
{
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
stripeAdapter.SubscriptionGetAsync(organization.GatewaySubscriptionId).Returns(new Subscription());
stripeAdapter.GetSubscriptionAsync(organization.GatewaySubscriptionId).Returns(new Subscription());
var result = await sutProvider.Sut.IsValidGatewaySubscriptionIdAsync(organization);
Assert.True(result);
await stripeAdapter.Received(1).SubscriptionGetAsync(organization.GatewaySubscriptionId);
await stripeAdapter.Received(1).GetSubscriptionAsync(organization.GatewaySubscriptionId);
}
[Theory, BitAutoData]
@@ -1762,12 +1762,12 @@ public class SubscriberServiceTests
{
var stripeAdapter = sutProvider.GetDependency<IStripeAdapter>();
var stripeException = new StripeException { StripeError = new StripeError { Code = "resource_missing" } };
stripeAdapter.SubscriptionGetAsync(organization.GatewaySubscriptionId).Throws(stripeException);
stripeAdapter.GetSubscriptionAsync(organization.GatewaySubscriptionId).Throws(stripeException);
var result = await sutProvider.Sut.IsValidGatewaySubscriptionIdAsync(organization);
Assert.False(result);
await stripeAdapter.Received(1).SubscriptionGetAsync(organization.GatewaySubscriptionId);
await stripeAdapter.Received(1).GetSubscriptionAsync(organization.GatewaySubscriptionId);
}
#endregion

View File

@@ -6,7 +6,6 @@ using Bit.Core.Billing.Services;
using Bit.Core.Billing.Subscriptions.Commands;
using Bit.Core.Entities;
using Bit.Core.Repositories;
using Bit.Core.Services;
using NSubstitute;
using Stripe;
using Xunit;
@@ -98,13 +97,13 @@ public class RestartSubscriptionCommandTests
};
_subscriberService.GetSubscription(organization).Returns(existingSubscription);
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(newSubscription);
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(newSubscription);
var result = await _command.Run(organization);
Assert.True(result.IsT0);
await _stripeAdapter.Received(1).SubscriptionCreateAsync(Arg.Is((SubscriptionCreateOptions options) =>
await _stripeAdapter.Received(1).CreateSubscriptionAsync(Arg.Is((SubscriptionCreateOptions options) =>
options.AutomaticTax.Enabled == true &&
options.CollectionMethod == CollectionMethod.ChargeAutomatically &&
options.Customer == "cus_123" &&
@@ -154,13 +153,13 @@ public class RestartSubscriptionCommandTests
};
_subscriberService.GetSubscription(provider).Returns(existingSubscription);
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(newSubscription);
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(newSubscription);
var result = await _command.Run(provider);
Assert.True(result.IsT0);
await _stripeAdapter.Received(1).SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
await _stripeAdapter.Received(1).CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
await _providerRepository.Received(1).ReplaceAsync(Arg.Is<Provider>(prov =>
prov.Id == providerId &&
@@ -199,13 +198,13 @@ public class RestartSubscriptionCommandTests
};
_subscriberService.GetSubscription(user).Returns(existingSubscription);
_stripeAdapter.SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(newSubscription);
_stripeAdapter.CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>()).Returns(newSubscription);
var result = await _command.Run(user);
Assert.True(result.IsT0);
await _stripeAdapter.Received(1).SubscriptionCreateAsync(Arg.Any<SubscriptionCreateOptions>());
await _stripeAdapter.Received(1).CreateSubscriptionAsync(Arg.Any<SubscriptionCreateOptions>());
await _userRepository.Received(1).ReplaceAsync(Arg.Is<User>(u =>
u.Id == userId &&

View File

@@ -1,4 +1,5 @@
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Billing.Services;
using Bit.Core.Entities;
using Bit.Core.Repositories;
using Bit.Core.Services;
@@ -12,7 +13,7 @@ public abstract class CancelSponsorshipCommandTestsBase : FamiliesForEnterpriseT
protected async Task AssertRemovedSponsoredPaymentAsync<T>(Organization sponsoredOrg,
OrganizationSponsorship sponsorship, SutProvider<T> sutProvider)
{
await sutProvider.GetDependency<IPaymentService>().Received(1)
await sutProvider.GetDependency<IStripePaymentService>().Received(1)
.RemoveOrganizationSponsorshipAsync(sponsoredOrg, sponsorship);
await sutProvider.GetDependency<IOrganizationRepository>().Received(1).UpsertAsync(sponsoredOrg);
if (sponsorship != null)
@@ -46,7 +47,7 @@ OrganizationSponsorship sponsorship, SutProvider<T> sutProvider)
protected static async Task AssertDidNotRemoveSponsoredPaymentAsync<T>(SutProvider<T> sutProvider)
{
await sutProvider.GetDependency<IPaymentService>().DidNotReceiveWithAnyArgs()
await sutProvider.GetDependency<IStripePaymentService>().DidNotReceiveWithAnyArgs()
.RemoveOrganizationSponsorshipAsync(default, default);
await sutProvider.GetDependency<IOrganizationRepository>().DidNotReceiveWithAnyArgs()
.UpsertAsync(default);

View File

@@ -1,10 +1,10 @@
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Services;
using Bit.Core.Entities;
using Bit.Core.Exceptions;
using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.Cloud;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Test.AutoFixture.OrganizationSponsorshipFixtures;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
@@ -82,7 +82,7 @@ public class SetUpSponsorshipCommandTests : FamiliesForEnterpriseTestsBase
private static async Task AssertDidNotSetUpAsync(SutProvider<SetUpSponsorshipCommand> sutProvider)
{
await sutProvider.GetDependency<IPaymentService>()
await sutProvider.GetDependency<IStripePaymentService>()
.DidNotReceiveWithAnyArgs()
.SponsorOrganizationAsync(default, default);
await sutProvider.GetDependency<IOrganizationRepository>()

View File

@@ -4,6 +4,7 @@ using Bit.Core.AdminConsole.Enums.Provider;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Pricing;
using Bit.Core.Billing.Services;
using Bit.Core.Exceptions;
using Bit.Core.Models.Business;
using Bit.Core.Models.StaticStore;
@@ -54,7 +55,7 @@ public class AddSecretsManagerSubscriptionCommandTests
c.AdditionalServiceAccounts == additionalServiceAccounts &&
c.AdditionalSeats == organization.Seats.GetValueOrDefault()));
await sutProvider.GetDependency<IPaymentService>().Received()
await sutProvider.GetDependency<IStripePaymentService>().Received()
.AddSecretsManagerToSubscription(organization, plan, additionalSmSeats, additionalServiceAccounts);
// TODO: call ReferenceEventService - see AC-1481
@@ -150,7 +151,7 @@ public class AddSecretsManagerSubscriptionCommandTests
private static async Task VerifyDependencyNotCalledAsync(SutProvider<AddSecretsManagerSubscriptionCommand> sutProvider)
{
await sutProvider.GetDependency<IPaymentService>().DidNotReceive()
await sutProvider.GetDependency<IStripePaymentService>().DidNotReceive()
.AddSecretsManagerToSubscription(Arg.Any<Organization>(), Arg.Any<Plan>(), Arg.Any<int>(), Arg.Any<int>());
// TODO: call ReferenceEventService - see AC-1481

View File

@@ -1,5 +1,6 @@
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Services;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.Business;
@@ -86,9 +87,9 @@ public class UpdateSecretsManagerSubscriptionCommandTests
await sutProvider.Sut.UpdateSubscriptionAsync(update);
await sutProvider.GetDependency<IPaymentService>().Received(1)
await sutProvider.GetDependency<IStripePaymentService>().Received(1)
.AdjustSmSeatsAsync(organization, plan, update.SmSeatsExcludingBase);
await sutProvider.GetDependency<IPaymentService>().Received(1)
await sutProvider.GetDependency<IStripePaymentService>().Received(1)
.AdjustServiceAccountsAsync(organization, plan, update.SmServiceAccountsExcludingBase);
// TODO: call ReferenceEventService - see AC-1481
@@ -136,9 +137,9 @@ public class UpdateSecretsManagerSubscriptionCommandTests
await sutProvider.Sut.UpdateSubscriptionAsync(update);
await sutProvider.GetDependency<IPaymentService>().Received(1)
await sutProvider.GetDependency<IStripePaymentService>().Received(1)
.AdjustSmSeatsAsync(organization, plan, update.SmSeatsExcludingBase);
await sutProvider.GetDependency<IPaymentService>().Received(1)
await sutProvider.GetDependency<IStripePaymentService>().Received(1)
.AdjustServiceAccountsAsync(organization, plan, update.SmServiceAccountsExcludingBase);
// TODO: call ReferenceEventService - see AC-1481
@@ -258,7 +259,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
await sutProvider.Sut.UpdateSubscriptionAsync(update);
await sutProvider.GetDependency<IPaymentService>().Received(1).AdjustServiceAccountsAsync(
await sutProvider.GetDependency<IStripePaymentService>().Received(1).AdjustServiceAccountsAsync(
Arg.Is<Organization>(o => o.Id == organizationId),
plan,
expectedSmServiceAccountsExcludingBase);
@@ -779,9 +780,9 @@ public class UpdateSecretsManagerSubscriptionCommandTests
private static async Task VerifyDependencyNotCalledAsync(SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
{
await sutProvider.GetDependency<IPaymentService>().DidNotReceive()
await sutProvider.GetDependency<IStripePaymentService>().DidNotReceive()
.AdjustSmSeatsAsync(Arg.Any<Organization>(), Arg.Any<Plan>(), Arg.Any<int>());
await sutProvider.GetDependency<IPaymentService>().DidNotReceive()
await sutProvider.GetDependency<IStripePaymentService>().DidNotReceive()
.AdjustServiceAccountsAsync(Arg.Any<Organization>(), Arg.Any<Plan>(), Arg.Any<int>());
// TODO: call ReferenceEventService - see AC-1481
await sutProvider.GetDependency<IMailService>().DidNotReceive()

View File

@@ -1,5 +1,6 @@
using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Pricing;
using Bit.Core.Billing.Services;
using Bit.Core.Exceptions;
using Bit.Core.Models.Business;
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
@@ -121,7 +122,7 @@ public class UpgradeOrganizationPlanCommandTests
Users = 1
});
await sutProvider.Sut.UpgradePlanAsync(organization.Id, organizationUpgrade);
await sutProvider.GetDependency<IPaymentService>().Received(1).AdjustSubscription(
await sutProvider.GetDependency<IStripePaymentService>().Received(1).AdjustSubscription(
organization,
MockPlans.Get(planType),
organizationUpgrade.AdditionalSeats,

View File

@@ -227,7 +227,7 @@ public abstract class WebApplicationFactoryBase<T> : WebApplicationFactory<T>
services.AddSingleton<ILoggerFactory, NullLoggerFactory>();
// Noop StripePaymentService - this could be changed to integrate with our Stripe test account
Replace(services, Substitute.For<IPaymentService>());
Replace(services, Substitute.For<IStripePaymentService>());
Replace(services, Substitute.For<IOrganizationBillingService>());
});