* feat(billing): introduce unified subscription price increase scheduler API
* feat(billing): implement unified subscription price increase scheduler logic
* refactor(billing): update subscription handlers to use unified scheduler
* feat(billing): extend price migration feature flag checks
* test(billing): add and update tests for unified price increase scheduler
* fix(billing): run dotnet format
* feat(billing): expand customer and customer.discount on subscription fetch
* refactor(ReinstateSubscriptionCommandTests): rename test method for broader scope
* feat(billing): expand customer.discount in update handler
* test(billing): update test name
* feat(billing): add test clock waiting mechanism for upcoming invoices
* feat(billing): introduce cancelling user ID metadata key
* feat(billing): store cancelling user ID on subscription cancellation
* feat(billing): clear cancelling user ID on subscription reinstatement
* test(billing): update subscriber service tests for cancelling user ID
* style(SubscriberService): use 'is not null' pattern matching
* feat(SubscriberService): add PM35215 migration cohort metadata handling
* feat(SubscriberService): extend price migration deferral to PM35215
* test(SubscriberService): add and update tests for PM35215 feature
* feat(billing): Introduce OrganizationPriceIncreaseOptions
* refactor(billing): Centralize price increase eligibility in scheduler
* refactor(billing): Delegate price increase validation from UpcomingInvoiceHandler
* feat(billing): Manage price increase schedules during subscription lifecycle events
* test(billing): Update UpcomingInvoiceHandlerTests for centralized validation
* test(billing): Add PriceIncreaseScheduler tests for SkipIfAlreadyScheduled option
* test(billing): Add SubscriberService tests for price increase schedule management
* fix(billing): run dotnet format
* fix(billing): remove redundant customer expansion
* fix(billing): expand discounts for customer and subscription
* refactor(billing): Rename method to clarify dispatching role for organization scheduling
* fix(billing): Prevent clearing migration cohort metadata on cancellation
* fix(billing): Fallback to standard email when price increase migration fails
* feat(billing): improve observability for missing migration path data
* refactor(billing): simplify business plan type identification
* feat(billing): add feature flag for automatic tax enforcement
* refactor(billing): remove unused SubscriptionUpdateOptionsExtensions
* refactor(billing): inject IFeatureService into billing services and commands
* feat(billing): conditionalize customer tax exemption logic with feature flag
* feat(billing): conditionally enable Stripe automatic tax in OrganizationBillingService
* test(billing): add unit tests for Stripe automatic tax feature flag
* fix(billing): Run dotnet format
* test(Premium): use class-level IFeatureService mock in UpgradePremiumToOrganizationCommandTests
* refactor(billing): consolidate customer return conditions for automatic tax
* refactor(billing): broaden postal code validation for organization creation
* refactor(billing): remove PM37597 feature flag for automatic tax logic
* Revert "refactor(billing): broaden postal code validation for organization creation"
This reverts commit cddbda838c.
* fix(test): remove outdated test
* [PM-34813] fix system coupons regression
refactor customer setup class to split system coupons from discount coupons so that they can be applied systematically
UpdateTaxInformation has no callers in src/. Remove from ISubscriberService,
SubscriberService, and associated tests. Also removes the now-unused
ITaxService constructor parameter from SubscriberService.
* Add coupon support to invoice preview and subscription creation
* Fix the build lint error
* Resolve the initial review comments
* fix the failing test
* fix the build lint error
* Fix the failing test
* Resolve the unaddressed issues
* Fixed the deconstruction error
* Fix the lint issue
* Fix the lint error
* Fix the lint error
* Fix the build lint error
* lint error resolved
* remove the setting file
* rename the variable name validatedCoupon
* Remove the owner property
* Update OrganizationBillingService tests to align with recent refactoring
- Remove GetMetadata tests as method no longer exists
- Remove Owner property references from OrganizationSale (removed in d7613365ed)
- Update coupon validation to use SubscriptionDiscountRepository instead of SubscriptionDiscountService
- Add missing imports for SubscriptionDiscount entities
- Rename test for clarity: Finalize_WithNullOwner_SkipsValidation → Finalize_WithCouponOutsideDateRange_IgnoresCouponAndProceeds
All tests passing (14/14)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix the lint error
* Making the owner non nullable
* fix the failing unit test
* Make the owner nullable
* Fix the bug for coupon in Stripe with no audience restrictions(PM-32756)
* Return validation message for invalid coupon
* Update the valid token message
* Fix the failing unit test
* Remove the duplicate method
* Fix the failing build and test
* Resolve the failing test
* Add delete of invalid coupon
* Add the expired error message
* Delete on invalid coupon in stripe
* Fix the lint errors
* return null if we get exception from stripe
* remove the auto-delete change
* fix the failing test
* Fix the lint build error
---------
Co-authored-by: Claude <noreply@anthropic.com>
* docs(billing): add design document for replacing SetupIntent cache
* docs(billing): add implementation plan for replacing SetupIntent cache
* feat(db): add gateway lookup stored procedures for Organization, Provider, and User
* feat(db): add gateway lookup indexes to Organization, Provider, and User table definitions
* chore(db): add SQL Server migration for gateway lookup indexes and stored procedures
* feat(repos): add gateway lookup methods to IOrganizationRepository and Dapper implementation
* feat(repos): add gateway lookup methods to IProviderRepository and Dapper implementation
* feat(repos): add gateway lookup methods to IUserRepository and Dapper implementation
* feat(repos): add EF OrganizationRepository gateway lookup methods and index configuration
* feat(repos): add EF ProviderRepository gateway lookup methods and index configuration
* feat(repos): add EF UserRepository gateway lookup methods and index configuration
* chore(db): add EF migrations for gateway lookup indexes
* refactor(billing): update SetupIntentSucceededHandler to use repository instead of cache
* refactor(billing): simplify StripeEventService by expanding customer on SetupIntent
* refactor(billing): query Stripe for SetupIntents by customer ID in GetPaymentMethodQuery
* refactor(billing): query Stripe for SetupIntents by customer ID in HasPaymentMethodQuery
* refactor(billing): update OrganizationBillingService to set customer on SetupIntent
* refactor(billing): update ProviderBillingService to set customer on SetupIntent and query by customer
* refactor(billing): update UpdatePaymentMethodCommand to set customer on SetupIntent
* refactor(billing): remove bank account support from CreatePremiumCloudHostedSubscriptionCommand
* refactor(billing): remove OrganizationBillingService.UpdatePaymentMethod dead code
* refactor(billing): remove ProviderBillingService.UpdatePaymentMethod
* refactor(billing): remove PremiumUserBillingService.UpdatePaymentMethod and UserService.ReplacePaymentMethodAsync
* refactor(billing): remove SubscriberService.UpdatePaymentSource and related dead code
* refactor(billing): update SubscriberService.GetPaymentSourceAsync to query Stripe by customer ID
Add Task 15a to plan - this was a missed requirement for updating
GetPaymentSourceAsync which still used the cache.
* refactor(billing): complete removal of PremiumUserBillingService.Finalize and UserService.SignUpPremiumAsync
* refactor(billing): remove ISetupIntentCache and SetupIntentDistributedCache
* chore: remove temporary planning documents
* chore: run dotnet format
* fix(billing): add MaxLength(50) to Provider gateway ID properties
* chore(db): add EF migrations for Provider gateway column lengths
* chore: run dotnet format
* chore: rename SQL migration for chronological order
Remove the fully-released feature flag and clean up the old code path:
- Remove flag constant from FeatureFlagKeys
- Remove [RequireFeature] gate from VNext billing controllers
- Remove old GetMetadataAsync endpoint from OrganizationBillingController
- Remove GetMetadata from IOrganizationBillingService and implementation
- Remove IsOnSecretsManagerStandalone private helper
- Remove associated tests
* 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>
And other refactors:
- move update organization method to a command
- separate authorization from business logic
- add tests
- move Billing Team logic into their service
* Remove feature flag and move StaticStore plans to MockPlans for tests
* Remove old plan models / move sponsored plans out of StaticStore
* Run dotnet format
* Add pricing URI to Development appsettings for local development and integration tests
* Updated Api Integration tests to get current plan type
* Run dotnet format
* Fix failing tests
* 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
* Fix provider invoice generation validation
* More QA fixes
* Fix tests
* QA defect resolutions
* QA defect resolutions
* Run dotnet format
* Fix tests
---------
Co-authored-by: cyprain-okeke <108260115+cyprain-okeke@users.noreply.github.com>
* ignore serena
* removing unused properties from org metadata
* removing further properties that can already be fetched on the client side using available data
* new vnext endpoint for org metadata plus caching metadata first pass
including new feature flag
# Conflicts:
# src/Core/Constants.cs
* [PM-25379] decided against cache and new query shouldn't use the service
* pr feedback
removing unneeded response model
* run dotnet format
* ignore serena
* removing unused properties from org metadata
* removing further properties that can already be fetched on the client side using available data
* new vnext endpoint for org metadata plus caching metadata first pass
including new feature flag
# Conflicts:
# src/Core/Constants.cs
* [PM-25379] decided against cache and new query shouldn't use the service
* pr feedback
removing unneeded response model
* run dotnet format
* [PM-25088] add feature flag for new premium subscription flow
* [PM-25088] refactor premium endpoint
* forgot the punctuation change in the test
* [PM-25088] - pr feedback
* [PM-25088] - pr feedback round two
* [PM-21878] also update gateway/stripe fields for business units
* pr feedback: replacing switch with extension method
* [PM-21878] prevent invalid stripe ids from crashing the edit provider page
* pr feedback: adding service methods to validate stripe ids
and added unit tests for the new methods
* pr feedback: move validation to SubscriberService and cleanup
* pr feedback: use subscriber service to remove dependency on stripe adapter
* Moved license models to billing
* Moved LicensingService to billing
* Moved license command and queries to billing
* Moved LicenseController to billing
* implement the seat decrease error message
* Resolve the comment regarding abstraction
* Resolved the database failure
Signed-off-by: Cy Okeke <cokeke@bitwarden.com>
* Resolve the failing test
Signed-off-by: Cy Okeke <cokeke@bitwarden.com>
* Resolve the failing test
Signed-off-by: Cy Okeke <cokeke@bitwarden.com>
* Resolve the failing upgrade test
Signed-off-by: Cy Okeke <cokeke@bitwarden.com>
* Resolve the failing test
Signed-off-by: Cy Okeke <cokeke@bitwarden.com>
* Resolve the failing test
Signed-off-by: Cy Okeke <cokeke@bitwarden.com>
* Removed the unused method
* Remove the total calculation from the stored procedure
* Refactoring base on pr feedback
* Refactoring base on pr feedback
* Resolve the fauiling database
* Resolve the failing database test
* Resolve the database test
* Remove duplicate migrations
* resolve the failing test
* Removed the unneeded change
* remove this file
* Reverted Deleted migration
* revert the added space
* resolve the stored procedure name
* Rename the migration name
* Updated the stored procedure name
* Revert the changes on the sproc
* Revert unrelated changes
* Remove the unused method
* improved the xmldoc
* Add an integration testing
* Add the use of helper test class
Signed-off-by: Cy Okeke <cokeke@bitwarden.com>
* Resolve the failing test
Signed-off-by: Cy Okeke <cokeke@bitwarden.com>
* Resolve the failing test
Signed-off-by: Cy Okeke <cokeke@bitwarden.com>
* remove object look up
* Resolve message rollback
Signed-off-by: Cy Okeke <cokeke@bitwarden.com>
---------
Signed-off-by: Cy Okeke <cokeke@bitwarden.com>
* Set automatic tax to enabled and tax exempt to reverse where applicable when ff is on
* Fix and add tests
* Run dotnet format
* Run dotnet format
* PM-21745: Resolve defect
* PM-21770: Resolve defect
* Run dotnet format'
* [NO LOGIC] [PM-21104] Organize Core.Billing tax code
* Add PreviewTaxAmountCommand and expose through TaxController
* Add PreviewTaxAmountCommandTests
* Run dotnet format
* Pm 19147 2 (#5544)
* Pm 19147 2 (#5544)
* Unit tests for tax strategies `GetUpdateOptions`
* Only allow automatic tax flag to be updated for complete subscription updates such as plan changes, not when upgrading additional storage, seats, etc
* unit tests for factory
* Fix build
* Automatic tax for tax estimation
* Fix stub
* Fix stub
* "customer.tax_ids" isn't expanded in some flows.
* Fix SubscriberServiceTests.cs
* BusinessUseAutomaticTaxStrategy > SetUpdateOptions tests
* Fix ProviderBillingServiceTests.cs
* Remove gRPC and convert PricingClient to HttpClient wrapper
* Add PlanType.GetProductTier extension
Many instances of StaticStore use are just to get the ProductTierType of a PlanType, but this can be derived from the PlanType itself without having to fetch the entire plan.
* Remove invocations of the StaticStore in non-Test code
* Deprecate StaticStore entry points
* Run dotnet format
* Matt's feedback
* Run dotnet format
* Rui's feedback
* Run dotnet format
* Replacements since approval
* Run dotnet format
* Added invoices and transaction history endpoints. Added cursor paging for each
* Removed try/catch since it's handled by middleware. Updated condition to use pattern matching
* Added unit tests for PaymentHistoryService
* Removed organizationId from account billing controller endpoints