Repository: guardian/support-frontend
Pull request #6849: Checkout: Ts&Cs tidy, tests and snapshots
Author: login: paul-daniel-dempsey
Labels: name: Seen-on-PROD
Created: 2025-03-13T09:07:57Z | Merged: 2025-03-24T12:26:53Z

## What are you doing in this PR?

Re-organised all terms and conditions so its predominantly organised by 
props: `productKey`/`ContributionType`/`CountryGroupId`
optional props: `Promotion`/`ThresholdAmount` (currently remaining unchanged as used in tests)

These components have been amended->
1. paymentTsAndCs
2. summaryTsAndCs
3. orderSummaryTsAndCs (previously`contributionsOrderSummaryContainer.tsx`)

Storybook scenarios created for components above
React Testing Library snapshots created for components above

[**Trello Card**](https://trello.com/c/l7aUrNob/1421-onetimecheckout-checkout-tscs-components-improvements)

## Why are you doing this?

To make the terms and conditions easer to maintain, traverse and view.

## How to test
OneTimeCheckout: https://support.thegulocal.com/uk/one-time-checkout
AdLite: https://support.thegulocal.com/uk/checkout?product=GuardianAdLite&ratePlan=Monthly
DigitalEdition: https://support.thegulocal.com/uk/checkout?product=DigitalSubscription&ratePlan=Monthly
Contribution: https://support.thegulocal.com/uk/checkout?product=Contribution&ratePlan=Monthly&contribution=3
SupporterPlus: https://support.thegulocal.com/uk/checkout?product=SupporterPlus&ratePlan=Monthly
Digital+Print: https://support.thegulocal.com/uk/checkout?product=TierThree&ratePlan=DomesticMonthly



Diff:
diff --git a/support-frontend/assets/components/orderSummary/__snapshots__/orderSummaryTsAndCs.test.tsx.snap b/support-frontend/assets/components/orderSummary/__snapshots__/orderSummaryTsAndCs.test.tsx.snap
new file mode 100644
index 0000000000..84e6c1eda8
--- /dev/null
+++ b/support-frontend/assets/components/orderSummary/__snapshots__/orderSummaryTsAndCs.test.tsx.snap
@@ -0,0 +1,73 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Payment Ts&Cs Snapshot comparison orderSummaryTs&Cs render product Contribution for region ANNUAL correctly 1`] = `
+<div>
+  <div
+    class="css-y3m96y-OrderSummaryTsAndCs"
+  >
+    <p>
+      Auto renews every 
+      year
+       until you cancel.
+    </p>
+    <p>
+      Cancel or change your support anytime.
+    </p>
+  </div>
+</div>
+`;
+
+exports[`Payment Ts&Cs Snapshot comparison orderSummaryTs&Cs render product GuardianAdLite for region MONTHLY correctly 1`] = `
+<div>
+  <div
+    class="css-y3m96y-OrderSummaryTsAndCs"
+  >
+    <p>
+      Auto renews every 
+      month
+       until you cancel.
+    </p>
+    <p>
+      Cancel anytime.
+    </p>
+  </div>
+</div>
+`;
+
+exports[`Payment Ts&Cs Snapshot comparison orderSummaryTs&Cs render product SupporterPlus for region MONTHLY correctly 1`] = `
+<div>
+  <div
+    class="css-y3m96y-OrderSummaryTsAndCs"
+  >
+    <p>
+      Auto renews every 
+      month
+       until you cancel.
+    </p>
+    <p>
+      Cancel or change your support anytime. If you cancel within the first 14 days, you will receive a full refund.
+    </p>
+  </div>
+</div>
+`;
+
+exports[`Payment Ts&Cs Snapshot comparison orderSummaryTs&Cs render product TierThree for region MONTHLY correctly 1`] = `
+<div>
+  <div
+    class="css-y3m96y-OrderSummaryTsAndCs"
+  >
+    <p>
+      You’ll pay
+       
+      $37/month for the first 12 months, then $45/month
+       
+      afterwards unless you cancel. Offer only available to new subscribers who do not have an existing subscription with the Guardian.
+    </p>
+    <p>
+      Auto renews every 
+      month
+      . Cancel anytime.
+    </p>
+  </div>
+</div>
+`;
diff --git a/support-frontend/assets/components/orderSummary/contributionsOrderSummary.tsx b/support-frontend/assets/components/orderSummary/contributionsOrderSummary.tsx
index a833e7175f..4013b57117 100644
--- a/support-frontend/assets/components/orderSummary/contributionsOrderSummary.tsx
+++ b/support-frontend/assets/components/orderSummary/contributionsOrderSummary.tsx
@@ -125,22 +125,6 @@ const termsAndConditions = css`
 	}
 `;
 
-const productStartDates = css`
-	display: block;
-	${textSans14};
-	color: #606060;
-	background-color: ${palette.neutral[97]};
-	border-radius: ${space[3]}px;
-	padding: ${space[3]}px;
-	margin-top: ${space[2]}px;
-	${from.desktop} {
-		margin-top: ${space[4]}px;
-	}
-	li + li {
-		margin-top: ${space[2]}px;
-	}
-`;
-
 export type ContributionsOrderSummaryProps = {
 	description: string;
 	amount: number;
@@ -148,11 +132,11 @@ export type ContributionsOrderSummaryProps = {
 	currency: Currency;
 	enableCheckList: boolean;
 	checkListData: BenefitsCheckListData[];
+	tsAndCs: React.ReactNode;
+	startDateTierThree: React.ReactNode;
 	paymentFrequency?: string;
 	onCheckListToggle?: (opening: boolean) => void;
 	headerButton?: React.ReactNode;
-	tsAndCs?: React.ReactNode;
-	tsAndCsTier3?: React.ReactNode;
 	heading?: string;
 	productDescription?: { description: string; frequency: string };
 };
@@ -171,7 +155,7 @@ export function ContributionsOrderSummary({
 	onCheckListToggle,
 	headerButton,
 	tsAndCs,
-	tsAndCsTier3,
+	startDateTierThree,
 	heading,
 	enableCheckList,
 }: ContributionsOrderSummaryProps): JSX.Element {
@@ -222,7 +206,7 @@ export function ContributionsOrderSummary({
 				{hasCheckList && showCheckList && (
 					<>
 						<div css={checklistContainer}>{checkList}</div>
-						{!!tsAndCsTier3 && <ul css={productStartDates}>{tsAndCsTier3}</ul>}
+						{startDateTierThree}
 					</>
 				)}
 			</div>
diff --git a/support-frontend/assets/components/orderSummary/contributionsOrderSummaryContainer.tsx b/support-frontend/assets/components/orderSummary/contributionsOrderSummaryContainer.tsx
deleted file mode 100644
index 3c1ae4a526..0000000000
--- a/support-frontend/assets/components/orderSummary/contributionsOrderSummaryContainer.tsx
+++ /dev/null
@@ -1,82 +0,0 @@
-import { css } from '@emotion/react';
-import { neutral, space } from '@guardian/source/foundations';
-import { type ContributionType } from 'helpers/contributions';
-import type { CountryGroupId } from 'helpers/internationalisation/countryGroup';
-import { productLegal } from 'helpers/legalCopy';
-import type { Promotion } from 'helpers/productPrice/promotions';
-
-const containerSummaryTsCs = css`
-	border-radius: ${space[2]}px;
-	background-color: ${neutral[97]};
-	padding: ${space[3]}px;
-`;
-
-export function getTermsStartDateTier3(startDateTier3: string) {
-	return (
-		<>
-			<li>Your digital benefits will start today.</li>
-			<li>
-				Your Guardian Weekly subscription will start on {startDateTier3}. Please
-				allow 1 to 7 days after your start date for your magazine to arrive,
-				depending on national post services.
-			</li>
-		</>
-	);
-}
-
-export function getTermsConditions(
-	countryGroupId: CountryGroupId,
-	contributionType: ContributionType,
-	productId: string,
-	thresholdAmount: number,
-	promotion?: Promotion,
-) {
-	if (contributionType === 'ONE_OFF') {
-		return;
-	}
-	const period = contributionType === 'MONTHLY' ? 'month' : 'year';
-	const isSupporterPlus = productId === 'SupporterPlus';
-	const isTier3 = productId === 'TierThree';
-	const isAdLite = productId === 'GuardianAdLite';
-
-	if (isSupporterPlus || isTier3) {
-		return (
-			<div css={containerSummaryTsCs}>
-				{promotion && (
-					<p>
-						You’ll pay{' '}
-						{productLegal(
-							countryGroupId,
-							contributionType,
-							'/',
-							thresholdAmount,
-							promotion,
-						)}{' '}
-						afterwards unless you cancel. Offer only available to new
-						subscribers who do not have an existing subscription with the
-						Guardian.
-					</p>
-				)}
-				{isSupporterPlus && (
-					<>
-						<p>Auto renews every {period} until you cancel.</p>
-						<p>
-							Cancel or change your support anytime. If you cancel within the
-							first 14 days, you will receive a full refund.
-						</p>
-					</>
-				)}
-				{isTier3 && <p>Auto renews every {period}. Cancel anytime.</p>}
-			</div>
-		);
-	}
-	const cancelCopy = isAdLite
-		? 'Cancel anytime.'
-		: 'Cancel or change your support anytime.';
-	return (
-		<div css={containerSummaryTsCs}>
-			<p>Auto renews every {period} until you cancel.</p>
-			<p>{cancelCopy}</p>
-		</div>
-	);
-}
diff --git a/support-frontend/assets/components/orderSummary/orderSummaryTsAndCs.test.tsx b/support-frontend/assets/components/orderSummary/orderSummaryTsAndCs.test.tsx
new file mode 100644
index 0000000000..c32eeeed1a
--- /dev/null
+++ b/support-frontend/assets/components/orderSummary/orderSummaryTsAndCs.test.tsx
@@ -0,0 +1,43 @@
+import { render } from '@testing-library/react';
+import type { ContributionType } from 'helpers/contributions';
+import type { CountryGroupId } from 'helpers/internationalisation/countryGroup';
+import type { ActiveProductKey } from 'helpers/productCatalog';
+import type { Promotion } from 'helpers/productPrice/promotions';
+import { OrderSummaryTsAndCs } from './orderSummaryTsAndCs';
+
+describe('Payment Ts&Cs Snapshot comparison', () => {
+	const promotionTierThreUnitedStatesMonthly: Promotion = {
+		name: '$8 off for 12 months',
+		description: 'Tier Three United States Monthly',
+		promoCode: 'TIER_THREE_USA_MONTHLY',
+		numberOfDiscountedPeriods: 12,
+		discountedPrice: 37,
+	};
+	const paymentProductKeys = [
+		['GuardianAdLite', 'MONTHLY', 'GBPCountries', 0],
+		['Contribution', 'ANNUAL', 'AUDCountries', 0],
+		['SupporterPlus', 'MONTHLY', 'GBPCountries', 12],
+		['TierThree', 'MONTHLY', 'UnitedStates', 45],
+	];
+	it.each(paymentProductKeys)(
+		`orderSummaryTs&Cs render product %s for region %s correctly`,
+		(paymentProductKey, contributionType, countryGroupId, amount) => {
+			const promo: Promotion | undefined =
+				paymentProductKey === 'TierThree' &&
+				contributionType === 'MONTHLY' &&
+				countryGroupId === 'UnitedStates'
+					? promotionTierThreUnitedStatesMonthly
+					: undefined;
+			const { container } = render(
+				<OrderSummaryTsAndCs
+					productKey={paymentProductKey as ActiveProductKey}
+					contributionType={contributionType as ContributionType}
+					countryGroupId={countryGroupId as CountryGroupId}
+					thresholdAmount={amount as number}
+					promotion={promo}
+				/>,
+			);
+			expect(container).toMatchSnapshot();
+		},
+	);
+});
diff --git a/support-frontend/assets/components/orderSummary/orderSummaryTsAndCs.tsx b/support-frontend/assets/components/orderSummary/orderSummaryTsAndCs.tsx
new file mode 100644
index 0000000000..6a2e821194
--- /dev/null
+++ b/support-frontend/assets/components/orderSummary/orderSummaryTsAndCs.tsx
@@ -0,0 +1,120 @@
+import { css } from '@emotion/react';
+import {
+	from,
+	neutral,
+	palette,
+	space,
+	textSans14,
+} from '@guardian/source/foundations';
+import { type ContributionType } from 'helpers/contributions';
+import type { CountryGroupId } from 'helpers/internationalisation/countryGroup';
+import { productLegal } from 'helpers/legalCopy';
+import type { ActiveProductKey } from 'helpers/productCatalog';
+import type { Promotion } from 'helpers/productPrice/promotions';
+
+const containerSummaryTsCs = css`
+	border-radius: ${space[2]}px;
+	background-color: ${neutral[97]};
+	padding: ${space[3]}px;
+`;
+const productStartDate = css`
+	display: block;
+	${textSans14};
+	color: #606060;
+	background-color: ${palette.neutral[97]};
+	border-radius: ${space[3]}px;
+	padding: ${space[3]}px;
+	margin-top: ${space[2]}px;
+	${from.desktop} {
+		margin-top: ${space[4]}px;
+	}
+	li + li {
+		margin-top: ${space[2]}px;
+	}
+`;
+
+interface OrderSummaryStartDateProps {
+	startDate: string;
+}
+export function OrderSummaryStartDate({
+	startDate,
+}: OrderSummaryStartDateProps): JSX.Element | null {
+	return (
+		<ul css={productStartDate}>
+			<li>Your digital benefits will start today.</li>
+			<li>
+				Your Guardian Weekly subscription will start on {startDate}. Please
+				allow 1 to 7 days after your start date for your magazine to arrive,
+				depending on national post services.
+			</li>
+		</ul>
+	);
+}
+
+export interface OrderSummaryTsAndCsProps {
+	productKey: ActiveProductKey;
+	contributionType: ContributionType;
+	countryGroupId: CountryGroupId;
+	promotion?: Promotion;
+	thresholdAmount?: number;
+}
+export function OrderSummaryTsAndCs({
+	productKey,
+	contributionType,
+	countryGroupId,
+	promotion,
+	thresholdAmount = 0,
+}: OrderSummaryTsAndCsProps): JSX.Element | null {
+	// Proceeds with RegularContributionType only
+	if (contributionType === 'ONE_OFF') {
+		return null;
+	}
+	const period = contributionType === 'MONTHLY' ? 'month' : 'year';
+	const tierThreeSupporterPlusTsAndCs = (
+		<div css={containerSummaryTsCs}>
+			{promotion && (
+				<p>
+					You’ll pay{' '}
+					{productLegal(
+						countryGroupId,
+						contributionType,
+						'/',
+						thresholdAmount,
+						promotion,
+					)}{' '}
+					afterwards unless you cancel. Offer only available to new subscribers
+					who do not have an existing subscription with the Guardian.
+				</p>
+			)}
+			{productKey === 'SupporterPlus' && (
+				<>
+					<p>Auto renews every {period} until you cancel.</p>
+					<p>
+						Cancel or change your support anytime. If you cancel within the
+						first 14 days, you will receive a full refund.
+					</p>
+				</>
+			)}
+			{productKey === 'TierThree' && (
+				<p>Auto renews every {period}. Cancel anytime.</p>
+			)}
+		</div>
+	);
+	const contributeAdLiteTsAndCs = (
+		<div css={containerSummaryTsCs}>
+			<p>Auto renews every {period} until you cancel.</p>
+			<p>
+				{productKey === 'GuardianAdLite'
+					? 'Cancel anytime.'
+					: 'Cancel or change your support anytime.'}
+			</p>
+		</div>
+	);
+	const orderSummaryTsAndCs: Partial<Record<ActiveProductKey, JSX.Element>> = {
+		GuardianAdLite: contributeAdLiteTsAndCs,
+		Contribution: contributeAdLiteTsAndCs,
+		SupporterPlus: tierThreeSupporterPlusTsAndCs,
+		TierThree: tierThreeSupporterPlusTsAndCs,
+	};
+	return orderSummaryTsAndCs[productKey] ?? null;
+}
diff --git a/support-frontend/assets/components/subscriptionCheckouts/tierThreeTerms.tsx b/support-frontend/assets/components/subscriptionCheckouts/tierThreeTerms.tsx
deleted file mode 100644
index 1053a834dc..0000000000
--- a/support-frontend/assets/components/subscriptionCheckouts/tierThreeTerms.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-import { css } from '@emotion/react';
-import { textSans12 } from '@guardian/source/foundations';
-import { StripeDisclaimer } from 'components/stripe/stripeDisclaimer';
-import { privacyLink, tierThreeTermsLink } from 'helpers/legal';
-import { ManageMyAccountLink } from '../../pages/supporter-plus-landing/components/manageMyAccountLink';
-
-const tierThreeTerms = css`
-	${textSans12};
-	color: #606060;
-	p {
-		margin-top: 10px;
-		a {
-			:visited {
-				color: #606060;
-			}
-		}
-	}
-`;
-
-const termsLink = (linkText: string, url: string) => (
-	<a target="_blank" rel="noopener noreferrer" href={url}>
-		{linkText}
-	</a>
-);
-
-export default function TierThreeTerms(props: {
-	paymentFrequency: 'month' | 'year';
-}): JSX.Element {
-	const paymentFrequencyName =
-		props.paymentFrequency === 'year' ? 'annual' : 'monthly';
-	const productName = 'Digital + print';
-
-	return (
-		<div css={tierThreeTerms}>
-			<p>
-				By signing up, you are taking out a {productName} subscription. Your{' '}
-				{productName} subscription will auto-renew each {props.paymentFrequency}{' '}
-				unless cancelled. Your first payment will be taken on the publication
-				date of your first Guardian Weekly magazine (as shown in the checkout)
-				but you will start to receive your digital benefits when you sign up.
-				Unless you cancel, subsequent {paymentFrequencyName} payments will be
-				taken on this date using your chosen payment method. You can cancel your
-				Digital + print subscription at any time before your next renewal date.
-				If you cancel your {productName} subscription within 14 days of signing
-				up, your subscription will stop immediately and we will not take the
-				first payment from you. Cancellation of your subscription after 14 days
-				will take effect at the end of your current {paymentFrequencyName}{' '}
-				payment period. To cancel go to&nbsp;
-				{ManageMyAccountLink} or see our {productName}{' '}
-				{termsLink('Terms', tierThreeTermsLink)}.
-			</p>
-			<p>
-				By proceeding, you are agreeing to the {productName}{' '}
-				{termsLink('Terms', tierThreeTermsLink)}.
-			</p>
-			<p>
-				To find out what personal data we collect and how we use it, please
-				visit our {termsLink('Privacy Policy', privacyLink)}.
-			</p>
-			<p>
-				<StripeDisclaimer />
-			</p>
-		</div>
-	);
-}
diff --git a/support-frontend/assets/pages/[countryGroupId]/components/checkoutComponent.tsx b/support-frontend/assets/pages/[countryGroupId]/components/checkoutComponent.tsx
index a8756a4ffa..98e7bf212a 100644
--- a/support-frontend/assets/pages/[countryGroupId]/components/checkoutComponent.tsx
+++ b/support-frontend/assets/pages/[countryGroupId]/components/checkoutComponent.tsx
@@ -26,9 +26,9 @@ import DirectDebitForm from 'components/directDebit/directDebitForm/directDebitF
 import { LoadingOverlay } from 'components/loadingOverlay/loadingOverlay';
 import { ContributionsOrderSummary } from 'components/orderSummary/contributionsOrderSummary';
 import {
-	getTermsConditions,
-	getTermsStartDateTier3,
-} from 'components/orderSummary/contributionsOrderSummaryContainer';
+	OrderSummaryStartDate,
+	OrderSummaryTsAndCs,
+} from 'components/orderSummary/orderSummaryTsAndCs';
 import { DefaultPaymentButton } from 'components/paymentButton/defaultPaymentButton';
 import { paymentMethodData } from 'components/paymentMethodSelector/paymentMethodData';
 import { PayPalButton } from 'components/payPalPaymentButton/payPalButton';
@@ -587,20 +587,22 @@ export function CheckoutComponent({
 							);
 						}}
 						enableCheckList={true}
-						tsAndCsTier3={
-							productKey === 'TierThree'
-								? getTermsStartDateTier3(
-										formatUserDate(getTierThreeDeliveryDate()),
-								  )
-								: null
+						startDateTierThree={
+							productKey === 'TierThree' ? (
+								<OrderSummaryStartDate
+									startDate={formatUserDate(getTierThreeDeliveryDate())}
+								/>
+							) : null
+						}
+						tsAndCs={
+							<OrderSummaryTsAndCs
+								productKey={productKey}
+								contributionType={contributionType}
+								countryGroupId={countryGroupId}
+								thresholdAmount={thresholdAmount}
+								promotion={promotion}
+							/>
 						}
-						tsAndCs={getTermsConditions(
-							countryGroupId,
-							contributionType,
-							productFields.productType,
-							thresholdAmount,
-							promotion,
-						)}
 						headerButton={
 							<BackButton path={returnToLandingPage} buttonText={'Change'} />
 						}
@@ -1169,11 +1171,10 @@ export function CheckoutComponent({
 							</RadioGroup>
 						</FormSection>
 						<SummaryTsAndCs
+							productKey={productKey}
 							contributionType={contributionType}
 							currency={currencyKey}
 							amount={originalAmount}
-							productKey={productKey}
-							promotion={promotion}
 						/>
 						<div
 							css={css`
diff --git a/support-frontend/assets/pages/[countryGroupId]/components/oneTimeCheckoutComponent.tsx b/support-frontend/assets/pages/[countryGroupId]/components/oneTimeCheckoutComponent.tsx
index 2170416afe..96fdc06904 100644
--- a/support-frontend/assets/pages/[countryGroupId]/components/oneTimeCheckoutComponent.tsx
+++ b/support-frontend/assets/pages/[countryGroupId]/components/oneTimeCheckoutComponent.tsx
@@ -79,7 +79,7 @@ import { CoverTransactionCost } from 'pages/supporter-plus-landing/components/co
 import { FinePrint } from 'pages/supporter-plus-landing/components/finePrint';
 import { GuardianTsAndCs } from 'pages/supporter-plus-landing/components/guardianTsAndCs';
 import { PatronsMessage } from 'pages/supporter-plus-landing/components/patronsMessage';
-import { TsAndCsFooterLinks } from 'pages/supporter-plus-landing/components/paymentTsAndCs';
+import { FooterTsAndCs } from 'pages/supporter-plus-landing/components/paymentTsAndCs';
 import { countryGroups } from '../../../helpers/internationalisation/countryGroup';
 import {
 	updateAbandonedBasketCookie,
@@ -876,9 +876,9 @@ export function OneTimeCheckoutComponent({
 						)}
 						<div css={tcContainer}>
 							<FinePrint mobileTheme={'dark'}>
-								<TsAndCsFooterLinks
+								<FooterTsAndCs
+									productKey={'OneTimeContribution'}
 									countryGroupId={countryGroupId}
-									productKey="OneTimeContribution"
 								/>
 							</FinePrint>
 						</div>
diff --git a/support-frontend/assets/pages/supporter-plus-landing/components/TsAndCsRenewal.tsx b/support-frontend/assets/pages/supporter-plus-landing/components/TsAndCsRenewal.tsx
deleted file mode 100644
index 775f58ce05..0000000000
--- a/support-frontend/assets/pages/supporter-plus-landing/components/TsAndCsRenewal.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import type { ContributionType } from 'helpers/contributions';
-import {
-	getDateWithOrdinal,
-	getLongMonth,
-} from 'helpers/utilities/dateFormatting';
-
-export default function TsAndCsRenewal({
-	contributionType,
-}: {
-	contributionType: ContributionType;
-}): JSX.Element {
-	const today = new Date();
-	if (contributionType === 'ANNUAL') {
-		return (
-			<>
-				on the {getDateWithOrdinal(today)} day of {getLongMonth(today)} every{' '}
-				year
-			</>
-		);
-	}
-	return <>on the {getDateWithOrdinal(today)} day of every month</>;
-}
diff --git a/support-frontend/assets/pages/supporter-plus-landing/components/__snapshots__/paymentTsAndCs.test.tsx.snap b/support-frontend/assets/pages/supporter-plus-landing/components/__snapshots__/paymentTsAndCs.test.tsx.snap
index 4e70ef7464..2fd3d6640e 100644
--- a/support-frontend/assets/pages/supporter-plus-landing/components/__snapshots__/paymentTsAndCs.test.tsx.snap
+++ b/support-frontend/assets/pages/supporter-plus-landing/components/__snapshots__/paymentTsAndCs.test.tsx.snap
@@ -1,28 +1,30 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product Contribution for region UnitedStates correctly 1`] = `
+exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product Contribution for region ANNUAL correctly 1`] = `
 <div>
   <div
-    class="css-1002frk-PaymentTsAndCs"
+    class="css-ki6xpt-PaymentTsAndCs"
   >
     <div
       class="css-1w63ndr-FinePrint"
     >
       <div
-        class="css-mhzvj4-TsAndCsFooterLinks"
+        class="css-15t9qdk-FooterTsAndCs"
       >
         By proceeding, you are agreeing to 
         our
          
         <a
-          href="https://www.theguardian.com/info/2016/apr/07/us-contribution-terms-and-conditions"
+          href="https://www.theguardian.com/info/2016/apr/08/australia-contribution-terms-and-conditions"
+          rel="noopener noreferrer"
+          target="_blank"
         >
           Terms and Conditions
         </a>
         .
          
         <p
-          class="css-mhzvj4-TsAndCsFooterLinks"
+          class="css-15t9qdk-FooterTsAndCs"
         >
           To find out what personal data we collect and how we use it, please visit our 
           <a
@@ -33,7 +35,7 @@ exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product Contribut
           .
         </p>
         <p
-          class="css-mhzvj4-TsAndCsFooterLinks"
+          class="css-15t9qdk-FooterTsAndCs"
         >
           All card payments are powered by Stripe. Read the Stripe
            
@@ -60,10 +62,10 @@ exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product Contribut
 </div>
 `;
 
-exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product DigitalSubscription for region GBPCountries correctly 1`] = `
+exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product DigitalSubscription for region MONTHLY correctly 1`] = `
 <div>
   <div
-    class="css-1002frk-PaymentTsAndCs"
+    class="css-ki6xpt-PaymentTsAndCs"
   >
     <div
       class="css-1w63ndr-FinePrint"
@@ -86,20 +88,22 @@ exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product DigitalSu
         .
       </div>
       <div
-        class="css-mhzvj4-TsAndCsFooterLinks"
+        class="css-15t9qdk-FooterTsAndCs"
       >
         By proceeding, you are agreeing to 
         our
          
         <a
           href="https://www.theguardian.com/info/2016/apr/04/contribution-terms-and-conditions"
+          rel="noopener noreferrer"
+          target="_blank"
         >
           Terms and Conditions
         </a>
         .
          
         <p
-          class="css-mhzvj4-TsAndCsFooterLinks"
+          class="css-15t9qdk-FooterTsAndCs"
         >
           To find out what personal data we collect and how we use it, please visit our 
           <a
@@ -110,7 +114,7 @@ exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product DigitalSu
           .
         </p>
         <p
-          class="css-mhzvj4-TsAndCsFooterLinks"
+          class="css-15t9qdk-FooterTsAndCs"
         >
           All card payments are powered by Stripe. Read the Stripe
            
@@ -137,10 +141,10 @@ exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product DigitalSu
 </div>
 `;
 
-exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product GuardianAdLite for region GBPCountries correctly 1`] = `
+exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product GuardianAdLite for region ANNUAL correctly 1`] = `
 <div>
   <div
-    class="css-1002frk-PaymentTsAndCs"
+    class="css-ki6xpt-PaymentTsAndCs"
   >
     <div
       class="css-1w63ndr-FinePrint"
@@ -148,7 +152,7 @@ exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product GuardianA
       <div>
         Your Guardian Ad-Lite subscription will auto-renew each
          
-        month
+        year
          unless cancelled. Your first payment will be taken on day 15 after signing up but you will start to receive your Guardian Ad-Lite benefits when you sign up. Unless you cancel, subsequent monthly payments will be taken on this date using your chosen payment method. You can cancel your subscription at any time before your next renewal date. If you cancel your Guardian Ad-Lite subscription within 14 days of signing up, your subscription will stop immediately and we will not take the first payment from you. Cancellation of your subscription after 14 days will take effect at the end of your current monthly payment period. To cancel, go to
          
         <a
@@ -160,26 +164,30 @@ exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product GuardianA
          
         <a
           href="https://www.theguardian.com/guardian-ad-lite-tcs"
+          rel="noopener noreferrer"
+          target="_blank"
         >
           Terms
         </a>
         .
       </div>
       <div
-        class="css-mhzvj4-TsAndCsFooterLinks"
+        class="css-15t9qdk-FooterTsAndCs"
       >
         By proceeding, you are agreeing to 
         the Guardian Ad-Lite
          
         <a
           href="https://www.theguardian.com/guardian-ad-lite-tcs"
+          rel="noopener noreferrer"
+          target="_blank"
         >
           Terms
         </a>
         .
          
         <p
-          class="css-mhzvj4-TsAndCsFooterLinks"
+          class="css-15t9qdk-FooterTsAndCs"
         >
           To find out what personal data we collect and how we use it, please visit our 
           <a
@@ -190,7 +198,7 @@ exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product GuardianA
           .
         </p>
         <p
-          class="css-mhzvj4-TsAndCsFooterLinks"
+          class="css-15t9qdk-FooterTsAndCs"
         >
           All card payments are powered by Stripe. Read the Stripe
            
@@ -217,29 +225,31 @@ exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product GuardianA
 </div>
 `;
 
-exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product OneTimeContribution for region AUDCountries correctly 1`] = `
+exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product OneTimeContribution for region MONTHLY correctly 1`] = `
 <div>
   <div
-    class="css-1002frk-PaymentTsAndCs"
+    class="css-ki6xpt-PaymentTsAndCs"
   >
     <div
       class="css-1w63ndr-FinePrint"
     >
       <div
-        class="css-mhzvj4-TsAndCsFooterLinks"
+        class="css-15t9qdk-FooterTsAndCs"
       >
         By proceeding, you are agreeing to 
         our
          
         <a
-          href="https://www.theguardian.com/info/2016/apr/08/australia-contribution-terms-and-conditions"
+          href="https://www.theguardian.com/info/2016/apr/07/us-contribution-terms-and-conditions"
+          rel="noopener noreferrer"
+          target="_blank"
         >
           Terms and Conditions
         </a>
         .
          
         <p
-          class="css-mhzvj4-TsAndCsFooterLinks"
+          class="css-15t9qdk-FooterTsAndCs"
         >
           To find out what personal data we collect and how we use it, please visit our 
           <a
@@ -250,7 +260,7 @@ exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product OneTimeCo
           .
         </p>
         <p
-          class="css-mhzvj4-TsAndCsFooterLinks"
+          class="css-15t9qdk-FooterTsAndCs"
         >
           All card payments are powered by Stripe. Read the Stripe
            
@@ -277,10 +287,10 @@ exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product OneTimeCo
 </div>
 `;
 
-exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product SupporterPlus for region GBPCountries correctly 1`] = `
+exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product SupporterPlus for region MONTHLY correctly 1`] = `
 <div>
   <div
-    class="css-1002frk-PaymentTsAndCs"
+    class="css-ki6xpt-PaymentTsAndCs"
   >
     <div
       class="css-1w63ndr-FinePrint"
@@ -291,20 +301,19 @@ exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product Supporter
         £12 per month
         , you will receive the 
         All-access digital
-         benefits on a subscription basis. If you increase your payments per
-         
+         benefits on a subscription basis. If you increase your payments per 
         month
-        , these additional amounts will be separate 
+        , these additional amounts will be separate
+         
         monthly
          voluntary financial contributions to the Guardian. The 
         All-access digital
-         subscription and any contributions will auto-renew each
-         
+         subscription and any contributions will auto-renew each 
         month
-        . You will be charged the subscription and contribution amounts using your chosen payment method at each renewal unless you cancel. You can cancel your subscription or change your contributions at any time before your next renewal date. If you cancel within 14 days of taking out a 
-        All-access digital
+        . You will be charged the subscription and contribution amounts using your chosen payment method at each renewal unless you cancel. You can cancel your subscription or change your contributions at any time before your next renewal date. If you cancel within 14 days of taking out a
          
-        subscription, you’ll receive a full refund (including of any contributions) and your subscription and any contribution will stop immediately. Cancellation of your subscription (which will also cancel any contribution) or cancellation of your contribution made after 14 days will take effect at the end of your current
+        All-access digital
+         subscription, you’ll receive a full refund (including of any contributions) and your subscription and any contribution will stop immediately. Cancellation of your subscription (which will also cancel any contribution) or cancellation of your contribution made after 14 days will take effect at the end of your current
          
         monthly
          payment period. To cancel, go to
@@ -314,29 +323,34 @@ exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product Supporter
         >
           Manage My Account
         </a>
-         or see our 
+         or see our
+         
         <a
           href="https://www.theguardian.com/info/2022/oct/28/the-guardian-supporter-plus-terms-and-conditions"
+          rel="noopener noreferrer"
+          target="_blank"
         >
           Terms
         </a>
         .
       </div>
       <div
-        class="css-mhzvj4-TsAndCsFooterLinks"
+        class="css-15t9qdk-FooterTsAndCs"
       >
         By proceeding, you are agreeing to 
         our
          
         <a
           href="https://www.theguardian.com/info/2022/oct/28/the-guardian-supporter-plus-terms-and-conditions"
+          rel="noopener noreferrer"
+          target="_blank"
         >
           Terms and Conditions
         </a>
         .
          
         <p
-          class="css-mhzvj4-TsAndCsFooterLinks"
+          class="css-15t9qdk-FooterTsAndCs"
         >
           To find out what personal data we collect and how we use it, please visit our 
           <a
@@ -347,7 +361,7 @@ exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product Supporter
           .
         </p>
         <p
-          class="css-mhzvj4-TsAndCsFooterLinks"
+          class="css-15t9qdk-FooterTsAndCs"
         >
           All card payments are powered by Stripe. Read the Stripe
            
@@ -374,54 +388,31 @@ exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product Supporter
 </div>
 `;
 
-exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product TierThree for region GBPCountries correctly 1`] = `
+exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product TierThree for region MONTHLY correctly 1`] = `
 <div>
   <div
-    class="css-1002frk-PaymentTsAndCs"
+    class="css-ki6xpt-PaymentTsAndCs"
   >
     <div
       class="css-1w63ndr-FinePrint"
     >
-      <div
-        class="css-7jiaf8-TierThreeTerms"
-      >
+      <div>
         <p>
-          By signing up, you are taking out a 
-          Digital + print
-           subscription. Your
+          By signing up, you are taking out a Digital + print subscription. Your Digital + print subscription will auto-renew each
            
-          Digital + print
-           subscription will auto-renew each 
           month
-           
-          unless cancelled. Your first payment will be taken on the publication date of your first Guardian Weekly magazine (as shown in the checkout) but you will start to receive your digital benefits when you sign up. Unless you cancel, subsequent 
-          monthly
-           payments will be taken on this date using your chosen payment method. You can cancel your Digital + print subscription at any time before your next renewal date. If you cancel your 
-          Digital + print
-           subscription within 14 days of signing up, your subscription will stop immediately and we will not take the first payment from you. Cancellation of your subscription after 14 days will take effect at the end of your current 
+           unless cancelled. Your first payment will be taken on the publication date of your first Guardian Weekly magazine (as shown in the checkout) but you will start to receive your digital benefits when you sign up. Unless you cancel, subsequent 
           monthly
+           payments will be taken on this date using your chosen payment method. You can cancel your Digital + print subscription at any time before your next renewal date. If you cancel your Digital + print subscription within 14 days of signing up, your subscription will stop immediately and we will not take the first payment from you. Cancellation of your subscription after 14 days will take effect at the end of your current
            
-          payment period. To cancel go to 
+          monthly
+           payment period. To cancel go to 
           <a
             href="https://manage.theguardian.com/subscriptions"
           >
             Manage My Account
           </a>
-           or see our 
-          Digital + print
-           
-          <a
-            href="https://www.theguardian.com/info/article/2024/jul/19/digital-print-terms-and-conditions"
-            rel="noopener noreferrer"
-            target="_blank"
-          >
-            Terms
-          </a>
-          .
-        </p>
-        <p>
-          By proceeding, you are agreeing to the 
-          Digital + print
+           or see our Digital + print
            
           <a
             href="https://www.theguardian.com/info/article/2024/jul/19/digital-print-terms-and-conditions"
@@ -432,18 +423,36 @@ exports[`Payment Ts&Cs Snapshot comparison paymentTs&Cs render product TierThree
           </a>
           .
         </p>
-        <p>
+      </div>
+      <div
+        class="css-15t9qdk-FooterTsAndCs"
+      >
+        By proceeding, you are agreeing to 
+        Digital + print
+         
+        <a
+          href="https://www.theguardian.com/info/article/2024/jul/19/digital-print-terms-and-conditions"
+          rel="noopener noreferrer"
+          target="_blank"
+        >
+          Terms
+        </a>
+        .
+         
+        <p
+          class="css-15t9qdk-FooterTsAndCs"
+        >
           To find out what personal data we collect and how we use it, please visit our 
           <a
             href="https://www.theguardian.com/help/privacy-policy"
-            rel="noopener noreferrer"
-            target="_blank"
           >
             Privacy Policy
           </a>
           .
         </p>
-        <p>
+        <p
+          class="css-15t9qdk-FooterTsAndCs"
+        >
           All card payments are powered by Stripe. Read the Stripe
            
           <a
diff --git a/support-frontend/assets/pages/supporter-plus-landing/components/__snapshots__/summaryTsAndCs.test.tsx.snap b/support-frontend/assets/pages/supporter-plus-landing/components/__snapshots__/summaryTsAndCs.test.tsx.snap
index 9d4293826d..b54cb3733a 100644
--- a/support-frontend/assets/pages/supporter-plus-landing/components/__snapshots__/summaryTsAndCs.test.tsx.snap
+++ b/support-frontend/assets/pages/supporter-plus-landing/components/__snapshots__/summaryTsAndCs.test.tsx.snap
@@ -1,95 +1,129 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`Summary Ts&Cs Snapshot comparison summaryTs&Cs render product Contribution correctly 1`] = `
+exports[`Summary Ts&Cs Snapshot comparison summaryTs&Cs for Contribution With contributionType ANNUALY renders correctly 1`] = `
 <div>
   <div
-    class="css-1e4uwg6-SummaryTsAndCs"
+    class="css-mlt1i5-SummaryTsAndCs"
   >
-    <div>
-      We will attempt to take payment
-       of £0
-      ,
-       
-      <div>
-        on the first day of every month
-      </div>
-      , from now until you cancel your payment. Payments may take up to 6 days to be recorded in your bank account. You can change how much you give or cancel your payment at any time.
-    </div>
+    We will attempt to take payment of 
+    £0
+    ,
+     
+    on the first day of every month
+    , from now until you cancel your payment. Payments may take up to 6 days to be recorded in your bank account. You can change how much you give or cancel your payment at any time.
   </div>
 </div>
 `;
 
-exports[`Summary Ts&Cs Snapshot comparison summaryTs&Cs render product DigitalSubscription correctly 1`] = `<div />`;
+exports[`Summary Ts&Cs Snapshot comparison summaryTs&Cs for Contribution With contributionType MONTHLY renders correctly 1`] = `
+<div>
+  <div
+    class="css-mlt1i5-SummaryTsAndCs"
+  >
+    We will attempt to take payment of 
+    £0
+    ,
+     
+    on the first day of every month
+    , from now until you cancel your payment. Payments may take up to 6 days to be recorded in your bank account. You can change how much you give or cancel your payment at any time.
+  </div>
+</div>
+`;
+
+exports[`Summary Ts&Cs Snapshot comparison summaryTs&Cs for DigitalSubscription With contributionType MONTHLY renders correctly 1`] = `<div />`;
+
+exports[`Summary Ts&Cs Snapshot comparison summaryTs&Cs for GuardianAdLite With contributionType ANNUALY renders correctly 1`] = `
+<div>
+  <div
+    class="css-mlt1i5-SummaryTsAndCs"
+  >
+    The 
+    Guardian Ad-Lite
+     subscription
+     will auto-renew each
+     
+    year
+    . You will be charged the subscription amount using your chosen payment method at each renewal, at the rate then in effect, unless you cancel.
+  </div>
+</div>
+`;
+
+exports[`Summary Ts&Cs Snapshot comparison summaryTs&Cs for GuardianAdLite With contributionType MONTHLY renders correctly 1`] = `
+<div>
+  <div
+    class="css-mlt1i5-SummaryTsAndCs"
+  >
+    The 
+    Guardian Ad-Lite
+     subscription
+     will auto-renew each
+     
+    month
+    . You will be charged the subscription amount using your chosen payment method at each renewal, at the rate then in effect, unless you cancel.
+  </div>
+</div>
+`;
+
+exports[`Summary Ts&Cs Snapshot comparison summaryTs&Cs for OneTimeContribution With contributionType MONTHLY renders correctly 1`] = `<div />`;
 
-exports[`Summary Ts&Cs Snapshot comparison summaryTs&Cs render product GuardianAdLite correctly 1`] = `
+exports[`Summary Ts&Cs Snapshot comparison summaryTs&Cs for SupporterPlus With contributionType ANNUALY renders correctly 1`] = `
 <div>
   <div
-    class="css-1e4uwg6-SummaryTsAndCs"
+    class="css-mlt1i5-SummaryTsAndCs"
   >
-    <div>
-      The 
-      Guardian Ad-Lite
-       subscription
-       will auto-renew each
-       
-      month
-      . You will be charged the subscription amount using your chosen payment method at each renewal, at the rate then in effect, unless you cancel.
-    </div>
+    The 
+    All-access digital
+     subscription and any contribution will auto-renew each 
+    year
+    . You will be charged the subscription and contribution amounts using your chosen payment method at each renewal, at the rate then in effect, unless you cancel.
   </div>
 </div>
 `;
 
-exports[`Summary Ts&Cs Snapshot comparison summaryTs&Cs render product OneTimeContribution correctly 1`] = `
+exports[`Summary Ts&Cs Snapshot comparison summaryTs&Cs for SupporterPlus With contributionType MONTHLY renders correctly 1`] = `
 <div>
   <div
-    class="css-1e4uwg6-SummaryTsAndCs"
+    class="css-mlt1i5-SummaryTsAndCs"
   >
-    <div>
-      We will attempt to take payment
-       of £0
-      ,
-       
-      <div>
-        on the first day of every month
-      </div>
-      , from now until you cancel your payment. Payments may take up to 6 days to be recorded in your bank account. You can change how much you give or cancel your payment at any time.
-    </div>
+    The 
+    All-access digital
+     subscription and any contribution will auto-renew each 
+    month
+    . You will be charged the subscription and contribution amounts using your chosen payment method at each renewal, at the rate then in effect, unless you cancel.
   </div>
 </div>
 `;
 
-exports[`Summary Ts&Cs Snapshot comparison summaryTs&Cs render product SupporterPlus correctly 1`] = `
+exports[`Summary Ts&Cs Snapshot comparison summaryTs&Cs for TierThree With contributionType ANNUALY renders correctly 1`] = `
 <div>
   <div
-    class="css-1e4uwg6-SummaryTsAndCs"
+    class="css-mlt1i5-SummaryTsAndCs"
   >
-    <div>
-      The 
-      All-access digital
-       subscription and any contribution will auto-renew each
-       
-      month
-      . You will be charged the subscription and contribution amounts using your chosen payment method at each renewal, at the rate then in effect, unless you cancel.
-    </div>
+    The 
+    Digital + print
+     subscription
+    s
+     will auto-renew each
+     
+    year
+    . You will be charged the subscription amount using your chosen payment method at each renewal, at the rate then in effect, unless you cancel.
   </div>
 </div>
 `;
 
-exports[`Summary Ts&Cs Snapshot comparison summaryTs&Cs render product TierThree correctly 1`] = `
+exports[`Summary Ts&Cs Snapshot comparison summaryTs&Cs for TierThree With contributionType MONTHLY renders correctly 1`] = `
 <div>
   <div
-    class="css-1e4uwg6-SummaryTsAndCs"
+    class="css-mlt1i5-SummaryTsAndCs"
   >
-    <div>
-      The 
-      Digital + print
-       subscription
-      s
-       will auto-renew each
-       
-      month
-      . You will be charged the subscription amount using your chosen payment method at each renewal, at the rate then in effect, unless you cancel.
-    </div>
+    The 
+    Digital + print
+     subscription
+    s
+     will auto-renew each
+     
+    month
+    . You will be charged the subscription amount using your chosen payment method at each renewal, at the rate then in effect, unless you cancel.
   </div>
 </div>
 `;
diff --git a/support-frontend/assets/pages/supporter-plus-landing/components/paymentTsAndCs.test.tsx b/support-frontend/assets/pages/supporter-plus-landing/components/paymentTsAndCs.test.tsx
index ffa90e9d51..adf49224c8 100644
--- a/support-frontend/assets/pages/supporter-plus-landing/components/paymentTsAndCs.test.tsx
+++ b/support-frontend/assets/pages/supporter-plus-landing/components/paymentTsAndCs.test.tsx
@@ -1,26 +1,42 @@
 import { render } from '@testing-library/react';
+import type { ContributionType } from 'helpers/contributions';
 import type { CountryGroupId } from 'helpers/internationalisation/countryGroup';
 import type { ActiveProductKey } from 'helpers/productCatalog';
+import type { Promotion } from 'helpers/productPrice/promotions';
 import { PaymentTsAndCs } from './paymentTsAndCs';
 
 describe('Payment Ts&Cs Snapshot comparison', () => {
+	const promotionTierThreUnitedStatesMonthly: Promotion = {
+		name: '$8 off for 12 months',
+		description: 'Tier Three United States Monthly',
+		promoCode: 'TIER_THREE_USA_MONTHLY',
+		numberOfDiscountedPeriods: 12,
+		discountedPrice: 37,
+	};
 	const paymentProductKeys = [
-		['Contribution', 'UnitedStates'],
-		['SupporterPlus', 'GBPCountries'],
-		['TierThree', 'GBPCountries'],
-		['OneTimeContribution', 'AUDCountries'],
-		['GuardianAdLite', 'GBPCountries'],
-		['DigitalSubscription', 'GBPCountries'],
+		['GuardianAdLite', 'ANNUAL', 'GBPCountries', 0],
+		['DigitalSubscription', 'MONTHLY', 'GBPCountries', 0],
+		['OneTimeContribution', 'MONTHLY', 'UnitedStates', 0],
+		['Contribution', 'ANNUAL', 'AUDCountries', 0],
+		['SupporterPlus', 'MONTHLY', 'GBPCountries', 12],
+		['TierThree', 'MONTHLY', 'UnitedStates', 45],
 	];
 	it.each(paymentProductKeys)(
 		`paymentTs&Cs render product %s for region %s correctly`,
-		(paymentProductKey, countryGroupId) => {
+		(paymentProductKey, contributionType, countryGroupId, amount) => {
+			const promo: Promotion | undefined =
+				paymentProductKey === 'TierThree' &&
+				contributionType === 'MONTHLY' &&
+				countryGroupId === 'UnitedStates'
+					? promotionTierThreUnitedStatesMonthly
+					: undefined;
 			const { container } = render(
 				<PaymentTsAndCs
-					contributionType={'MONTHLY'}
+					contributionType={contributionType as ContributionType}
 					countryGroupId={countryGroupId as CountryGroupId}
 					productKey={paymentProductKey as ActiveProductKey}
-					thresholdAmount={12}
+					thresholdAmount={amount as number}
+					promotion={promo}
 				/>,
 			);
 			expect(container).toMatchSnapshot();
diff --git a/support-frontend/assets/pages/supporter-plus-landing/components/paymentTsAndCs.tsx b/support-frontend/assets/pages/supporter-plus-landing/components/paymentTsAndCs.tsx
index 783978604d..d0a5c17683 100644
--- a/support-frontend/assets/pages/supporter-plus-landing/components/paymentTsAndCs.tsx
+++ b/support-frontend/assets/pages/supporter-plus-landing/components/paymentTsAndCs.tsx
@@ -1,8 +1,6 @@
-import type { SerializedStyles } from '@emotion/react';
 import { css } from '@emotion/react';
 import { neutral, textSans12 } from '@guardian/source/foundations';
 import { StripeDisclaimer } from 'components/stripe/stripeDisclaimer';
-import TierThreeTerms from 'components/subscriptionCheckouts/tierThreeTerms';
 import type {
 	ContributionType,
 	RegularContributionType,
@@ -13,6 +11,7 @@ import {
 	guardianAdLiteTermsLink,
 	privacyLink,
 	supporterPlusTermsLink,
+	tierThreeTermsLink,
 } from 'helpers/legal';
 import { productLegal } from 'helpers/legalCopy';
 import {
@@ -20,7 +19,6 @@ import {
 	productCatalogDescription,
 } from 'helpers/productCatalog';
 import type { Promotion } from 'helpers/productPrice/promotions';
-import type { FinePrintTheme } from './finePrint';
 import { FinePrint } from './finePrint';
 import { ManageMyAccountLink } from './manageMyAccountLink';
 
@@ -31,58 +29,62 @@ const marginTop = css`
 const container = css`
 	${textSans12};
 	color: ${neutral[20]};
-
 	& a {
 		color: ${neutral[20]};
+		:visited {
+			color: ${neutral[20]};
+		}
 	}
 `;
 
-export interface PaymentTsAndCsProps {
-	productKey: ActiveProductKey;
-	contributionType: ContributionType;
-	countryGroupId: CountryGroupId;
-	promotion?: Promotion;
-	thresholdAmount?: number;
-	mobileTheme?: FinePrintTheme;
-	cssOverrides?: SerializedStyles;
-}
-
-const termsSupporterPlus = (linkText: string) => (
-	<a href={supporterPlusTermsLink}>{linkText}</a>
-);
-const termsGuardianAdLite = (linkText: string) => (
-	<a href={guardianAdLiteTermsLink}>{linkText}</a>
+const termsLink = (linkText: string, url: string) => (
+	<a target="_blank" rel="noopener noreferrer" href={url}>
+		{linkText}
+	</a>
 );
 
 const frequencySingular = (contributionType: ContributionType) =>
 	contributionType === 'MONTHLY' ? 'month' : 'year';
+const frequencyPlural = (contributionType: ContributionType) =>
+	contributionType === 'MONTHLY' ? 'monthly' : 'annual';
 
-export function TsAndCsFooterLinks({
-	countryGroupId,
+export function FooterTsAndCs({
 	productKey,
+	countryGroupId,
 }: {
-	countryGroupId: CountryGroupId;
 	productKey: ActiveProductKey;
+	countryGroupId: CountryGroupId;
 }) {
-	const inAdLite = productKey === 'GuardianAdLite';
-	const inSupporterPlusOrTierThree =
-		productKey === 'SupporterPlus' || productKey === 'TierThree';
 	const privacy = <a href={privacyLink}>Privacy Policy</a>;
-
-	const termsContributions = (
-		<a href={contributionsTermsLinks[countryGroupId]}>Terms and Conditions</a>
-	);
-
-	const terms = inSupporterPlusOrTierThree
-		? termsSupporterPlus('Terms and Conditions')
-		: inAdLite
-		? termsGuardianAdLite('Terms')
-		: termsContributions;
-	const productNameSummary = inAdLite ? 'the Guardian Ad-Lite' : 'our';
-
+	const getProductNameSummary = (): string => {
+		switch (productKey) {
+			case 'GuardianAdLite':
+				return 'the Guardian Ad-Lite';
+			case 'TierThree':
+				return 'Digital + print';
+			default:
+				return 'our';
+		}
+	};
+	const getProductTerms = (): JSX.Element => {
+		switch (productKey) {
+			case 'GuardianAdLite':
+				return termsLink('Terms', guardianAdLiteTermsLink);
+			case 'SupporterPlus':
+				return termsLink('Terms and Conditions', supporterPlusTermsLink);
+			case 'TierThree':
+				return termsLink('Terms', tierThreeTermsLink);
+			default:
+				return termsLink(
+					'Terms and Conditions',
+					contributionsTermsLinks[countryGroupId],
+				);
+		}
+	};
 	return (
 		<div css={marginTop}>
-			By proceeding, you are agreeing to {productNameSummary} {terms}.{' '}
+			By proceeding, you are agreeing to {getProductNameSummary()}{' '}
+			{getProductTerms()}.{' '}
 			<p css={marginTop}>
 				To find out what personal data we collect and how we use it, please
 				visit our {privacy}.
@@ -94,95 +96,39 @@ export function TsAndCsFooterLinks({
 	);
 }
 
+export interface PaymentTsAndCsProps {
+	productKey: ActiveProductKey;
+	contributionType: ContributionType;
+	countryGroupId: CountryGroupId;
+	promotion?: Promotion;
+	thresholdAmount?: number;
+}
 export function PaymentTsAndCs({
 	productKey,
 	contributionType,
 	countryGroupId,
 	promotion,
 	thresholdAmount = 0,
-	mobileTheme = 'dark',
 }: PaymentTsAndCsProps): JSX.Element {
-	const inDigitalEdition = productKey === 'DigitalSubscription';
-	const inAdLite = productKey === 'GuardianAdLite';
-	const inAllAccessDigital = productKey === 'SupporterPlus';
-	const inDigitalPlusPrint = productKey === 'TierThree';
-	const inSupport =
-		productKey === 'Contribution' ||
-		!(inAllAccessDigital || inDigitalPlusPrint || inAdLite || inDigitalEdition);
-
-	const frequencyPlural = (contributionType: ContributionType) =>
-		contributionType === 'MONTHLY' ? 'monthly' : 'annual';
-
-	const copyAboveThreshold = (
-		contributionType: RegularContributionType,
-		promotion?: Promotion,
-	) => {
-		const productLabel = productCatalogDescription[productKey].label;
-		return (
-			<>
-				<div>
-					If you pay at least{' '}
-					{productLegal(
-						countryGroupId,
-						contributionType,
-						' per ',
-						thresholdAmount,
-						promotion,
-					)}
-					, you will receive the {productLabel} benefits on a subscription
-					basis. If you increase your payments per{' '}
-					{frequencySingular(contributionType)}, these additional amounts will
-					be separate {frequencyPlural(contributionType)} voluntary financial
-					contributions to the Guardian. The {productLabel} subscription and any
-					contributions will auto-renew each{' '}
-					{frequencySingular(contributionType)}. You will be charged the
-					subscription and contribution amounts using your chosen payment method
-					at each renewal unless you cancel. You can cancel your subscription or
-					change your contributions at any time before your next renewal date.
-					If you cancel within 14 days of taking out a {productLabel}{' '}
-					subscription, you’ll receive a full refund (including of any
-					contributions) and your subscription and any contribution will stop
-					immediately. Cancellation of your subscription (which will also cancel
-					any contribution) or cancellation of your contribution made after 14
-					days will take effect at the end of your current{' '}
-					{frequencyPlural(contributionType)} payment period. To cancel, go to{' '}
-					{ManageMyAccountLink} or see our {termsSupporterPlus('Terms')}.
-				</div>
-				<TsAndCsFooterLinks
-					countryGroupId={countryGroupId}
-					productKey={productKey}
-				/>
-			</>
-		);
-	};
-
-	if (contributionType === 'ONE_OFF') {
-		return (
-			<div css={container}>
-				<FinePrint mobileTheme={mobileTheme}>
-					<TsAndCsFooterLinks
-						countryGroupId={countryGroupId}
-						productKey={productKey}
-					/>
-				</FinePrint>
+	const productLabel = productCatalogDescription[productKey].label;
+	const paymentTsAndCs: Partial<Record<ActiveProductKey, JSX.Element>> = {
+		DigitalSubscription: (
+			<div>
+				Payment taken after the first 14 day free trial. At the end of the free
+				trial period your subscription will auto-renew, and you will be charged,
+				each month at the full price of £14.99 per month or £149 per year unless
+				you cancel. You can cancel at any time before your next renewal date.
+				Cancellation will take effect at the end of your current subscription
+				month. To cancel, go to{' '}
+				<a href={'http://manage.theguardian.com/'}>Manage My Account</a> or see
+				our{' '}
+				<a href="https://www.theguardian.com/info/2014/aug/06/guardian-observer-digital-subscriptions-terms-conditions">
+					Terms
+				</a>
+				.
 			</div>
-		);
-	}
-
-	const copyBelowThreshold = (
-		countryGroupId: CountryGroupId,
-		productKey: ActiveProductKey,
-	) => {
-		return (
-			<TsAndCsFooterLinks
-				countryGroupId={countryGroupId}
-				productKey={productKey}
-			/>
-		);
-	};
-
-	const copyAdLite = (contributionType: RegularContributionType) => {
-		return (
+		),
+		GuardianAdLite: (
 			<div>
 				Your Guardian Ad-Lite subscription will auto-renew each{' '}
 				{frequencySingular(contributionType)} unless cancelled. Your first
@@ -196,49 +142,71 @@ export function PaymentTsAndCs({
 				Cancellation of your subscription after 14 days will take effect at the
 				end of your current monthly payment period. To cancel, go to{' '}
 				{ManageMyAccountLink} or see our Guardian Ad-Lite{' '}
-				{termsGuardianAdLite('Terms')}.
+				{termsLink('Terms', guardianAdLiteTermsLink)}.
 			</div>
-		);
-	};
-
-	const copyDigitalEdition = () => {
-		return (
-			<>
-				<div>
-					Payment taken after the first 14 day free trial. At the end of the
-					free trial period your subscription will auto-renew, and you will be
-					charged, each month at the full price of £14.99 per month or £149 per
-					year unless you cancel. You can cancel at any time before your next
-					renewal date. Cancellation will take effect at the end of your current
-					subscription month. To cancel, go to{' '}
-					<a href={'http://manage.theguardian.com/'}>Manage My Account</a> or
-					see our{' '}
-					<a href="https://www.theguardian.com/info/2014/aug/06/guardian-observer-digital-subscriptions-terms-conditions">
-						Terms
-					</a>
-					.
-				</div>
-				<TsAndCsFooterLinks
-					countryGroupId={countryGroupId}
-					productKey={productKey}
-				/>
-			</>
-		);
+		),
+		SupporterPlus: (
+			<div>
+				If you pay at least{' '}
+				{productLegal(
+					countryGroupId,
+					contributionType as RegularContributionType,
+					' per ',
+					thresholdAmount,
+					promotion,
+				)}
+				, you will receive the {productLabel} benefits on a subscription basis.
+				If you increase your payments per {frequencySingular(contributionType)},
+				these additional amounts will be separate{' '}
+				{frequencyPlural(contributionType)} voluntary financial contributions to
+				the Guardian. The {productLabel} subscription and any contributions will
+				auto-renew each {frequencySingular(contributionType)}. You will be
+				charged the subscription and contribution amounts using your chosen
+				payment method at each renewal unless you cancel. You can cancel your
+				subscription or change your contributions at any time before your next
+				renewal date. If you cancel within 14 days of taking out a{' '}
+				{productLabel} subscription, you’ll receive a full refund (including of
+				any contributions) and your subscription and any contribution will stop
+				immediately. Cancellation of your subscription (which will also cancel
+				any contribution) or cancellation of your contribution made after 14
+				days will take effect at the end of your current{' '}
+				{frequencyPlural(contributionType)} payment period. To cancel, go to{' '}
+				{ManageMyAccountLink} or see our{' '}
+				{termsLink('Terms', supporterPlusTermsLink)}.
+			</div>
+		),
+		TierThree: (
+			<div>
+				<p>
+					By signing up, you are taking out a Digital + print subscription. Your
+					Digital + print subscription will auto-renew each{' '}
+					{frequencySingular(contributionType)} unless cancelled. Your first
+					payment will be taken on the publication date of your first Guardian
+					Weekly magazine (as shown in the checkout) but you will start to
+					receive your digital benefits when you sign up. Unless you cancel,
+					subsequent {frequencyPlural(contributionType)} payments will be taken
+					on this date using your chosen payment method. You can cancel your
+					Digital + print subscription at any time before your next renewal
+					date. If you cancel your Digital + print subscription within 14 days
+					of signing up, your subscription will stop immediately and we will not
+					take the first payment from you. Cancellation of your subscription
+					after 14 days will take effect at the end of your current{' '}
+					{frequencyPlural(contributionType)} payment period. To cancel go
+					to&nbsp;
+					{ManageMyAccountLink} or see our Digital + print{' '}
+					{termsLink('Terms', tierThreeTermsLink)}.
+				</p>
+			</div>
+		),
 	};
-
 	return (
 		<div css={container}>
-			<FinePrint mobileTheme={mobileTheme}>
-				{inDigitalPlusPrint && (
-					<TierThreeTerms
-						paymentFrequency={contributionType === 'ANNUAL' ? 'year' : 'month'}
-					/>
-				)}
-				{inAllAccessDigital && copyAboveThreshold(contributionType, promotion)}
-				{inAdLite && copyAdLite(contributionType)}
-				{(inSupport || inAdLite) &&
-					copyBelowThreshold(countryGroupId, productKey)}
-				{inDigitalEdition && copyDigitalEdition()}
+			<FinePrint mobileTheme={'dark'}>
+				{paymentTsAndCs[productKey]}
+				<FooterTsAndCs
+					productKey={productKey}
+					countryGroupId={countryGroupId}
+				/>
 			</FinePrint>
 		</div>
 	);
diff --git a/support-frontend/assets/pages/supporter-plus-landing/components/summaryTsAndCs.test.tsx b/support-frontend/assets/pages/supporter-plus-landing/components/summaryTsAndCs.test.tsx
index 8250f3e1ec..a06a43bcfb 100644
--- a/support-frontend/assets/pages/supporter-plus-landing/components/summaryTsAndCs.test.tsx
+++ b/support-frontend/assets/pages/supporter-plus-landing/components/summaryTsAndCs.test.tsx
@@ -1,32 +1,34 @@
 import { render } from '@testing-library/react';
+import type { ContributionType } from 'helpers/contributions';
 import type { ActiveProductKey } from 'helpers/productCatalog';
 import { SummaryTsAndCs } from './summaryTsAndCs';
 
 // Mocking price retrieval from productCatalog (not available in window at runtime)
-jest.mock(
-	'./TsAndCsRenewal',
-	() =>
-		function () {
-			return <div>on the first day of every month</div>;
-		},
-);
+jest.mock('helpers/utilities/dateFormatting', () => ({
+	getDateWithOrdinal: () => 'first',
+	getLongMonth: () => 'March',
+}));
 
 describe('Summary Ts&Cs Snapshot comparison', () => {
-	const summaryProductKeys: ActiveProductKey[] = [
-		'Contribution',
-		'SupporterPlus',
-		'TierThree',
-		'OneTimeContribution',
-		'GuardianAdLite',
-		'DigitalSubscription',
-	];
-	it.each(summaryProductKeys)(
-		`summaryTs&Cs render product %s correctly`,
-		(summaryProductKey) => {
+	it.each`
+		productKey               | contributionType
+		${'Contribution'}        | ${'MONTHLY'}
+		${'Contribution'}        | ${'ANNUALY'}
+		${'SupporterPlus'}       | ${'MONTHLY'}
+		${'SupporterPlus'}       | ${'ANNUALY'}
+		${'TierThree'}           | ${'MONTHLY'}
+		${'TierThree'}           | ${'ANNUALY'}
+		${'OneTimeContribution'} | ${'MONTHLY'}
+		${'GuardianAdLite'}      | ${'MONTHLY'}
+		${'GuardianAdLite'}      | ${'ANNUALY'}
+		${'DigitalSubscription'} | ${'MONTHLY'}
+	`(
+		`summaryTs&Cs for $productKey With contributionType $contributionType renders correctly`,
+		({ productKey, contributionType }) => {
 			const { container } = render(
 				<SummaryTsAndCs
-					contributionType={'MONTHLY'}
-					productKey={summaryProductKey}
+					contributionType={contributionType as ContributionType}
+					productKey={productKey as ActiveProductKey}
 					currency={'GBP'}
 					amount={0}
 				/>,
diff --git a/support-frontend/assets/pages/supporter-plus-landing/components/summaryTsAndCs.tsx b/support-frontend/assets/pages/supporter-plus-landing/components/summaryTsAndCs.tsx
index 26e6693f03..6d1810810d 100644
--- a/support-frontend/assets/pages/supporter-plus-landing/components/summaryTsAndCs.tsx
+++ b/support-frontend/assets/pages/supporter-plus-landing/components/summaryTsAndCs.tsx
@@ -1,18 +1,18 @@
 import { css } from '@emotion/react';
-import type { SerializedStyles } from '@emotion/utils';
 import { neutral, space, textSans17 } from '@guardian/source/foundations';
 import type { ContributionType } from 'helpers/contributions';
 import { formatAmount } from 'helpers/forms/checkouts';
+import type { IsoCurrency } from 'helpers/internationalisation/currency';
 import {
 	currencies,
 	spokenCurrencies,
 } from 'helpers/internationalisation/currency';
-import type { IsoCurrency } from 'helpers/internationalisation/currency';
-import { productCatalogDescription } from 'helpers/productCatalog';
 import type { ActiveProductKey } from 'helpers/productCatalog';
-import type { Promotion } from 'helpers/productPrice/promotions';
-import type { FinePrintTheme } from './finePrint';
-import TsAndCsRenewal from './TsAndCsRenewal';
+import { productCatalogDescription } from 'helpers/productCatalog';
+import {
+	getDateWithOrdinal,
+	getLongMonth,
+} from 'helpers/utilities/dateFormatting';
 
 const containerSummaryTsCs = css`
 	margin-top: ${space[6]}px;
@@ -26,100 +26,66 @@ const containerSummaryTsCs = css`
 	}
 `;
 
+const frequencySingular = (contributionType: ContributionType) =>
+	contributionType === 'MONTHLY' ? 'month' : 'year';
+
+const getRenewalFrequency = (contributionType: ContributionType) => {
+	const today = new Date();
+	return contributionType === 'ANNUAL'
+		? `on the ${getDateWithOrdinal(today)} day of ${getLongMonth(
+				today,
+		  )} every year`
+		: `on the ${getDateWithOrdinal(today)} day of every month`;
+};
+
 export interface SummaryTsAndCsProps {
-	mobileTheme?: FinePrintTheme;
+	productKey: ActiveProductKey;
 	contributionType: ContributionType;
 	currency: IsoCurrency;
 	amount: number;
-	productKey: ActiveProductKey;
-	promotion?: Promotion;
-	cssOverrides?: SerializedStyles;
 }
-
-const frequencySingular = (contributionType: ContributionType) =>
-	contributionType === 'MONTHLY' ? 'month' : 'year';
-
 export function SummaryTsAndCs({
+	productKey,
 	contributionType,
 	currency,
 	amount,
-	productKey,
-	cssOverrides,
-}: SummaryTsAndCsProps): JSX.Element {
-	const inDigitalEdition = productKey === 'DigitalSubscription';
-	const inAdLite = productKey === 'GuardianAdLite';
-	const inDigitalPlusPrint = productKey === 'TierThree';
-	const inAllAccessDigital = productKey === 'SupporterPlus';
-	const inSupport =
-		productKey === 'Contribution' ||
-		!(inAllAccessDigital || inDigitalPlusPrint || inAdLite);
-
-	const amountCopy = ` of ${formatAmount(
+}: SummaryTsAndCsProps): JSX.Element | null {
+	const amountWithCurrency = formatAmount(
 		currencies[currency],
 		spokenCurrencies[currency],
 		amount,
 		false,
-	)}`;
-
-	const copyTier1 = (contributionType: ContributionType) => {
-		return (
-			<>
-				<div>
-					We will attempt to take payment{amountCopy},{' '}
-					<TsAndCsRenewal contributionType={contributionType} />, from now until
-					you cancel your payment. Payments may take up to 6 days to be recorded
-					in your bank account. You can change how much you give or cancel your
-					payment at any time.
-				</div>
-			</>
-		);
-	};
-
-	const copyTier2 = (
-		contributionType: ContributionType,
-		productKey: ActiveProductKey,
-	) => {
-		return (
-			<>
-				<div>
-					The {productCatalogDescription[productKey].label} subscription and any
-					contribution will auto-renew each{' '}
-					{frequencySingular(contributionType)}. You will be charged the
-					subscription and contribution amounts using your chosen payment method
-					at each renewal, at the rate then in effect, unless you cancel.
-				</div>
-			</>
-		);
-	};
-
-	const copyTier3 = (
-		contributionType: ContributionType,
-		productKey: ActiveProductKey,
-		plural: boolean,
-	) => {
-		return (
-			<>
-				<div>
-					The {productCatalogDescription[productKey].label} subscription
-					{plural ? 's' : ''} will auto-renew each{' '}
-					{frequencySingular(contributionType)}. You will be charged the
-					subscription amount using your chosen payment method at each renewal,
-					at the rate then in effect, unless you cancel.
-				</div>
-			</>
-		);
-	};
-
-	return (
-		<>
-			{!inDigitalEdition && (
-				<div css={[containerSummaryTsCs, cssOverrides]}>
-					{inSupport && copyTier1(contributionType)}
-					{inAllAccessDigital && copyTier2(contributionType, productKey)}
-					{inDigitalPlusPrint && copyTier3(contributionType, productKey, true)}
-					{inAdLite && copyTier3(contributionType, productKey, false)}
-				</div>
-			)}
-		</>
 	);
+	const summaryTsAndCsTierThreeGuardianAdLite = (
+		<div css={containerSummaryTsCs}>
+			The {productCatalogDescription[productKey].label} subscription
+			{productKey === 'TierThree' ? 's' : ''} will auto-renew each{' '}
+			{frequencySingular(contributionType)}. You will be charged the
+			subscription amount using your chosen payment method at each renewal, at
+			the rate then in effect, unless you cancel.
+		</div>
+	);
+	const summaryTsAndCs: Partial<Record<ActiveProductKey, JSX.Element>> = {
+		Contribution: (
+			<div css={containerSummaryTsCs}>
+				We will attempt to take payment of {amountWithCurrency},{' '}
+				{getRenewalFrequency(contributionType)}, from now until you cancel your
+				payment. Payments may take up to 6 days to be recorded in your bank
+				account. You can change how much you give or cancel your payment at any
+				time.
+			</div>
+		),
+		SupporterPlus: (
+			<div css={containerSummaryTsCs}>
+				The {productCatalogDescription[productKey].label} subscription and any
+				contribution will auto-renew each {frequencySingular(contributionType)}.
+				You will be charged the subscription and contribution amounts using your
+				chosen payment method at each renewal, at the rate then in effect,
+				unless you cancel.
+			</div>
+		),
+		TierThree: summaryTsAndCsTierThreeGuardianAdLite,
+		GuardianAdLite: summaryTsAndCsTierThreeGuardianAdLite,
+	};
+	return summaryTsAndCs[productKey] ?? null;
 }
diff --git a/support-frontend/stories/checkouts/ContributionsOrderSummary.stories.tsx b/support-frontend/stories/checkouts/ContributionsOrderSummary.stories.tsx
index a4cf96d1c6..b47def025b 100644
--- a/support-frontend/stories/checkouts/ContributionsOrderSummary.stories.tsx
+++ b/support-frontend/stories/checkouts/ContributionsOrderSummary.stories.tsx
@@ -5,6 +5,12 @@ import type { ContributionsOrderSummaryProps } from 'components/orderSummary/con
 import { ContributionsOrderSummary } from 'components/orderSummary/contributionsOrderSummary';
 import { withCenterAlignment } from '../../.storybook/decorators/withCenterAlignment';
 import { withSourceReset } from '../../.storybook/decorators/withSourceReset';
+import { productCatalogDescription } from 'helpers/productCatalog';
+import {
+	OrderSummaryStartDate,
+	OrderSummaryTsAndCs,
+} from 'components/orderSummary/orderSummaryTsAndCs';
+import { GBPCountries } from 'helpers/internationalisation/countryGroup';
 
 const boldText = css`
 	font-weight: bold;
@@ -86,11 +92,6 @@ Default.args = {
 		isPaddedGlyph: false,
 	},
 	checkListData: checkListData,
-	headerButton: (
-		<Button priority="tertiary" size="xsmall">
-			Change
-		</Button>
-	),
 	tsAndCs: (
 		<>
 			<p>Auto renews every month until you cancel.</p>
@@ -100,6 +101,12 @@ Default.args = {
 			</p>
 		</>
 	),
+	startDateTierThree: <></>,
+	headerButton: (
+		<Button priority="tertiary" size="xsmall">
+			Change
+		</Button>
+	),
 };
 
 export const SingleContribution = Template.bind({});
@@ -115,6 +122,115 @@ SingleContribution.args = {
 		isPaddedGlyph: false,
 	},
 	checkListData: [],
+	tsAndCs: <></>,
+	startDateTierThree: <></>,
+	headerButton: (
+		<Button priority="tertiary" size="xsmall">
+			Change
+		</Button>
+	),
+};
+
+export const RecurringContribution = Template.bind({});
+
+RecurringContribution.args = {
+	description: 'Support',
+	enableCheckList: true,
+	amount: 3,
+	currency: {
+		glyph: '£',
+		extendedGlyph: '£',
+		isSuffixGlyph: false,
+		isPaddedGlyph: false,
+	},
+	checkListData: [
+		...productCatalogDescription.Contribution.benefits.map((benefit) => ({
+			isChecked: true,
+			text: benefit.copy,
+		})),
+	],
+	tsAndCs: (
+		<OrderSummaryTsAndCs
+			productKey={'Contribution'}
+			contributionType={'MONTHLY'}
+			countryGroupId={GBPCountries}
+		/>
+	),
+	startDateTierThree: null,
+	headerButton: (
+		<Button priority="tertiary" size="xsmall">
+			Change
+		</Button>
+	),
+};
+
+export const SupporterPlus = Template.bind({});
+
+SupporterPlus.args = {
+	description: 'All-access Digital',
+	enableCheckList: true,
+	amount: 12,
+	currency: {
+		glyph: '£',
+		extendedGlyph: '£',
+		isSuffixGlyph: false,
+		isPaddedGlyph: false,
+	},
+	checkListData: [
+		...productCatalogDescription.SupporterPlus.benefits.map((benefit) => ({
+			isChecked: true,
+			text: benefit.copy,
+		})),
+	],
+	tsAndCs: (
+		<OrderSummaryTsAndCs
+			productKey={'SupporterPlus'}
+			contributionType={'MONTHLY'}
+			countryGroupId={GBPCountries}
+			thresholdAmount={12}
+		/>
+	),
+	startDateTierThree: null,
+	headerButton: (
+		<Button priority="tertiary" size="xsmall">
+			Change
+		</Button>
+	),
+};
+
+export const TierThree = Template.bind({});
+
+TierThree.args = {
+	description: 'Digital + print',
+	enableCheckList: true,
+	amount: 27,
+	currency: {
+		glyph: '£',
+		extendedGlyph: '£',
+		isSuffixGlyph: false,
+		isPaddedGlyph: false,
+	},
+	checkListData: [
+		...productCatalogDescription.SupporterPlus.benefits.map((benefit) => ({
+			isChecked: true,
+			text: benefit.copy,
+		})),
+		...productCatalogDescription.TierThree.benefits.map((benefit) => ({
+			isChecked: true,
+			text: benefit.copy,
+		})),
+	],
+	tsAndCs: (
+		<OrderSummaryTsAndCs
+			productKey={'TierThree'}
+			contributionType={'MONTHLY'}
+			countryGroupId={GBPCountries}
+			thresholdAmount={27}
+		/>
+	),
+	startDateTierThree: (
+		<OrderSummaryStartDate startDate={'Friday, April 11, 2025'} />
+	),
 	headerButton: (
 		<Button priority="tertiary" size="xsmall">
 			Change
diff --git a/support-frontend/stories/checkouts/SummaryTsAndCs.stories.tsx b/support-frontend/stories/checkouts/SummaryTsAndCs.stories.tsx
index 9e00f2cf05..77a0457b96 100644
--- a/support-frontend/stories/checkouts/SummaryTsAndCs.stories.tsx
+++ b/support-frontend/stories/checkouts/SummaryTsAndCs.stories.tsx
@@ -24,14 +24,6 @@ GuardianAdLite.args = {
 	amount: 0,
 };
 
-export const OneTimeContribution = Template.bind({});
-OneTimeContribution.args = {
-	productKey: 'OneTimeContribution',
-	contributionType: 'ONE_OFF',
-	currency: 'AUD',
-	amount: 5,
-};
-
 export const Contribution = Template.bind({});
 Contribution.args = {
 	productKey: 'Contribution',
diff --git a/support-frontend/stories/checkouts/orderSummaryTsAndCs.stories.tsx b/support-frontend/stories/checkouts/orderSummaryTsAndCs.stories.tsx
new file mode 100644
index 0000000000..0b6f4e9b60
--- /dev/null
+++ b/support-frontend/stories/checkouts/orderSummaryTsAndCs.stories.tsx
@@ -0,0 +1,54 @@
+import {
+	OrderSummaryTsAndCs,
+	OrderSummaryTsAndCsProps,
+} from 'components/orderSummary/orderSummaryTsAndCs';
+
+export default {
+	title: 'Checkouts/Ts&Cs Order Summary',
+	component: OrderSummaryTsAndCs,
+	argTypes: {},
+	decorators: [],
+};
+
+function Template(args: OrderSummaryTsAndCsProps) {
+	return <OrderSummaryTsAndCs {...args} />;
+}
+
+Template.args = {} as Omit<OrderSummaryTsAndCsProps, ''>;
+
+export const GuardianAdLite = Template.bind({});
+GuardianAdLite.args = {
+	productKey: 'GuardianAdLite',
+	contributionType: 'MONTHLY',
+	countryGroupId: 'GBPCountries',
+};
+
+export const Contribution = Template.bind({});
+Contribution.args = {
+	productKey: 'Contribution',
+	contributionType: 'ANNUAL',
+	countryGroupId: 'AUDCountries',
+};
+
+export const SupporterPlus = Template.bind({});
+SupporterPlus.args = {
+	productKey: 'SupporterPlus',
+	contributionType: 'MONTHLY',
+	countryGroupId: 'GBPCountries',
+	thresholdAmount: 12,
+};
+
+export const TierThree = Template.bind({});
+TierThree.args = {
+	productKey: 'TierThree',
+	contributionType: 'MONTHLY',
+	countryGroupId: 'UnitedStates',
+	thresholdAmount: 45,
+	promotion: {
+		name: '$8 off for 12 months',
+		description: 'Tier Three United States Monthly',
+		promoCode: 'TIER_THREE_USA_MONTHLY',
+		numberOfDiscountedPeriods: 12,
+		discountedPrice: 37,
+	},
+};
diff --git a/support-frontend/stories/checkouts/paymentTsAndCs.stories.tsx b/support-frontend/stories/checkouts/paymentTsAndCs.stories.tsx
index 7d595b13f2..39127d84c0 100644
--- a/support-frontend/stories/checkouts/paymentTsAndCs.stories.tsx
+++ b/support-frontend/stories/checkouts/paymentTsAndCs.stories.tsx
@@ -16,16 +16,16 @@ function Template(args: PaymentTsAndCsProps) {
 
 Template.args = {} as Omit<PaymentTsAndCsProps, ''>;
 
-export const DigitalSubscription = Template.bind({});
-DigitalSubscription.args = {
-	productKey: 'DigitalSubscription',
+export const GuardianAdLite = Template.bind({});
+GuardianAdLite.args = {
+	productKey: 'GuardianAdLite',
 	contributionType: 'MONTHLY',
 	countryGroupId: 'GBPCountries',
 };
 
-export const GuardianAdLite = Template.bind({});
-GuardianAdLite.args = {
-	productKey: 'GuardianAdLite',
+export const DigitalSubscription = Template.bind({});
+DigitalSubscription.args = {
+	productKey: 'DigitalSubscription',
 	contributionType: 'MONTHLY',
 	countryGroupId: 'GBPCountries',
 };
@@ -34,14 +34,14 @@ export const OneTimeContribution = Template.bind({});
 OneTimeContribution.args = {
 	productKey: 'OneTimeContribution',
 	contributionType: 'ONE_OFF',
-	countryGroupId: 'AUDCountries',
+	countryGroupId: 'UnitedStates',
 };
 
 export const Contribution = Template.bind({});
 Contribution.args = {
 	productKey: 'Contribution',
-	contributionType: 'MONTHLY',
-	countryGroupId: 'UnitedStates',
+	contributionType: 'ANNUAL',
+	countryGroupId: 'AUDCountries',
 };
 
 export const SupporterPlus = Template.bind({});
@@ -56,6 +56,13 @@ export const TierThree = Template.bind({});
 TierThree.args = {
 	productKey: 'TierThree',
 	contributionType: 'MONTHLY',
-	countryGroupId: 'GBPCountries',
-	thresholdAmount: 12,
+	countryGroupId: 'UnitedStates',
+	thresholdAmount: 45,
+	promotion: {
+		name: '$8 off for 12 months',
+		description: 'Tier Three United States Monthly',
+		promoCode: 'TIER_THREE_USA_MONTHLY',
+		numberOfDiscountedPeriods: 12,
+		discountedPrice: 37,
+	},
 };


Reviews:
user: login: maloky
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T10:19:44Z
user: login: maloky
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T10:21:32Z
user: login: paul-daniel-dempsey
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T12:49:45Z
user: login: paul-daniel-dempsey
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T12:50:40Z
user: login: GHaberis
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T15:49:38Z
user: login: GHaberis
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T16:03:17Z
user: login: GHaberis
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T16:04:43Z
user: login: paul-daniel-dempsey
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T16:28:05Z
user: login: paul-daniel-dempsey
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T17:57:11Z
user: login: paul-daniel-dempsey
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T18:20:08Z
user: login: GHaberis
body: Looks good! 👍, nice comprehensive suite of tests and stories too!
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T12:02:22Z

Review comments:
diff_hunk: @@ -0,0 +1,126 @@
+import { css } from '@emotion/react';
+import {
+	from,
+	neutral,
+	palette,
+	space,
+	textSans14,
+} from '@guardian/source/foundations';
+import { type ContributionType } from 'helpers/contributions';
+import type { CountryGroupId } from 'helpers/internationalisation/countryGroup';
+import { productLegal } from 'helpers/legalCopy';
+import type { ActiveProductKey } from 'helpers/productCatalog';
+import type { Promotion } from 'helpers/productPrice/promotions';
+
+const containerSummaryTsCs = css`
+	border-radius: ${space[2]}px;
+	background-color: ${neutral[97]};
+	padding: ${space[3]}px;
+`;
+const productStartDate = css`
+	display: block;
+	${textSans14};
+	color: #606060;
+	background-color: ${palette.neutral[97]};
+	border-radius: ${space[3]}px;
+	padding: ${space[3]}px;
+	margin-top: ${space[2]}px;
+	${from.desktop} {
+		margin-top: ${space[4]}px;
+	}
+	li + li {
+		margin-top: ${space[2]}px;
+	}
+`;
+
+interface OrderSummaryStartDateProps {
+	productKey: ActiveProductKey;
+	startDate: string;
+}
+export function OrderSummaryStartDate({
+	productKey,
+	startDate,
+}: OrderSummaryStartDateProps): JSX.Element {
+	const orderSummaryStartDate: Partial<Record<ActiveProductKey, JSX.Element>> =
+		{
+			TierThree: (
+				<ul css={productStartDate}>
+					<li>Your digital benefits will start today.</li>
+					<li>
+						Your Guardian Weekly subscription will start on {startDate}. Please
+						allow 1 to 7 days after your start date for your magazine to arrive,
+						depending on national post services.
+					</li>
+				</ul>
+			),
+		};
+	return orderSummaryStartDate[productKey] ?? <></>;
+}
+
+export interface OrderSummaryTsAndCsProps {
+	productKey: ActiveProductKey;
+	contributionType: ContributionType;
+	countryGroupId: CountryGroupId;
+	promotion?: Promotion;
+	thresholdAmount?: number;
+}
+export function OrderSummaryTsAndCs({
+	productKey,
+	contributionType,
+	countryGroupId,
+	promotion,
+	thresholdAmount = 0,
+}: OrderSummaryTsAndCsProps): JSX.Element {
+	// Proceeds with RegularContributionType only
+	if (contributionType === 'ONE_OFF') {
+		return <></>;
+	}
+	const period = contributionType === 'MONTHLY' ? 'month' : 'year';
+	const tierThreeSupporterPlusTsAndCs = (
+		<div css={containerSummaryTsCs}>
+			{promotion && (
+				<p>
+					You’ll pay{' '}
+					{productLegal(
+						countryGroupId,
+						contributionType,
+						'/',
+						thresholdAmount,
+						promotion,
+					)}{' '}
+					afterwards unless you cancel. Offer only available to new subscribers
+					who do not have an existing subscription with the Guardian.
+				</p>
+			)}
+			{productKey === 'SupporterPlus' && (
+				<>
+					<p>Auto renews every {period} until you cancel.</p>
+					<p>
+						Cancel or change your support anytime. If you cancel within the
+						first 14 days, you will receive a full refund.
+					</p>
+				</>
+			)}
+			{productKey === 'TierThree' && (
+				<p>Auto renews every {period}. Cancel anytime.</p>
+			)}
+		</div>
+	);
+	const contributeAdLiteTsAndCs = (
+		<div css={containerSummaryTsCs}>
+			<p>Auto renews every {period} until you cancel.</p>
+			<p>
+				{productKey === 'GuardianAdLite'
+					? 'Cancel anytime.'
+					: 'Cancel or change your support anytime.'}
+			</p>
+		</div>
+	);
+	const orderSummaryTsAndCs: Partial<Record<ActiveProductKey, JSX.Element>> = {
+		GuardianAdLite: contributeAdLiteTsAndCs,
+		Contribution: contributeAdLiteTsAndCs,
+		SupporterPlus: tierThreeSupporterPlusTsAndCs,
+		TierThree: tierThreeSupporterPlusTsAndCs,
+	};
+	return orderSummaryTsAndCs[productKey] ?? <></>;
path: support-frontend/assets/components/orderSummary/orderSummaryTsAndCs.tsx
user: login: maloky
body: As in the other module, I don't think we need to mulish coalescing operator. 
```suggestion
	return orderSummaryTsAndCs[productKey]
	;
```
created_at: 2025-03-21T10:19:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,126 @@
+import { css } from '@emotion/react';
+import {
+	from,
+	neutral,
+	palette,
+	space,
+	textSans14,
+} from '@guardian/source/foundations';
+import { type ContributionType } from 'helpers/contributions';
+import type { CountryGroupId } from 'helpers/internationalisation/countryGroup';
+import { productLegal } from 'helpers/legalCopy';
+import type { ActiveProductKey } from 'helpers/productCatalog';
+import type { Promotion } from 'helpers/productPrice/promotions';
+
+const containerSummaryTsCs = css`
+	border-radius: ${space[2]}px;
+	background-color: ${neutral[97]};
+	padding: ${space[3]}px;
+`;
+const productStartDate = css`
+	display: block;
+	${textSans14};
+	color: #606060;
+	background-color: ${palette.neutral[97]};
+	border-radius: ${space[3]}px;
+	padding: ${space[3]}px;
+	margin-top: ${space[2]}px;
+	${from.desktop} {
+		margin-top: ${space[4]}px;
+	}
+	li + li {
+		margin-top: ${space[2]}px;
+	}
+`;
+
+interface OrderSummaryStartDateProps {
+	productKey: ActiveProductKey;
+	startDate: string;
+}
+export function OrderSummaryStartDate({
+	productKey,
+	startDate,
+}: OrderSummaryStartDateProps): JSX.Element {
+	const orderSummaryStartDate: Partial<Record<ActiveProductKey, JSX.Element>> =
+		{
+			TierThree: (
+				<ul css={productStartDate}>
+					<li>Your digital benefits will start today.</li>
+					<li>
+						Your Guardian Weekly subscription will start on {startDate}. Please
+						allow 1 to 7 days after your start date for your magazine to arrive,
+						depending on national post services.
+					</li>
+				</ul>
+			),
+		};
+	return orderSummaryStartDate[productKey] ?? <></>;
+}
+
+export interface OrderSummaryTsAndCsProps {
+	productKey: ActiveProductKey;
+	contributionType: ContributionType;
+	countryGroupId: CountryGroupId;
+	promotion?: Promotion;
+	thresholdAmount?: number;
+}
+export function OrderSummaryTsAndCs({
+	productKey,
+	contributionType,
+	countryGroupId,
+	promotion,
+	thresholdAmount = 0,
+}: OrderSummaryTsAndCsProps): JSX.Element {
+	// Proceeds with RegularContributionType only
+	if (contributionType === 'ONE_OFF') {
+		return <></>;
path: support-frontend/assets/components/orderSummary/orderSummaryTsAndCs.tsx
user: login: maloky
body: I think the preferred way for react is to return null.
https://legacy.reactjs.org/docs/conditional-rendering.html#preventing-component-from-rendering
created_at: 2025-03-21T10:21:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,126 @@
+import { css } from '@emotion/react';
+import {
+	from,
+	neutral,
+	palette,
+	space,
+	textSans14,
+} from '@guardian/source/foundations';
+import { type ContributionType } from 'helpers/contributions';
+import type { CountryGroupId } from 'helpers/internationalisation/countryGroup';
+import { productLegal } from 'helpers/legalCopy';
+import type { ActiveProductKey } from 'helpers/productCatalog';
+import type { Promotion } from 'helpers/productPrice/promotions';
+
+const containerSummaryTsCs = css`
+	border-radius: ${space[2]}px;
+	background-color: ${neutral[97]};
+	padding: ${space[3]}px;
+`;
+const productStartDate = css`
+	display: block;
+	${textSans14};
+	color: #606060;
+	background-color: ${palette.neutral[97]};
+	border-radius: ${space[3]}px;
+	padding: ${space[3]}px;
+	margin-top: ${space[2]}px;
+	${from.desktop} {
+		margin-top: ${space[4]}px;
+	}
+	li + li {
+		margin-top: ${space[2]}px;
+	}
+`;
+
+interface OrderSummaryStartDateProps {
+	productKey: ActiveProductKey;
+	startDate: string;
+}
+export function OrderSummaryStartDate({
+	productKey,
+	startDate,
+}: OrderSummaryStartDateProps): JSX.Element {
+	const orderSummaryStartDate: Partial<Record<ActiveProductKey, JSX.Element>> =
+		{
+			TierThree: (
+				<ul css={productStartDate}>
+					<li>Your digital benefits will start today.</li>
+					<li>
+						Your Guardian Weekly subscription will start on {startDate}. Please
+						allow 1 to 7 days after your start date for your magazine to arrive,
+						depending on national post services.
+					</li>
+				</ul>
+			),
+		};
+	return orderSummaryStartDate[productKey] ?? <></>;
+}
+
+export interface OrderSummaryTsAndCsProps {
+	productKey: ActiveProductKey;
+	contributionType: ContributionType;
+	countryGroupId: CountryGroupId;
+	promotion?: Promotion;
+	thresholdAmount?: number;
+}
+export function OrderSummaryTsAndCs({
+	productKey,
+	contributionType,
+	countryGroupId,
+	promotion,
+	thresholdAmount = 0,
+}: OrderSummaryTsAndCsProps): JSX.Element {
+	// Proceeds with RegularContributionType only
+	if (contributionType === 'ONE_OFF') {
+		return <></>;
path: support-frontend/assets/components/orderSummary/orderSummaryTsAndCs.tsx
user: login: paul-daniel-dempsey
body: @maloky : Have now used this `null` approach on all Ts&Cs components, this includes the one on comment [above](https://github.com/guardian/support-frontend/pull/6849#discussion_r2007277419)). Updated.
created_at: 2025-03-21T12:49:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,126 @@
+import { css } from '@emotion/react';
+import {
+	from,
+	neutral,
+	palette,
+	space,
+	textSans14,
+} from '@guardian/source/foundations';
+import { type ContributionType } from 'helpers/contributions';
+import type { CountryGroupId } from 'helpers/internationalisation/countryGroup';
+import { productLegal } from 'helpers/legalCopy';
+import type { ActiveProductKey } from 'helpers/productCatalog';
+import type { Promotion } from 'helpers/productPrice/promotions';
+
+const containerSummaryTsCs = css`
+	border-radius: ${space[2]}px;
+	background-color: ${neutral[97]};
+	padding: ${space[3]}px;
+`;
+const productStartDate = css`
+	display: block;
+	${textSans14};
+	color: #606060;
+	background-color: ${palette.neutral[97]};
+	border-radius: ${space[3]}px;
+	padding: ${space[3]}px;
+	margin-top: ${space[2]}px;
+	${from.desktop} {
+		margin-top: ${space[4]}px;
+	}
+	li + li {
+		margin-top: ${space[2]}px;
+	}
+`;
+
+interface OrderSummaryStartDateProps {
+	productKey: ActiveProductKey;
+	startDate: string;
+}
+export function OrderSummaryStartDate({
+	productKey,
+	startDate,
+}: OrderSummaryStartDateProps): JSX.Element {
+	const orderSummaryStartDate: Partial<Record<ActiveProductKey, JSX.Element>> =
+		{
+			TierThree: (
+				<ul css={productStartDate}>
+					<li>Your digital benefits will start today.</li>
+					<li>
+						Your Guardian Weekly subscription will start on {startDate}. Please
+						allow 1 to 7 days after your start date for your magazine to arrive,
+						depending on national post services.
+					</li>
+				</ul>
+			),
+		};
+	return orderSummaryStartDate[productKey] ?? <></>;
+}
+
+export interface OrderSummaryTsAndCsProps {
+	productKey: ActiveProductKey;
+	contributionType: ContributionType;
+	countryGroupId: CountryGroupId;
+	promotion?: Promotion;
+	thresholdAmount?: number;
+}
+export function OrderSummaryTsAndCs({
+	productKey,
+	contributionType,
+	countryGroupId,
+	promotion,
+	thresholdAmount = 0,
+}: OrderSummaryTsAndCsProps): JSX.Element {
+	// Proceeds with RegularContributionType only
+	if (contributionType === 'ONE_OFF') {
+		return <></>;
+	}
+	const period = contributionType === 'MONTHLY' ? 'month' : 'year';
+	const tierThreeSupporterPlusTsAndCs = (
+		<div css={containerSummaryTsCs}>
+			{promotion && (
+				<p>
+					You’ll pay{' '}
+					{productLegal(
+						countryGroupId,
+						contributionType,
+						'/',
+						thresholdAmount,
+						promotion,
+					)}{' '}
+					afterwards unless you cancel. Offer only available to new subscribers
+					who do not have an existing subscription with the Guardian.
+				</p>
+			)}
+			{productKey === 'SupporterPlus' && (
+				<>
+					<p>Auto renews every {period} until you cancel.</p>
+					<p>
+						Cancel or change your support anytime. If you cancel within the
+						first 14 days, you will receive a full refund.
+					</p>
+				</>
+			)}
+			{productKey === 'TierThree' && (
+				<p>Auto renews every {period}. Cancel anytime.</p>
+			)}
+		</div>
+	);
+	const contributeAdLiteTsAndCs = (
+		<div css={containerSummaryTsCs}>
+			<p>Auto renews every {period} until you cancel.</p>
+			<p>
+				{productKey === 'GuardianAdLite'
+					? 'Cancel anytime.'
+					: 'Cancel or change your support anytime.'}
+			</p>
+		</div>
+	);
+	const orderSummaryTsAndCs: Partial<Record<ActiveProductKey, JSX.Element>> = {
+		GuardianAdLite: contributeAdLiteTsAndCs,
+		Contribution: contributeAdLiteTsAndCs,
+		SupporterPlus: tierThreeSupporterPlusTsAndCs,
+		TierThree: tierThreeSupporterPlusTsAndCs,
+	};
+	return orderSummaryTsAndCs[productKey] ?? <></>;
path: support-frontend/assets/components/orderSummary/orderSummaryTsAndCs.tsx
user: login: paul-daniel-dempsey
body: @maloky : have applied a `null` check here (ass recommended [below](https://github.com/guardian/support-frontend/pull/6849#discussion_r2007279924)). Updated.
created_at: 2025-03-21T12:50:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,27 @@
+import { render } from '@testing-library/react';
+import type { CountryGroupId } from 'helpers/internationalisation/countryGroup';
+import type { ActiveProductKey } from 'helpers/productCatalog';
+import { OrderSummaryTsAndCs } from './orderSummaryTsAndCs';
+
+describe('Payment Ts&Cs Snapshot comparison', () => {
+	const paymentProductKeys = [
+		['GuardianAdLite', 'GBPCountries', 0],
+		['Contribution', 'UnitedStates', 0],
+		['SupporterPlus', 'GBPCountries', 12],
+		['TierThree', 'AUDCountries', 27],
+	];
+	it.each(paymentProductKeys)(
+		`orderSummaryTs&Cs render product %s for region %s correctly`,
+		(paymentProductKey, countryGroupId, amount) => {
+			const { container } = render(
+				<OrderSummaryTsAndCs
+					contributionType={'MONTHLY'}
path: support-frontend/assets/components/orderSummary/orderSummaryTsAndCs.test.tsx
user: login: GHaberis
body: Would it be worthwhile testing any alternative `contributionType` values if `OrderSummaryTsAndCs` renders different content dependent on the `contributionType`  passed to it?
created_at: 2025-03-21T15:49:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -587,20 +587,21 @@ export function CheckoutComponent({
 							);
 						}}
 						enableCheckList={true}
-						tsAndCsTier3={
-							productKey === 'TierThree'
-								? getTermsStartDateTier3(
-										formatUserDate(getTierThreeDeliveryDate()),
-								  )
-								: null
+						startDateTierThree={
path: support-frontend/assets/pages/[countryGroupId]/components/checkoutComponent.tsx
user: login: GHaberis
body: Do you see `OrderSummaryStartDate` being used for more products other than `TierThree`?

If `OrderSummaryStartDate` has one use case (for the `TierThree` product) in `startDateTierThree` then we could rename the component to `TierThreeOrderSummaryStartDate` and remove the conditional logic from inside the component for handling any `productKey`, based on the assumption it'll only be used for `TierThree`?

You'd need to do something like this here though...

```
startDateTierThree={productKey === 'TierThree' ? <TierThreeOrderSummaryStartDate ... /> : null}
```
created_at: 2025-03-21T16:03:17Z
author_association: CONTRIBUTOR
diff_hunk: @@ -5,22 +5,22 @@ import { PaymentTsAndCs } from './paymentTsAndCs';
 
 describe('Payment Ts&Cs Snapshot comparison', () => {
 	const paymentProductKeys = [
-		['Contribution', 'UnitedStates'],
-		['SupporterPlus', 'GBPCountries'],
-		['TierThree', 'GBPCountries'],
-		['OneTimeContribution', 'AUDCountries'],
-		['GuardianAdLite', 'GBPCountries'],
-		['DigitalSubscription', 'GBPCountries'],
+		['Contribution', 'UnitedStates', 0],
+		['SupporterPlus', 'GBPCountries', 12],
+		['TierThree', 'GBPCountries', 27],
+		['OneTimeContribution', 'AUDCountries', 0],
+		['GuardianAdLite', 'GBPCountries', 0],
+		['DigitalSubscription', 'GBPCountries', 0],
 	];
 	it.each(paymentProductKeys)(
 		`paymentTs&Cs render product %s for region %s correctly`,
-		(paymentProductKey, countryGroupId) => {
+		(paymentProductKey, countryGroupId, amount) => {
 			const { container } = render(
 				<PaymentTsAndCs
 					contributionType={'MONTHLY'}
path: support-frontend/assets/pages/supporter-plus-landing/components/paymentTsAndCs.test.tsx
user: login: GHaberis
body: Would it be worthwhile testing any alternative `contributionType` values if `PaymentTsAndCs` renders different content dependent on the `contributionType`  passed to it?
created_at: 2025-03-21T16:04:43Z
author_association: CONTRIBUTOR
diff_hunk: @@ -587,20 +587,21 @@ export function CheckoutComponent({
 							);
 						}}
 						enableCheckList={true}
-						tsAndCsTier3={
-							productKey === 'TierThree'
-								? getTermsStartDateTier3(
-										formatUserDate(getTierThreeDeliveryDate()),
-								  )
-								: null
+						startDateTierThree={
path: support-frontend/assets/pages/[countryGroupId]/components/checkoutComponent.tsx
user: login: paul-daniel-dempsey
body: I think I should of put a comment here, Helene was talking about using this component for the [observer - see note to right](https://www.figma.com/design/LF4FSOzeusjX057R1l7AUe/Observer---Q4---Q1-2025?node-id=2170-16168&t=rzlhEAJZQGnBHL1Q-1). However, would be easy to change later. Updated.
created_at: 2025-03-21T16:28:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,27 @@
+import { render } from '@testing-library/react';
+import type { CountryGroupId } from 'helpers/internationalisation/countryGroup';
+import type { ActiveProductKey } from 'helpers/productCatalog';
+import { OrderSummaryTsAndCs } from './orderSummaryTsAndCs';
+
+describe('Payment Ts&Cs Snapshot comparison', () => {
+	const paymentProductKeys = [
+		['GuardianAdLite', 'GBPCountries', 0],
+		['Contribution', 'UnitedStates', 0],
+		['SupporterPlus', 'GBPCountries', 12],
+		['TierThree', 'AUDCountries', 27],
+	];
+	it.each(paymentProductKeys)(
+		`orderSummaryTs&Cs render product %s for region %s correctly`,
+		(paymentProductKey, countryGroupId, amount) => {
+			const { container } = render(
+				<OrderSummaryTsAndCs
+					contributionType={'MONTHLY'}
path: support-frontend/assets/components/orderSummary/orderSummaryTsAndCs.test.tsx
user: login: paul-daniel-dempsey
body: Yes, have expanded to include `contributionType` = `MONTHLY` and `ANNUAL`. Also added a `PromoCode` test. Applied to stories and tests. Updated
created_at: 2025-03-21T17:57:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -5,22 +5,22 @@ import { PaymentTsAndCs } from './paymentTsAndCs';
 
 describe('Payment Ts&Cs Snapshot comparison', () => {
 	const paymentProductKeys = [
-		['Contribution', 'UnitedStates'],
-		['SupporterPlus', 'GBPCountries'],
-		['TierThree', 'GBPCountries'],
-		['OneTimeContribution', 'AUDCountries'],
-		['GuardianAdLite', 'GBPCountries'],
-		['DigitalSubscription', 'GBPCountries'],
+		['Contribution', 'UnitedStates', 0],
+		['SupporterPlus', 'GBPCountries', 12],
+		['TierThree', 'GBPCountries', 27],
+		['OneTimeContribution', 'AUDCountries', 0],
+		['GuardianAdLite', 'GBPCountries', 0],
+		['DigitalSubscription', 'GBPCountries', 0],
 	];
 	it.each(paymentProductKeys)(
 		`paymentTs&Cs render product %s for region %s correctly`,
-		(paymentProductKey, countryGroupId) => {
+		(paymentProductKey, countryGroupId, amount) => {
 			const { container } = render(
 				<PaymentTsAndCs
 					contributionType={'MONTHLY'}
path: support-frontend/assets/pages/supporter-plus-landing/components/paymentTsAndCs.test.tsx
user: login: paul-daniel-dempsey
body: Yes (like `orderSummaryTsAndCs.test.tsx`) have expanded to include contributionType = MONTHLY and ANNUAL. Also added a PromoCode test. Applied to stories and tests. Updated
created_at: 2025-03-21T18:20:08Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-03-13T09:10:15Z
body: ### [Deploy build 13883 of `support::stripe-patrons-data` to CODE](https://riffraff.gutools.co.uk/deployment/deployAgain?project=support%3A%3Astripe-patrons-data&build=13883&stage=CODE&updateStrategy=MostlyHarmless&action=deploy)
<details>
<summary>All deployment options</summary>

- [Deploy build 13883 of `support::stripe-patrons-data` to CODE](https://riffraff.gutools.co.uk/deployment/deployAgain?project=support%3A%3Astripe-patrons-data&build=13883&stage=CODE&updateStrategy=MostlyHarmless&action=deploy)
- [Deploy parts of build 13883 to CODE by previewing it first](https://riffraff.gutools.co.uk/preview/yaml?project=support%3A%3Astripe-patrons-data&build=13883&stage=CODE&updateStrategy=MostlyHarmless)
- [What's on CODE right now?](https://riffraff.gutools.co.uk/deployment/history?projectName=support%3A%3Astripe-patrons-data&stage=CODE)
</details>

---
_From [guardian/actions-riff-raff](https://github.com/guardian/actions-riff-raff)._
<!-- guardian/actions-riff-raff for support::stripe-patrons-data -->
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-03-13T09:11:02Z
body: **Size Change:** -276 B (-0.01%) 

**Total Size:** 1.95 MB

| Filename | Size | Change |  |
| :--- | :---: | :---: | :---: |
| `./public/compiled-assets/webpack/542.js` | 0 B | -37.6 kB (removed) | 🏆 |
| `./public/compiled-assets/webpack/816.js` | 37.4 kB | +37.4 kB (new file) | 🆕 |

<details><summary>ℹ️ <strong>View Unchanged</strong></summary>

| Filename | Size | Change |
| :--- | :---: | :---: |
| `./public/compiled-assets/javascripts/[countryGroupId]/events/router.js` | 92.6 kB | 0 B |
| `./public/compiled-assets/javascripts/[countryGroupId]/router.js` | 98 kB | +3 B (0%) |
| `./public/compiled-assets/javascripts/ausMomentMap.js` | 108 kB | 0 B |
| `./public/compiled-assets/javascripts/contributionsRedirectStyles.js` | 20 B | 0 B |
| `./public/compiled-assets/javascripts/digitalSubscriptionLandingPage.js` | 226 kB | 0 B |
| `./public/compiled-assets/javascripts/downForMaintenancePage.js` | 69.6 kB | 0 B |
| `./public/compiled-assets/javascripts/error404Page.js` | 69.5 kB | 0 B |
| `./public/compiled-assets/javascripts/error500Page.js` | 69.5 kB | 0 B |
| `./public/compiled-assets/javascripts/favicons.js` | 618 B | 0 B |
| `./public/compiled-assets/javascripts/paperSubscriptionCheckoutPage.js` | 167 kB | 0 B |
| `./public/compiled-assets/javascripts/paperSubscriptionLandingPage.js` | 89.9 kB | 0 B |
| `./public/compiled-assets/javascripts/payPalErrorPage.js` | 68 kB | 0 B |
| `./public/compiled-assets/javascripts/payPalErrorPageStyles.js` | 20 B | 0 B |
| `./public/compiled-assets/javascripts/promotionTerms.js` | 76 kB | 0 B |
| `./public/compiled-assets/javascripts/subscriptionsLandingPage.js` | 80.4 kB | 0 B |
| `./public/compiled-assets/javascripts/subscriptionsRedemptionPage.js` | 121 kB | 0 B |
| `./public/compiled-assets/javascripts/unsupportedBrowserStyles.js` | 20 B | 0 B |
| `./public/compiled-assets/javascripts/weeklySubscriptionCheckoutPage.js` | 163 kB | 0 B |
| `./public/compiled-assets/javascripts/weeklySubscriptionLandingPage.js` | 90.1 kB | 0 B |
| `./public/compiled-assets/webpack/142.js` | 7.57 kB | 0 B |
| `./public/compiled-assets/webpack/192.js` | 3.54 kB | 0 B |
| `./public/compiled-assets/webpack/236.js` | 24.2 kB | 0 B |
| `./public/compiled-assets/webpack/316.js` | 2.01 kB | 0 B |
| `./public/compiled-assets/webpack/490.js` | 6.92 kB | 0 B |
| `./public/compiled-assets/webpack/603.js` | 4.39 kB | 0 B |
| `./public/compiled-assets/webpack/630.js` | 12.2 kB | 0 B |
| `./public/compiled-assets/webpack/644.js` | 2.17 kB | 0 B |
| `./public/compiled-assets/webpack/696.js` | 9.04 kB | 0 B |
| `./public/compiled-assets/webpack/778.js` | 107 kB | 0 B |
| `./public/compiled-assets/webpack/783.js` | 26 kB | 0 B |
| `./public/compiled-assets/webpack/889.js` | 5.72 kB | 0 B |
| `./public/compiled-assets/webpack/944.js` | 21.6 kB | 0 B |
| `./public/compiled-assets/webpack/checkout.js` | 20.7 kB | -57 B (-0.28%) |
| `./public/compiled-assets/webpack/GuardianAdLiteLanding.js` | 8.15 kB | 0 B |
| `./public/compiled-assets/webpack/LandingPage.js` | 15.3 kB | 0 B |
| `./public/compiled-assets/webpack/oneTimeCheckout.js` | 6.16 kB | -2 B (-0.03%) |
| `./public/compiled-assets/webpack/ThankYou.js` | 45 kB | 0 B |

</details>



<a href="https://github.com/preactjs/compressed-size-action"><sub>compressed-size-action</sub></a>
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-03-13T09:11:52Z
body: ### [Deploy build 23147 of `support:support-workers-mono` to CODE](https://riffraff.gutools.co.uk/deployment/deployAgain?project=support%3Asupport-workers-mono&build=23147&stage=CODE&updateStrategy=MostlyHarmless&action=deploy)
<details>
<summary>All deployment options</summary>

- [Deploy build 23147 of `support:support-workers-mono` to CODE](https://riffraff.gutools.co.uk/deployment/deployAgain?project=support%3Asupport-workers-mono&build=23147&stage=CODE&updateStrategy=MostlyHarmless&action=deploy)
- [Deploy parts of build 23147 to CODE by previewing it first](https://riffraff.gutools.co.uk/preview/yaml?project=support%3Asupport-workers-mono&build=23147&stage=CODE&updateStrategy=MostlyHarmless)
- [What's on CODE right now?](https://riffraff.gutools.co.uk/deployment/history?projectName=support%3Asupport-workers-mono&stage=CODE)
</details>

---
_From [guardian/actions-riff-raff](https://github.com/guardian/actions-riff-raff)._
<!-- guardian/actions-riff-raff for support:support-workers-mono -->
author_association: CONTRIBUTOR
user: login: prout-bot
created_at: 2025-03-24T12:36:44Z
body: Seen on [PROD](https://support.theguardian.com/uk/subscribe) (merged by @paul-daniel-dempsey 9 minutes and 51 seconds ago) 
- Keep an eye out for the post deployment Playwright smoke tests [github action](https://github.com/guardian/support-frontend/actions/workflows/playwright-smoke.yml)
- If the tests have failed, the [post deployment test runbook](https://github.com/guardian/support-frontend/wiki/Post-deployment-test-runbook) should help troubleshoot.


#### Sentry Release: [support-client-side](https://sentry.io/the-guardian/support-client-side/releases/36963fdb262c22f73d6f5667329e5d5d7958d5b1/), [support](https://sentry.io/the-guardian/support/releases/36963fdb262c22f73d6f5667329e5d5d7958d5b1/)
author_association: NONE