diff --git a/packages/fxa-auth-server/scripts/convert-customers-to-stripe-automatic-tax/convert-customers-to-stripe-automatic-tax.ts b/packages/fxa-auth-server/scripts/convert-customers-to-stripe-automatic-tax/convert-customers-to-stripe-automatic-tax.ts index 423519db10d..8afd55bdf71 100644 --- a/packages/fxa-auth-server/scripts/convert-customers-to-stripe-automatic-tax/convert-customers-to-stripe-automatic-tax.ts +++ b/packages/fxa-auth-server/scripts/convert-customers-to-stripe-automatic-tax/convert-customers-to-stripe-automatic-tax.ts @@ -23,6 +23,7 @@ export class StripeAutomaticTaxConverter { private ipAddressMap: IpAddressMap; private helpers: StripeAutomaticTaxConverterHelpers; private stripeQueue: PQueue; + private ineligibleProducts: string[]; /** * A converter to update all eligible customers to Stripe automatic tax @@ -60,6 +61,8 @@ export class StripeAutomaticTaxConverter { fs.readFileSync(ipAddressMapFile, 'utf-8') ); this.ipAddressMap = this.helpers.processIPAddressList(ipAddressList); + + this.ineligibleProducts = ['prod_HEJ13uxjG4Rj6L', 'prod_HeWOjYtYcEjAzV']; } /** @@ -132,6 +135,9 @@ export class StripeAutomaticTaxConverter { try { const product = await this.fetchProduct(plan.product as string); + const isExcludedProduct = this.isExcludedSubscriptionProduct(product.id); + if (isExcludedProduct) return; // Return early if subscription is for excluded product + const customer = await this.fetchCustomer(customerId); if (!customer) return; // Do not enable tax for an invalid customer @@ -216,6 +222,15 @@ export class StripeAutomaticTaxConverter { return isTaxEligible; } + /** + * Check if the subscriptions product is eligible to enable Tax + * @param productId + * @returns + */ + isExcludedSubscriptionProduct(productId: string) { + return this.ineligibleProducts.includes(productId); + } + /** * Updates a Stripe subscription with automatic tax enabled * @param subscriptionId Subscription to enable automatic tax for diff --git a/packages/fxa-auth-server/test/scripts/convert-customers-to-stripe-automatic-tax.ts b/packages/fxa-auth-server/test/scripts/convert-customers-to-stripe-automatic-tax.ts index dbedfd4945b..360f60f111f 100644 --- a/packages/fxa-auth-server/test/scripts/convert-customers-to-stripe-automatic-tax.ts +++ b/packages/fxa-auth-server/test/scripts/convert-customers-to-stripe-automatic-tax.ts @@ -227,6 +227,9 @@ describe('StripeAutomaticTaxConverter', () => { .resolves(mockCustomer); enableTaxForCustomer = sinon.stub().resolves(true); stripeAutomaticTaxConverter.enableTaxForCustomer = enableTaxForCustomer; + stripeAutomaticTaxConverter.isExcludedSubscriptionProduct = sinon + .stub() + .returns(false); enableTaxForSubscription = sinon.stub().resolves(); stripeAutomaticTaxConverter.enableTaxForSubscription = enableTaxForSubscription; @@ -291,6 +294,19 @@ describe('StripeAutomaticTaxConverter', () => { expect(enableTaxForSubscription.notCalled).true; expect(logStub.notCalled).true; }); + + it('does not update subscription for ineligible product', async () => { + stripeAutomaticTaxConverter.isExcludedSubscriptionProduct = sinon + .stub() + .returns(true); + await stripeAutomaticTaxConverter.generateReportForSubscription( + mockFirestoreSub + ); + + expect(enableTaxForCustomer.notCalled).true; + expect(enableTaxForSubscription.notCalled).true; + expect(logStub.notCalled).true; + }); }); }); @@ -436,6 +452,28 @@ describe('StripeAutomaticTaxConverter', () => { }); }); + describe('isEligibleSubscriptionProduct', () => { + let result: boolean; + const VALID_PRODUCT = 'valid'; + const EXCLUDED_PRODUCT = 'prod_HEJ13uxjG4Rj6L'; + + it('returns false if the product is not excluded', () => { + result = + stripeAutomaticTaxConverter.isExcludedSubscriptionProduct( + VALID_PRODUCT + ); + expect(result).false; + }); + + it('returns true if the product is meant to be excluded', () => { + result = + stripeAutomaticTaxConverter.isExcludedSubscriptionProduct( + EXCLUDED_PRODUCT + ); + expect(result).true; + }); + }); + describe('enableTaxForSubscription', () => { let updateStub: sinon.SinonStub; let retrieveStub: sinon.SinonStub;