Skip to content

Commit 9d0a561

Browse files
committed
fix(payments): send subscription welcome email for otp
Because: - Passwordless OTP accounts were not receiving the Welcome to product_name email due to a legacy check in stripe-webhooks that checked if the account was a passwordless email/password stub account. This commit: - Removes the legacy check for passwordless email/password stub accounts, since these types of accounts are no longer supported. Closes #PAY-3592
1 parent d064d6d commit 9d0a561

3 files changed

Lines changed: 58 additions & 64 deletions

File tree

packages/fxa-auth-server/lib/routes/subscriptions/stripe-webhook.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -978,11 +978,7 @@ export class StripeWebhookHandler extends StripeHandler {
978978
case 'subscription_create':
979979
await this.mailer.sendSubscriptionFirstInvoiceEmail(...mailParams);
980980

981-
// To not overwhelm users with emails, we only send download subscription email
982-
// for existing accounts. Passwordless accounts get their own email.
983-
if (account.verifierSetAt > 0) {
984-
await this.mailer.sendDownloadSubscriptionEmail(...mailParams);
985-
}
981+
await this.mailer.sendDownloadSubscriptionEmail(...mailParams);
986982
break;
987983
case 'subscription_update':
988984
// We already send an email for subscription updates. https://mozilla-hub.atlassian.net/browse/PAY-2290

packages/fxa-auth-server/lib/routes/subscriptions/stripe-webhooks.spec.ts

Lines changed: 57 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,9 @@ describe('StripeWebhookHandler', () => {
214214
sandbox.replace(Sentry, 'withScope', (fn: any) => fn(scopeSpy));
215215
});
216216

217-
const assertNamedHandlerCalled = (expectedHandlerName: string | null = null) => {
217+
const assertNamedHandlerCalled = (
218+
expectedHandlerName: string | null = null
219+
) => {
218220
for (const handlerName of handlerNames) {
219221
const shouldCall =
220222
expectedHandlerName && handlerName === expectedHandlerName;
@@ -1686,7 +1688,11 @@ describe('StripeWebhookHandler', () => {
16861688
'This transaction already has a chargeback filed'
16871689
);
16881690
refusedError.output = { payload: { invoiceId: invoice.id } };
1689-
sinon.assert.calledOnceWithExactly(sentryMod.reportSentryError, refusedError, {});
1691+
sinon.assert.calledOnceWithExactly(
1692+
sentryMod.reportSentryError,
1693+
refusedError,
1694+
{}
1695+
);
16901696
sinon.assert.calledOnceWithExactly(
16911697
StripeWebhookHandlerInstance.log.error,
16921698
'handleCreditNoteEvent',
@@ -2162,7 +2168,11 @@ describe('StripeWebhookHandler', () => {
21622168

21632169
describe('sendSubscriptionInvoiceEmail', () => {
21642170
const commonSendSubscriptionInvoiceEmailTest =
2165-
(expectedMethodName: string, billingReason: string, verifierSetAt = Date.now()) =>
2171+
(
2172+
expectedMethodName: string,
2173+
billingReason: string,
2174+
verifierSetAt = Date.now()
2175+
) =>
21662176
async () => {
21672177
const invoice = eventInvoicePaid.data.object;
21682178

@@ -2225,15 +2235,6 @@ describe('StripeWebhookHandler', () => {
22252235
)
22262236
);
22272237

2228-
it(
2229-
'sends the initial invoice email for a newly created subscription with passwordless account',
2230-
commonSendSubscriptionInvoiceEmailTest(
2231-
'sendSubscriptionFirstInvoiceEmail',
2232-
'subscription_create',
2233-
0
2234-
)
2235-
);
2236-
22372238
it(
22382239
'sends the subsequent invoice email for billing reasons besides creation',
22392240
commonSendSubscriptionInvoiceEmailTest(
@@ -2278,44 +2279,48 @@ describe('StripeWebhookHandler', () => {
22782279
});
22792280

22802281
describe('sendSubscriptionUpdatedEmail', () => {
2281-
const commonSendSubscriptionUpdatedEmailTest = (updateType: any) => async () => {
2282-
const event = deepCopy(eventCustomerSubscriptionUpdated);
2282+
const commonSendSubscriptionUpdatedEmailTest =
2283+
(updateType: any) => async () => {
2284+
const event = deepCopy(eventCustomerSubscriptionUpdated);
22832285

2284-
const mockDetails = {
2285-
uid: '1234',
2286-
test: 'fake',
2287-
updateType,
2288-
};
2289-
StripeWebhookHandlerInstance.stripeHelper.extractSubscriptionUpdateEventDetailsForEmail.resolves(
2290-
mockDetails
2291-
);
2286+
const mockDetails = {
2287+
uid: '1234',
2288+
test: 'fake',
2289+
updateType,
2290+
};
2291+
StripeWebhookHandlerInstance.stripeHelper.extractSubscriptionUpdateEventDetailsForEmail.resolves(
2292+
mockDetails
2293+
);
22922294

2293-
const mockAccount = { emails: 'fakeemails', locale: 'fakelocale' };
2294-
StripeWebhookHandlerInstance.db.account = sinon.spy(
2295-
async () => mockAccount
2296-
);
2295+
const mockAccount = { emails: 'fakeemails', locale: 'fakelocale' };
2296+
StripeWebhookHandlerInstance.db.account = sinon.spy(
2297+
async () => mockAccount
2298+
);
22972299

2298-
await StripeWebhookHandlerInstance.sendSubscriptionUpdatedEmail(event);
2300+
await StripeWebhookHandlerInstance.sendSubscriptionUpdatedEmail(event);
22992301

2300-
const expectedMethodName = ({
2301-
[SUBSCRIPTION_UPDATE_TYPES.UPGRADE]: 'sendSubscriptionUpgradeEmail',
2302-
[SUBSCRIPTION_UPDATE_TYPES.DOWNGRADE]: 'sendSubscriptionDowngradeEmail',
2303-
[SUBSCRIPTION_UPDATE_TYPES.REACTIVATION]:
2304-
'sendSubscriptionReactivationEmail',
2305-
[SUBSCRIPTION_UPDATE_TYPES.CANCELLATION]:
2306-
'sendSubscriptionCancellationEmail',
2307-
} as any)[updateType];
2302+
const expectedMethodName = (
2303+
{
2304+
[SUBSCRIPTION_UPDATE_TYPES.UPGRADE]: 'sendSubscriptionUpgradeEmail',
2305+
[SUBSCRIPTION_UPDATE_TYPES.DOWNGRADE]:
2306+
'sendSubscriptionDowngradeEmail',
2307+
[SUBSCRIPTION_UPDATE_TYPES.REACTIVATION]:
2308+
'sendSubscriptionReactivationEmail',
2309+
[SUBSCRIPTION_UPDATE_TYPES.CANCELLATION]:
2310+
'sendSubscriptionCancellationEmail',
2311+
} as any
2312+
)[updateType];
23082313

2309-
sinon.assert.calledWith(
2310-
StripeWebhookHandlerInstance.mailer[expectedMethodName],
2311-
mockAccount.emails,
2312-
mockAccount,
2313-
{
2314-
acceptLanguage: mockAccount.locale,
2315-
...mockDetails,
2316-
}
2317-
);
2318-
};
2314+
sinon.assert.calledWith(
2315+
StripeWebhookHandlerInstance.mailer[expectedMethodName],
2316+
mockAccount.emails,
2317+
mockAccount,
2318+
{
2319+
acceptLanguage: mockAccount.locale,
2320+
...mockDetails,
2321+
}
2322+
);
2323+
};
23192324

23202325
it(
23212326
'sends an upgrade email on subscription upgrade',
@@ -2402,12 +2407,14 @@ describe('StripeWebhookHandler', () => {
24022407
});
24032408

24042409
const mockAccount = { emails: 'fakeemails', locale: 'fakelocale' };
2405-
StripeWebhookHandlerInstance.db.account = sinon.spy(async (data: any) => {
2406-
if (options.accountFound) {
2407-
return mockAccount;
2410+
StripeWebhookHandlerInstance.db.account = sinon.spy(
2411+
async (data: any) => {
2412+
if (options.accountFound) {
2413+
return mockAccount;
2414+
}
2415+
throw error.unknownAccount();
24082416
}
2409-
throw error.unknownAccount();
2410-
});
2417+
);
24112418

24122419
await StripeWebhookHandlerInstance.sendSubscriptionDeletedEmail(
24132420
subscription

packages/fxa-auth-server/test/local/routes/subscriptions/stripe-webhooks.js

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2246,15 +2246,6 @@ describe('StripeWebhookHandler', () => {
22462246
)
22472247
);
22482248

2249-
it(
2250-
'sends the initial invoice email for a newly created subscription with passwordless account',
2251-
commonSendSubscriptionInvoiceEmailTest(
2252-
'sendSubscriptionFirstInvoiceEmail',
2253-
'subscription_create',
2254-
0
2255-
)
2256-
);
2257-
22582249
it(
22592250
'sends the subsequent invoice email for billing reasons besides creation',
22602251
commonSendSubscriptionInvoiceEmailTest(

0 commit comments

Comments
 (0)