diff --git a/support-frontend/assets/helpers/tracking/quantumMetric.ts b/support-frontend/assets/helpers/tracking/quantumMetric.ts index bc74e53661..65dbbf6dce 100644 --- a/support-frontend/assets/helpers/tracking/quantumMetric.ts +++ b/support-frontend/assets/helpers/tracking/quantumMetric.ts @@ -4,6 +4,7 @@ import type { Participations } from 'helpers/abTests/abtest'; import type { ContributionType } from 'helpers/contributions'; import type { PaymentMethod } from 'helpers/forms/paymentMethods'; import type { IsoCurrency } from 'helpers/internationalisation/currency'; +import type { ProductKey } from 'helpers/productCatalog'; import type { BillingPeriod } from 'helpers/productPrice/billingPeriods'; import type { ProductPrice } from 'helpers/productPrice/productPrices'; import type { SubscriptionProduct } from 'helpers/productPrice/subscriptions'; @@ -11,6 +12,7 @@ import { logException } from 'helpers/utilities/logger'; import type { ReferrerAcquisitionData } from './acquisitions'; import { canRunQuantumMetric, + getCheckoutAnnualValue, getContributionAnnualValue, getSubscriptionAnnualValue, waitForQuantumMetricAPi, @@ -22,6 +24,8 @@ type SendEventTestParticipationId = 30; type SendEventPageViewId = 181; +type SendEventCheckoutValueId = 182; + enum SendEventAcquisitionDataFromQueryParam { Source = 94, ComponentId = 95, @@ -70,7 +74,8 @@ type SendEventId = | SendEventContributionCheckoutConversion | SendEventContributionPaymentMethodUpdate | SendEventAcquisitionDataFromQueryParam - | SendEventPageViewId; + | SendEventPageViewId + | SendEventCheckoutValueId; // ---- sendEvent logic ---- // @@ -107,6 +112,7 @@ function sendEvent( id: SendEventId, isConversion: boolean, value: string, + payload?: Record, ): void { /** * A cart value event is indicated by 64 in QM. @@ -119,7 +125,12 @@ function sendEvent( ? 64 : 0; if (window.QuantumMetricAPI?.isOn()) { - window.QuantumMetricAPI.sendEvent(id, qmCartValueEventId, value); + console.log('*** sendEvent ***', id, qmCartValueEventId, value, payload); + if (payload) { + window.QuantumMetricAPI.sendEvent(id, qmCartValueEventId, value, payload); + } else { + window.QuantumMetricAPI.sendEvent(id, qmCartValueEventId, value); + } } } @@ -287,6 +298,45 @@ function sendEventSubscriptionCheckoutConversion( } } +function sendEventCheckoutValue( + amount: number, + product: ProductKey, + billingPeriod: BillingPeriod, + sourceCurrency: IsoCurrency, +): void { + console.log( + '*** sendEventCheckoutValue ***', + amount, + product, + billingPeriod, + sourceCurrency, + ); + void ifQmPermitted(() => { + const sendEventWhenReady = () => { + const sendEventId = 182; + const convertedValue = getCheckoutAnnualValue( + billingPeriod, + amount, + sourceCurrency, + ); + const payload = { + product, + billingPeriod, + }; + if (convertedValue) { + sendEvent( + sendEventId, + false, + Math.round(convertedValue).toString(), + payload, + ); + } + }; + sendEventWhenReadyTrigger(sendEventWhenReady); + }); +} + +// TODO: To be deleted with the 2-step checkout function sendEventContributionCheckoutConversion( amount: number, contributionType: ContributionType, @@ -307,11 +357,11 @@ function sendEventContributionCheckoutConversion( sendEvent(sendEventId, true, Math.round(convertedValue).toString()); } }; - sendEventWhenReadyTrigger(sendEventWhenReady); }); } +// TODO: To be deleted with the 2-step checkout function sendEventContributionCartValue( amount: string, contributionType: ContributionType, @@ -320,7 +370,6 @@ function sendEventContributionCartValue( if (amount === 'other' || Number.isNaN(parseInt(amount))) { return; } - void ifQmPermitted(() => { const sendEventWhenReady = () => { const sendEventId = @@ -336,7 +385,6 @@ function sendEventContributionCartValue( sendEvent(sendEventId, false, Math.round(convertedValue).toString()); } }; - sendEventWhenReadyTrigger(sendEventWhenReady); }); } @@ -456,4 +504,5 @@ export { sendEventPaymentMethodSelected, sendEventConversionPaymentMethod, sendEventAcquisitionDataFromQueryParamEvent, + sendEventCheckoutValue, }; diff --git a/support-frontend/assets/helpers/tracking/quantumMetricHelpers.ts b/support-frontend/assets/helpers/tracking/quantumMetricHelpers.ts index 759bbe3a5c..fd5a8482e8 100644 --- a/support-frontend/assets/helpers/tracking/quantumMetricHelpers.ts +++ b/support-frontend/assets/helpers/tracking/quantumMetricHelpers.ts @@ -49,6 +49,33 @@ export function getSubscriptionAnnualValue( return discountedAnnualPrice; } +export function getCheckoutAnnualValue( + billingPeriod: BillingPeriod, + amount: number, + sourceCurrency: IsoCurrency, +): number | undefined { + const billingMultiplier = { + Annual: 1, + Monthly: 12, + Quarterly: 4, + } as const satisfies Record; + const valueInPence = amount * billingMultiplier[billingPeriod] * 100; + const targetCurrency: IsoCurrency = 'GBP'; + + if (window.QuantumMetricAPI?.isOn()) { + const convertedValue: number = + window.QuantumMetricAPI.currencyConvertFromToValue( + valueInPence, + sourceCurrency, + targetCurrency, + ); + return convertedValue; + } + + return; +} + +// TODO: To be deleted with the 2-step checkout export function getContributionAnnualValue( contributionType: ContributionType, amount: number, diff --git a/support-frontend/assets/pages/[countryGroupId]/checkout.tsx b/support-frontend/assets/pages/[countryGroupId]/checkout.tsx index 25a4ebd8a8..ccf6b75cc6 100644 --- a/support-frontend/assets/pages/[countryGroupId]/checkout.tsx +++ b/support-frontend/assets/pages/[countryGroupId]/checkout.tsx @@ -97,7 +97,10 @@ import { getSupportAbTests, } from 'helpers/tracking/acquisitions'; import { trackComponentClick } from 'helpers/tracking/behaviour'; -import { sendEventPaymentMethodSelected } from 'helpers/tracking/quantumMetric'; +import { + sendEventCheckoutValue, + sendEventPaymentMethodSelected, +} from 'helpers/tracking/quantumMetric'; import { isProd } from 'helpers/urls/url'; import { logException } from 'helpers/utilities/logger'; import type { GeoId } from 'pages/geoIdConfig'; @@ -243,6 +246,17 @@ export function Checkout({ geoId, appConfig }: Props) { ? parseInt(contributionParam, 10) : undefined; + /** + * This is some annoying transformation we need from + * Product API => Contributions work we need to do + */ + const billingPeriod = + ratePlan.billingPeriod === 'Quarter' + ? 'Quarterly' + : ratePlan.billingPeriod === 'Month' + ? 'Monthly' + : 'Annual'; + let promotion; if (productKey === 'Contribution') { /** @@ -279,17 +293,6 @@ export function Checkout({ geoId, appConfig }: Props) { ? appConfig.allProductPrices[productKey] : undefined; - /** - * This is some annoying transformation we need from - * Product API => Contributions work we need to do - */ - const billingPeriod = - ratePlan.billingPeriod === 'Quarter' - ? 'Quarterly' - : ratePlan.billingPeriod === 'Month' - ? 'Monthly' - : 'Annual'; - const getFulfilmentOptions = (productKey: string): FulfilmentOptions => { switch (productKey) { case 'SupporterPlus': @@ -398,6 +401,19 @@ export function Checkout({ geoId, appConfig }: Props) { * a country that doesn't correspond to the countryGroup a product is in. */ const forcedCountry = urlSearchParams.get('country') ?? undefined; + + useEffect(() => { + /** + * Notify QM of checkout value + */ + sendEventCheckoutValue( + payment.finalAmount, + productKey, + billingPeriod, + currencyKey, + ); + }, []); + return ( , ) => void; currencyConvertFromToValue: ( value: number,