Skip to content

Commit acd2856

Browse files
committed
feat(next): dedup glean success and fail events
Because: - Success and fail events were reported multiple times on page load of the success and error pages. This commit: - Removes glean event reporting from success and error pages. - Adds glean event reporting to processing and needs_input page redirects to the success or error page. Closes #PAY-3181
1 parent 1f5ad09 commit acd2856

22 files changed

Lines changed: 260 additions & 128 deletions

File tree

apps/payments/next/app/[locale]/[offeringId]/[interval]/checkout/[cartId]/error/page.tsx

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import {
1717
} from '@fxa/payments/ui/server';
1818
import {
1919
getCartOrRedirectAction,
20-
recordEmitterEventAction,
2120
} from '@fxa/payments/ui/actions';
2221
import { config } from 'apps/payments/next/config';
2322
import type { Metadata } from 'next';
@@ -62,13 +61,6 @@ export default async function CheckoutError({
6261
const l10n = getApp().getL10n(acceptLanguage, locale);
6362
const [cart] = await Promise.all([cartPromise]);
6463

65-
recordEmitterEventAction(
66-
'checkoutFail',
67-
{ ...params },
68-
searchParams,
69-
cart.paymentInfo?.type
70-
);
71-
7264
const errorReason = getErrorFtlInfo(cart.errorReasonId, params, config, searchParams);
7365

7466
return (
@@ -80,7 +72,7 @@ export default async function CheckoutError({
8072
{
8173
// Once more conditionals are added, move this to a separate component
8274
cart.errorReasonId ===
83-
CartErrorReasonId.CART_ELIGIBILITY_STATUS_SAME ? (
75+
CartErrorReasonId.CART_ELIGIBILITY_STATUS_SAME ? (
8476
<Image
8577
src={checkIcon}
8678
alt=""

apps/payments/next/app/[locale]/[offeringId]/[interval]/checkout/[cartId]/success/page.tsx

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { getCardIcon } from '@fxa/payments/ui';
1010
import {
1111
fetchCMSData,
1212
getCartOrRedirectAction,
13-
recordEmitterEventAction,
1413
} from '@fxa/payments/ui/actions';
1514
import {
1615
getApp,
@@ -67,13 +66,6 @@ export default async function CheckoutSuccess({
6766
sessionPromise,
6867
]);
6968

70-
recordEmitterEventAction(
71-
'checkoutSuccess',
72-
{ ...params },
73-
searchParams,
74-
cart.paymentInfo.type
75-
);
76-
7769
const { successActionButtonUrl, successActionButtonLabel } =
7870
cms.commonContent.localizations.at(0) || cms.commonContent;
7971

apps/payments/next/app/[locale]/[offeringId]/[interval]/upgrade/[cartId]/(mainLayout)/error/page.tsx

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import {
1616
} from '@fxa/payments/ui/server';
1717
import {
1818
getCartOrRedirectAction,
19-
recordEmitterEventAction,
2019
} from '@fxa/payments/ui/actions';
2120
import { config } from 'apps/payments/next/config';
2221
import { Metadata } from 'next';
@@ -60,13 +59,6 @@ export default async function UpgradeError({
6059
const l10n = getApp().getL10n(acceptLanguage, locale);
6160
const [cart] = await Promise.all([cartPromise]);
6261

63-
recordEmitterEventAction(
64-
'checkoutFail',
65-
{ ...params },
66-
searchParams,
67-
cart.paymentInfo?.type
68-
);
69-
7062
const errorReason = getErrorFtlInfo(cart.errorReasonId, params, config, searchParams);
7163

7264
return (

apps/payments/next/app/[locale]/[offeringId]/[interval]/upgrade/[cartId]/(mainLayout)/success/page.tsx

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {
1313
import {
1414
fetchCMSData,
1515
getCartOrRedirectAction,
16-
recordEmitterEventAction,
1716
} from '@fxa/payments/ui/actions';
1817
import { CheckoutParams } from '@fxa/payments/ui/server';
1918
import Image from 'next/image';
@@ -67,13 +66,6 @@ export default async function UpgradeSuccess({
6766
sessionPromise,
6867
]);
6968

70-
recordEmitterEventAction(
71-
'checkoutSuccess',
72-
{ ...params },
73-
searchParams,
74-
cart.paymentInfo.type
75-
);
76-
7769
const { successActionButtonUrl, successActionButtonLabel } =
7870
cms.commonContent.localizations.at(0) || cms.commonContent;
7971

@@ -211,7 +203,7 @@ export default async function UpgradeSuccess({
211203
width={70}
212204
height={24}
213205
/>
214-
) :(
206+
) : (
215207
<span className="flex items-center gap-2">
216208
{cart.paymentInfo.brand && (
217209
<Image

libs/payments/cart/src/lib/cart.service.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,9 @@ export class CartService {
823823
? this.subscriptionManager.listForCustomer(cart.stripeCustomerId)
824824
: undefined,
825825
cart.stripeCustomerId
826-
? this.customerSessionManager.createCheckoutSession(cart.stripeCustomerId)
826+
? this.customerSessionManager.createCheckoutSession(
827+
cart.stripeCustomerId
828+
)
827829
: undefined,
828830
]);
829831
const cartEligibilityStatus =

libs/payments/customer/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export * from './lib/promotionCode.manager';
1414
export * from './lib/setupIntent.manager';
1515
export * from './lib/subscription.manager';
1616
export * from './lib/types';
17+
export * from './lib/factories/paymentMethod.factory';
1718
export * from './lib/factories/pricing-for-currency.factory';
1819
export * from './lib/factories/tax-address.factory';
1920
export * from './lib/customer.error';
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
import { faker } from '@faker-js/faker';
6+
import { SubPlatPaymentMethodType, type StripePaymentMethod } from '../types';
7+
8+
export const StripePaymentMethodTypeResponseFactory = (
9+
override?: Partial<StripePaymentMethod>
10+
): StripePaymentMethod => ({
11+
type: faker.helpers.arrayElement([
12+
SubPlatPaymentMethodType.Card,
13+
SubPlatPaymentMethodType.ApplePay,
14+
SubPlatPaymentMethodType.GooglePay,
15+
SubPlatPaymentMethodType.Link,
16+
SubPlatPaymentMethodType.Stripe,
17+
]),
18+
paymentMethodId: `pm_${faker.string.alphanumeric({ length: 14 })}`,
19+
...override,
20+
});

libs/payments/customer/src/lib/paymentMethod.manager.ts

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,9 @@ import {
1313
import {
1414
DefaultPaymentMethod,
1515
SubPlatPaymentMethodType,
16-
StripePaymentMethod,
17-
PayPalPaymentMethod,
16+
type PaymentMethodTypeResponse,
1817
} from './types';
1918

20-
type PaymentMethodTypeResponse =
21-
| StripePaymentMethod
22-
| PayPalPaymentMethod
23-
| null;
24-
2519
@Injectable()
2620
export class PaymentMethodManager {
2721
constructor(
@@ -46,10 +40,7 @@ export class PaymentMethodManager {
4640
uid: string
4741
) {
4842
let defaultPaymentMethod: DefaultPaymentMethod | undefined;
49-
const paymentMethodType = await this.determineType(
50-
customer,
51-
subscriptions
52-
);
43+
const paymentMethodType = await this.determineType(customer, subscriptions);
5344
switch (paymentMethodType?.type) {
5445
case SubPlatPaymentMethodType.Link:
5546
case SubPlatPaymentMethodType.Card:
@@ -82,10 +73,10 @@ export class PaymentMethodManager {
8273
return defaultPaymentMethod;
8374
}
8475

85-
async determineType (
76+
async determineType(
8677
customer?: StripeCustomer,
8778
subscriptions?: StripeSubscription[]
88-
): Promise <PaymentMethodTypeResponse> {
79+
): Promise<PaymentMethodTypeResponse> {
8980
// First check if payment method is PayPal
9081
// Note, this needs to happen first since a customer could also have a
9182
// default payment method. However if PayPal is set as the payment method,
@@ -107,22 +98,22 @@ export class PaymentMethodManager {
10798
return {
10899
type: SubPlatPaymentMethodType.ApplePay,
109100
paymentMethodId: customer.invoice_settings.default_payment_method,
110-
}
101+
};
111102
} else if (paymentMethod.card?.wallet?.type === 'google_pay') {
112103
return {
113104
type: SubPlatPaymentMethodType.GooglePay,
114105
paymentMethodId: customer.invoice_settings.default_payment_method,
115-
}
106+
};
116107
} else if (paymentMethod.type === 'link') {
117108
return {
118109
type: SubPlatPaymentMethodType.Link,
119110
paymentMethodId: customer.invoice_settings.default_payment_method,
120-
}
111+
};
121112
} else if (paymentMethod.type === 'card') {
122113
return {
123114
type: SubPlatPaymentMethodType.Card,
124115
paymentMethodId: customer.invoice_settings.default_payment_method,
125-
}
116+
};
126117
} else {
127118
return {
128119
type: SubPlatPaymentMethodType.Stripe,
@@ -132,6 +123,5 @@ export class PaymentMethodManager {
132123
}
133124

134125
return null;
135-
};
136-
126+
}
137127
}

libs/payments/customer/src/lib/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ export interface PayPalPaymentMethod {
5252
type: SubPlatPaymentMethodType.PayPal;
5353
}
5454

55+
export type PaymentMethodTypeResponse =
56+
| StripePaymentMethod
57+
| PayPalPaymentMethod
58+
| null;
59+
5560
export interface Interval {
5661
interval: NonNullable<StripePrice['recurring']>['interval'];
5762
intervalCount: number;

0 commit comments

Comments
 (0)