From 8d7e695fa5a5cc091dea04b6b559b065ba8d0175 Mon Sep 17 00:00:00 2001 From: suweinberg Date: Sat, 6 Sep 2025 12:16:27 -0700 Subject: [PATCH 01/14] add ca content --- content/messages/CA/generic.json | 26 ++++++++++++ content/messages/CA/generic_fr.json | 28 +++++++++++++ content/messages/CA/short_term_nq.json | 26 ++++++++++++ content/messages/CA/short_term_nq_fr.json | 28 +++++++++++++ content/messages/CA/short_term_q.json | 26 ++++++++++++ content/messages/CA/short_term_q_fr.json | 28 +++++++++++++ content/modals/CA/short_term.json | 41 +++++++++++++++++++ content/modals/CA/short_term_fr.json | 41 +++++++++++++++++++ content/modals/CA/short_term_xo.json | 47 ++++++++++++++++++++++ content/modals/CA/short_term_xo_fr.json | 49 +++++++++++++++++++++++ 10 files changed, 340 insertions(+) create mode 100644 content/messages/CA/generic.json create mode 100644 content/messages/CA/generic_fr.json create mode 100644 content/messages/CA/short_term_nq.json create mode 100644 content/messages/CA/short_term_nq_fr.json create mode 100644 content/messages/CA/short_term_q.json create mode 100644 content/messages/CA/short_term_q_fr.json create mode 100644 content/modals/CA/short_term.json create mode 100644 content/modals/CA/short_term_fr.json create mode 100644 content/modals/CA/short_term_xo.json create mode 100644 content/modals/CA/short_term_xo_fr.json diff --git a/content/messages/CA/generic.json b/content/messages/CA/generic.json new file mode 100644 index 0000000000..3dc5407215 --- /dev/null +++ b/content/messages/CA/generic.json @@ -0,0 +1,26 @@ +{ + "meta": { + "id": "", + "offerCountry": "CA", + "offerType": "GENERIC", + "messageType": "GENERIC", + "offerTerm": "${CREDIT_OFFERS_DS.total_payments}", + "lander": "", + "variables": { + "financing_code": "${CREDIT_OFFERS_DS.financing_code}", + "formattedMonthlyPayment": "${CREDIT_OFFERS_DS.formattedMonthlyPayment}", + "total_payments": "${CREDIT_OFFERS_DS.total_payments}", + "minAmount": "${CREDIT_OFFERS_DS.minAmount}", + "maxAmount": "${CREDIT_OFFERS_DS.maxAmount}", + "formattedMinAmount": "${CREDIT_OFFERS_DS.formattedMinAmount}", + "formattedMaxAmount": "${CREDIT_OFFERS_DS.formattedMaxAmount}", + "formattedTotalCost": "${CREDIT_OFFERS_DS.formattedTotalCost}" + } + }, + "headline": [ + ["Buy now, pay later.", ["default", "xsmall"]], + ["Buy now and pay later.", ["xsmall.2"]] + ], + "subHeadline": [], + "disclaimer": [[" Learn more", ["default"]]] +} diff --git a/content/messages/CA/generic_fr.json b/content/messages/CA/generic_fr.json new file mode 100644 index 0000000000..ad8e66d341 --- /dev/null +++ b/content/messages/CA/generic_fr.json @@ -0,0 +1,28 @@ +{ + "meta": { + "id": "", + "offerCountry": "CA", + "offerType": "GENERIC", + "messageType": "GENERIC", + "offerTerm": "${CREDIT_OFFERS_DS.total_payments}", + "lander": "", + "variables": { + "financing_code": "${CREDIT_OFFERS_DS.financing_code}", + "formattedMonthlyPayment": "${CREDIT_OFFERS_DS.formattedMonthlyPayment}", + "total_payments": "${CREDIT_OFFERS_DS.total_payments}", + "minAmount": "${CREDIT_OFFERS_DS.minAmount}", + "maxAmount": "${CREDIT_OFFERS_DS.maxAmount}", + "formattedMinAmount": "${CREDIT_OFFERS_DS.formattedMinAmount}", + "formattedMaxAmount": "${CREDIT_OFFERS_DS.formattedMaxAmount}", + "formattedTotalCost": "${CREDIT_OFFERS_DS.formattedTotalCost}" + } + }, + "headline": [ + ["Achetez maintenant, payez plus tard.", ["default", "xsmall"]], + ["Achetez maintenant et payez plus tard.", ["xsmall.2"]] + ], + "subHeadline": [], + "disclaimer": [ + [" En savoir plus", ["default"]] + ] +} diff --git a/content/messages/CA/short_term_nq.json b/content/messages/CA/short_term_nq.json new file mode 100644 index 0000000000..150976d716 --- /dev/null +++ b/content/messages/CA/short_term_nq.json @@ -0,0 +1,26 @@ +{ + "meta": { + "id": "", + "offerCountry": "CA", + "offerType": "PAY_LATER_SHORT_TERM", + "messageType": "PLST_NQ", + "offerTerm": "${CREDIT_OFFERS_DS.total_payments}", + "lander": "", + "variables": { + "offer_id": "${CREDIT_OFFERS_DS.offer_id}", + "vendor_financing_id": "${CREDIT_OFFERS_DS.vendor_financing_id}", + "financing_code": "${CREDIT_OFFERS_DS.financing_code}", + "formattedPeriodicPayment": "${CREDIT_OFFERS_DS.formattedPeriodicPayment}" + } + }, + "headline": [ + ["Buy now, pay later.", ["default", "xsmall"]], + ["Buy now and pay later.", ["xsmall.2"]], + [ + "Pay in 4 interest-free payments on purchases of {formattedMinAmount}-{formattedMaxAmount}.", + ["medium", "large", "xlarge"] + ] + ], + "subHeadline": [], + "disclaimer": [[" Learn more", ["default"]]] +} diff --git a/content/messages/CA/short_term_nq_fr.json b/content/messages/CA/short_term_nq_fr.json new file mode 100644 index 0000000000..852a888289 --- /dev/null +++ b/content/messages/CA/short_term_nq_fr.json @@ -0,0 +1,28 @@ +{ + "meta": { + "id": "", + "offerCountry": "CA", + "offerType": "PAY_LATER_SHORT_TERM", + "messageType": "PLST_NQ", + "offerTerm": "${CREDIT_OFFERS_DS.total_payments}", + "lander": "", + "variables": { + "offer_id": "${CREDIT_OFFERS_DS.offer_id}", + "vendor_financing_id": "${CREDIT_OFFERS_DS.vendor_financing_id}", + "financing_code": "${CREDIT_OFFERS_DS.financing_code}", + "formattedPeriodicPayment": "${CREDIT_OFFERS_DS.formattedPeriodicPayment}" + } + }, + "headline": [ + ["Achetez maintenant, payez plus tard.", ["default", "xsmall"]], + ["Achetez maintenant et payez plus tard.", ["xsmall.2"]], + [ + "Payer en 4 versements sans intérêt pour les achats de {formattedMinAmount} à {formattedMaxAmount}.", + ["medium", "large", "xlarge"] + ] + ], + "subHeadline": [], + "disclaimer": [ + [" En savoir plus", ["default"]] + ] +} diff --git a/content/messages/CA/short_term_q.json b/content/messages/CA/short_term_q.json new file mode 100644 index 0000000000..0dcf6cc046 --- /dev/null +++ b/content/messages/CA/short_term_q.json @@ -0,0 +1,26 @@ +{ + "meta": { + "id": "", + "offerCountry": "CA", + "offerType": "PAY_LATER_SHORT_TERM", + "messageType": "PLST_SQ", + "offerTerm": "${CREDIT_OFFERS_DS.total_payments}", + "lander": "", + "variables": { + "offer_id": "${CREDIT_OFFERS_DS.offer_id}", + "vendor_financing_id": "${CREDIT_OFFERS_DS.vendor_financing_id}", + "financing_code": "${CREDIT_OFFERS_DS.financing_code}", + "formattedPeriodicPayment": "${CREDIT_OFFERS_DS.formattedPeriodicPayment}" + } + }, + "headline": [ + ["Buy now, pay later.", ["default", "xsmall"]], + [["Buy now and pay later."], ["xsmall.2"]], + [ + ["Pay in 4 interest-free payments of {formattedPeriodicPayment}", [".", "weak"]], + ["medium", "large", "xlarge"] + ] + ], + "subHeadline": [], + "disclaimer": [[" Learn more", ["default"]]] +} diff --git a/content/messages/CA/short_term_q_fr.json b/content/messages/CA/short_term_q_fr.json new file mode 100644 index 0000000000..2e47260fb1 --- /dev/null +++ b/content/messages/CA/short_term_q_fr.json @@ -0,0 +1,28 @@ +{ + "meta": { + "id": "", + "offerCountry": "CA", + "offerType": "PAY_LATER_SHORT_TERM", + "messageType": "PLST_SQ", + "offerTerm": "${CREDIT_OFFERS_DS.total_payments}", + "lander": "", + "variables": { + "offer_id": "${CREDIT_OFFERS_DS.offer_id}", + "vendor_financing_id": "${CREDIT_OFFERS_DS.vendor_financing_id}", + "financing_code": "${CREDIT_OFFERS_DS.financing_code}", + "formattedPeriodicPayment": "${CREDIT_OFFERS_DS.formattedPeriodicPayment}" + } + }, + "headline": [ + ["Achetez maintenant, payez plus tard.", ["default", "xsmall"]], + [["Achetez maintenant et payez plus tard."], ["xsmall.2"]], + [ + ["Payer en 4 versements sans intérêt de {formattedPeriodicPayment}", [".", "weak"]], + ["medium", "large", "xlarge"] + ] + ], + "subHeadline": [], + "disclaimer": [ + [" En savoir plus", ["default"]] + ] +} diff --git a/content/modals/CA/short_term.json b/content/modals/CA/short_term.json new file mode 100644 index 0000000000..19194822b8 --- /dev/null +++ b/content/modals/CA/short_term.json @@ -0,0 +1,41 @@ +{ + "meta": { + "product": "PAY_LATER_SHORT_TERM", + "periodicPayment": "{formattedPeriodicPayment}", + "minAmount": "{minAmount}", + "maxAmount": "{maxAmount}", + "qualifying": "{qualifying_offer}", + "amount": "{transaction_amount}", + "apr": "{apr}", + "useV5Design": "true", + "v5.1": "true", + "variables": { + "transaction_amount": "${eval(transaction_amount ? transaction_amount : '-')}", + "qualifying_offer": "${eval(CREDIT_OFFERS_DS.qualifying_offer ? CREDIT_OFFERS_DS.qualifying_offer : 'false')}", + "financing_code": "${CREDIT_OFFERS_DS.financing_code}", + "formattedPeriodicPayment": "${CREDIT_OFFERS_DS.formattedPeriodicPayment}", + "total_payments": "${CREDIT_OFFERS_DS.total_payments}", + "formattedMinAmount": "${CREDIT_OFFERS_DS.formattedMinAmount}", + "formattedMaxAmount": "${CREDIT_OFFERS_DS.formattedMaxAmount}", + "formattedTotalCost": "${CREDIT_OFFERS_DS.formattedTotalCost}", + "minAmount": "${CREDIT_OFFERS_DS.minAmount}", + "maxAmount": "${CREDIT_OFFERS_DS.maxAmount}", + "apr": "${CREDIT_OFFERS_DS.apr}", + "nominal_rate": "${CREDIT_OFFERS_DS.nominal_rate}" + } + }, + "content": { + "headline": "Pay in 4 interest-free payments", + "subheadline": "No impact on credit score and no late fees. Available for purchases of {formattedMinAmount} to {formattedMaxAmount}.", + "qualifyingSubheadline": "Split your purchase of {formattedTotalCost} into {total_payments} with no impact on credit score and no late fees.", + "donutTimestamps": ["Today", "2 weeks", "4 weeks", "6 weeks"], + "instructions": [ + "Choose PayPal at checkout to pay later with Pay in 4. ", + "Complete your purchase with a 25% first payment.", + "Use autopay for the rest of your payments. It's easy!" + ], + "disclosure": [ + "Pay in 4 is available to approved consumers for purchases of {formattedMinAmount} to {formattedMaxAmount} (CAD) for certain transaction types. Availability depends on the merchant. You must be age of majority in the province or territory where you live to apply. Any transactions in other currencies will be converted to Canadian dollars subject to applicable currency conversion charges. You may repay the amount you owe in full at any time, without any fees or charges." + ] + } +} diff --git a/content/modals/CA/short_term_fr.json b/content/modals/CA/short_term_fr.json new file mode 100644 index 0000000000..ff4d0c7516 --- /dev/null +++ b/content/modals/CA/short_term_fr.json @@ -0,0 +1,41 @@ +{ + "meta": { + "product": "PAY_LATER_SHORT_TERM", + "periodicPayment": "{formattedPeriodicPayment}", + "minAmount": "{minAmount}", + "maxAmount": "{maxAmount}", + "qualifying": "{qualifying_offer}", + "amount": "{transaction_amount}", + "apr": "{apr}", + "useV5Design": "true", + "v5.1": "true", + "variables": { + "transaction_amount": "${eval(transaction_amount ? transaction_amount : '-')}", + "qualifying_offer": "${eval(CREDIT_OFFERS_DS.qualifying_offer ? CREDIT_OFFERS_DS.qualifying_offer : 'false')}", + "financing_code": "${CREDIT_OFFERS_DS.financing_code}", + "formattedPeriodicPayment": "${CREDIT_OFFERS_DS.formattedPeriodicPayment}", + "total_payments": "${CREDIT_OFFERS_DS.total_payments}", + "formattedMinAmount": "${CREDIT_OFFERS_DS.formattedMinAmount}", + "formattedMaxAmount": "${CREDIT_OFFERS_DS.formattedMaxAmount}", + "formattedTotalCost": "${CREDIT_OFFERS_DS.formattedTotalCost}", + "minAmount": "${CREDIT_OFFERS_DS.minAmount}", + "maxAmount": "${CREDIT_OFFERS_DS.maxAmount}", + "apr": "${CREDIT_OFFERS_DS.apr}", + "nominal_rate": "${CREDIT_OFFERS_DS.nominal_rate}" + } + }, + "content": { + "headline": "Payer en 4 versements sans intérêt", + "subheadline": "Aucun impact sur la cote de crédit et aucuns frais de retard. Disponible pour les achats de {formattedMinAmount} à {formattedMaxAmount}.", + "qualifyingSubheadline": "Divisez le montant de {formattedTotalCost} en {total_payments} versements sans intérêt, sans incidence sur votre cote de crédit et sans frais de retard.", + "donutTimestamps": ["Exigible aujourd'hui", "2 semaines", "4 semaines", "6 semaines"], + "instructions": [ + "Choisissez PayPal à la caisse pour payer plus tard avec le Paiement en 4.", + "Terminez votre achat avec un premier paiement de 25 %.", + "Utilisez le paiement préapprouvé pour le reste de vos paiements. C'est facile !" + ], + "disclosure": [ + "Paiement en 4 est offert aux consommateurs approuvés pour les achats de {formattedMinAmount} à {formattedMaxAmount} (CAD) pour certains types de transactions. La disponibilité dépend du marchand. Vous devez avoir atteint l’âge de la majorité dans la province ou le territoire où vous résidez pour présenter une demande. Toutes les transactions dans d’autres devises seront converties en dollars canadiens, sous réserve des frais de conversion de devise applicables. Vous pouvez rembourser la totalité du montant que vous devez en tout temps, sans frais." + ] + } +} diff --git a/content/modals/CA/short_term_xo.json b/content/modals/CA/short_term_xo.json new file mode 100644 index 0000000000..ec88efb487 --- /dev/null +++ b/content/modals/CA/short_term_xo.json @@ -0,0 +1,47 @@ +{ + "meta": { + "product": "PAY_LATER_SHORT_TERM", + "periodicPayment": "{formattedPeriodicPayment}", + "minAmount": "{minAmount}", + "maxAmount": "{maxAmount}", + "qualifying": "{qualifying_offer}", + "amount": "{transaction_amount}", + "apr": "{apr}", + "useV5Design": "true", + + "variables": { + "transaction_amount": "${eval(transaction_amount ? transaction_amount : '-')}", + "qualifying_offer": "${eval(CREDIT_OFFERS_DS.qualifying_offer ? CREDIT_OFFERS_DS.qualifying_offer : 'false')}", + "financing_code": "${CREDIT_OFFERS_DS.financing_code}", + "formattedPeriodicPayment": "${CREDIT_OFFERS_DS.formattedPeriodicPayment}", + "total_payments": "${CREDIT_OFFERS_DS.total_payments}", + "formattedMinAmount": "${CREDIT_OFFERS_DS.formattedMinAmount}", + "formattedMaxAmount": "${CREDIT_OFFERS_DS.formattedMaxAmount}", + "formattedTotalCost": "${CREDIT_OFFERS_DS.formattedTotalCost}", + "minAmount": "${CREDIT_OFFERS_DS.minAmount}", + "maxAmount": "${CREDIT_OFFERS_DS.maxAmount}", + "apr": "${CREDIT_OFFERS_DS.apr}", + "nominal_rate": "${CREDIT_OFFERS_DS.nominal_rate}" + } + }, + "content": { + "headline": "Payer en 4", + "subheadline": "Aucun impact sur la cote de crédit et aucuns frais de retard. Disponible pour les achats de {formattedMinAmount} à {formattedMaxAmount}.", + "qualifyingSubheadline": "Divisez le montant de {formattedTotalCost} en {total_payments} versements sans intérêt, sans incidence sur votre cote de crédit et sans frais de retard.", + "donutTimestamps": ["Exigible aujourd'hui", "2 semaines", "4 semaines", "6 semaines"], + "instructions": { + "instructionsHeadline": "Comment fonctionne le Paiement en 4?", + "instructionsSubHeadline": [ + "Choisissez PayPal à la caisse pour payer plus tard avec le Paiement en 4. ", + "Terminez votre achat avec un premier paiement de 25 %.", + "Utilisez le paiement préapprouvé pour le reste de vos paiements. C'est facile !" + ] + }, + "cta": { + "buttonTextEligible": "Continuer avec le Paiement en 4", + "buttonTextIneligible": "Retour à la caisse", + "link": "https://www.paypal.com/link/to/short-term-application" + }, + "disclosure": "Paiement en 4 est offert aux consommateurs approuvés pour les achats de {formattedMinAmount} à {formattedMaxAmount} (CAD) pour certains types de transactions. La disponibilité dépend du marchand. Vous devez avoir atteint l’âge de la majorité dans la province ou le territoire où vous résidez pour présenter une demande. Toutes les transactions dans d’autres devises seront converties en dollars canadiens, sous réserve des frais de conversion de devise applicables. Vous pouvez rembourser la totalité du montant que vous devez en tout temps, sans frais." + } +} diff --git a/content/modals/CA/short_term_xo_fr.json b/content/modals/CA/short_term_xo_fr.json new file mode 100644 index 0000000000..d12290897b --- /dev/null +++ b/content/modals/CA/short_term_xo_fr.json @@ -0,0 +1,49 @@ +{ + "meta": { + "product": "PAY_LATER_SHORT_TERM", + "periodicPayment": "{formattedPeriodicPayment}", + "minAmount": "{minAmount}", + "maxAmount": "{maxAmount}", + "qualifying": "{qualifying_offer}", + "amount": "{transaction_amount}", + "apr": "{apr}", + "useV5Design": "true", + "v5.1": "true", + "variables": { + "transaction_amount": "${eval(transaction_amount ? transaction_amount : '-')}", + "qualifying_offer": "${eval(CREDIT_OFFERS_DS.qualifying_offer ? CREDIT_OFFERS_DS.qualifying_offer : 'false')}", + "financing_code": "${CREDIT_OFFERS_DS.financing_code}", + "formattedPeriodicPayment": "${CREDIT_OFFERS_DS.formattedPeriodicPayment}", + "total_payments": "${CREDIT_OFFERS_DS.total_payments}", + "formattedMinAmount": "${CREDIT_OFFERS_DS.formattedMinAmount}", + "formattedMaxAmount": "${CREDIT_OFFERS_DS.formattedMaxAmount}", + "formattedTotalCost": "${CREDIT_OFFERS_DS.formattedTotalCost}", + "minAmount": "${CREDIT_OFFERS_DS.minAmount}", + "maxAmount": "${CREDIT_OFFERS_DS.maxAmount}", + "apr": "${CREDIT_OFFERS_DS.apr}", + "nominal_rate": "${CREDIT_OFFERS_DS.nominal_rate}" + } + }, + "content": { + "headline": "French Pay in 4 interest-free payments", + "subheadline": "No impact on credit score and no late fees. Available for purchases of {formattedMinAmount} to {formattedMaxAmount}.", + "qualifyingSubheadline": "Split your purchase of {formattedTotalCost} into {total_payments} with no impact on credit score and no late fees.", + "donutTimestamps": ["Today", "2 weeks", "4 weeks", "6 weeks"], + "instructions": { + "instructionsHeadline": "How Pay in 4 works", + "instructionsSubHeadline": [ + "Choose PayPal at checkout to pay later with Pay in 4", + "Complete your purchase with a 25% first payment.", + "Use autopay for the rest of your payments. It's easy!" + ] + }, + "cta": { + "buttonTextEligible": "Continue with Pay in 4", + "buttonTextIneligible": "Back to Checkout", + "link": "https://www.paypal.com/link/to/short-term-application" + }, + "disclosure": [ + "Pay in 4 is available to approved consumers for purchases of {formattedMinAmount} to {formattedMaxAmount} (CAD) for certain transaction types. Availability depends on the merchant. You must be age of majority in the province or territory where you live to apply. Any transactions in other currencies will be converted to Canadian dollars subject to applicable currency conversion charges. You may repay the amount you owe in full at any time, without any fees or charges." + ] + } +} From e836e28e62918fc89218af8fce7f99e164f019d1 Mon Sep 17 00:00:00 2001 From: suweinberg Date: Sat, 6 Sep 2025 12:19:24 -0700 Subject: [PATCH 02/14] add ca msg styles --- src/server/locale/CA/index.js | 13 ++ src/server/locale/CA/mutations/index.js | 16 ++ .../locale/CA/mutations/short_term_nq.js | 157 ++++++++++++++++ .../locale/CA/mutations/short_term_q.js | 175 ++++++++++++++++++ src/server/locale/CA/styles/flex/base.css | 61 ++++++ src/server/locale/CA/styles/flex/index.js | 14 ++ .../locale/CA/styles/flex/ratio--1x1.css | 47 +++++ .../locale/CA/styles/flex/ratio--1x4.css | 46 +++++ .../locale/CA/styles/flex/ratio--20x1.css | 111 +++++++++++ .../locale/CA/styles/flex/ratio--6x1.css | 97 ++++++++++ .../locale/CA/styles/flex/ratio--8x1.css | 69 +++++++ src/server/locale/CA/styles/index.js | 7 + src/server/locale/CA/styles/text/index.js | 3 + src/server/locale/CA/validOptions.js | 32 ++++ 14 files changed, 848 insertions(+) create mode 100644 src/server/locale/CA/index.js create mode 100644 src/server/locale/CA/mutations/index.js create mode 100644 src/server/locale/CA/mutations/short_term_nq.js create mode 100644 src/server/locale/CA/mutations/short_term_q.js create mode 100644 src/server/locale/CA/styles/flex/base.css create mode 100644 src/server/locale/CA/styles/flex/index.js create mode 100644 src/server/locale/CA/styles/flex/ratio--1x1.css create mode 100644 src/server/locale/CA/styles/flex/ratio--1x4.css create mode 100644 src/server/locale/CA/styles/flex/ratio--20x1.css create mode 100644 src/server/locale/CA/styles/flex/ratio--6x1.css create mode 100644 src/server/locale/CA/styles/flex/ratio--8x1.css create mode 100644 src/server/locale/CA/styles/index.js create mode 100644 src/server/locale/CA/styles/text/index.js create mode 100644 src/server/locale/CA/validOptions.js diff --git a/src/server/locale/CA/index.js b/src/server/locale/CA/index.js new file mode 100644 index 0000000000..8cdfdcb6b2 --- /dev/null +++ b/src/server/locale/CA/index.js @@ -0,0 +1,13 @@ +import validOptions from './validOptions'; +import getMutations from './mutations'; +import logos from '../../message/logos'; +import styles from './styles'; + +export default { + localeClass: 'locale--CA', + productName: ['with', 'PayPal.'], + validOptions, + getMutations, + logos, + styles +}; diff --git a/src/server/locale/CA/mutations/index.js b/src/server/locale/CA/mutations/index.js new file mode 100644 index 0000000000..90d8c34a04 --- /dev/null +++ b/src/server/locale/CA/mutations/index.js @@ -0,0 +1,16 @@ +/* eslint-disable eslint-comments/disable-enable-pair */ +// mutations import here. +import shortTermNQ from './short_term_nq'; +import shortTermQ from './short_term_q'; + +export default function getMutations(id, type) { + switch (id) { + case 'GPLQ': + case 'PLST_SQ': + return shortTermQ[type]; + case 'GPLNQ': + case 'PLST_NQ': + default: + return shortTermNQ[type]; + } +} diff --git a/src/server/locale/CA/mutations/short_term_nq.js b/src/server/locale/CA/mutations/short_term_nq.js new file mode 100644 index 0000000000..629daf32e1 --- /dev/null +++ b/src/server/locale/CA/mutations/short_term_nq.js @@ -0,0 +1,157 @@ +import Logo from '../../../message/logos'; +import { + textWrap, + messageLogoWidth, + altNoWrap, + setLogoTop, + xSmallFallback, + logo20x1 +} from '../../../message/mediaQueries'; +import { flexLogoMutations, textLogoMutations } from '../../../message/logoMutations'; + +const flex = [ + [ + 'default', + { + logo: Logo.PP_PAYPAL.WHITE, + headline: [ + { + tag: 'xsmall' + }, + { + tag: 'medium' + } + ], + disclaimer: ['default'] + } + ], + [ + 'ratio:20x1', + { + styles: [logo20x1()] + } + ], + [ + 'ratio:8x1', + { + headline: [ + { + tag: 'xsmall' + }, + { + tag: 'medium', + br: ['on'] + } + ], + styles: [ + `@media (min-aspect-ratio: 60/11) and (min-width: 324px) { + .message__headline .tag--medium .br:first-child { + display: inline; + } + } + ` + ] + } + ], + ['color:white-no-border', { logo: Logo.PP_PAYPAL.COLOR }], + ...flexLogoMutations +]; + +export default { + 'layout:flex': flex, + 'layout:text': [ + [ + 'default', + ({ textSize }) => ({ + styles: [ + textWrap(textSize * 39.5, textSize, 'CA'), + xSmallFallback(textSize * 16), + messageLogoWidth(false, textSize * 4, textSize * 1.25), + setLogoTop(textSize * 20) + ], + logo: Logo.PP_PAYPAL.COLOR, + headline: [ + { + tag: 'medium', + br: ['of'] + }, + { tag: 'xsmall' } + ], + disclaimer: ['default'] + }) + ], + [ + 'logo.type:primary && logo.position:right', + ({ textSize }) => ({ + styles: [ + xSmallFallback(textSize * 16), + setLogoTop(textSize * 40), + messageLogoWidth(textSize * 6, textSize * 4, textSize * 1.25) + ] + }) + ], + [ + 'logo.type:primary && logo.position:top', + ({ textSize }) => ({ + styles: [ + xSmallFallback(textSize * 14.75 + 10), + messageLogoWidth(textSize * 6, textSize * 4, textSize * 1.25) + ] + }) + ], + [ + 'logo.type:alternative', + ({ textSize }) => ({ + styles: [ + `@media screen and (max-width: ${textSize * 10.6}px) { .message__content { white-space: nowrap; }}`, + textWrap(textSize * 37, textSize, 'CA'), + xSmallFallback(textSize * 15.4), + altNoWrap(textSize * 10.6), + messageLogoWidth(textSize * 1.75, textSize * 4, textSize * 1.25), + `.locale--CA .message__headline > .tag--medium > span { white-space: normal }`, + `@media screen and (max-width: ${ + textSize * 12.5 + }px) {.locale--CA .message__headline > .tag--xsmall > span { white-space: normal }}` + ], + logo: Logo.PP_PAYPAL.COLOR[0] + }) + ], + [ + 'logo.type:none', + ({ textSize }) => ({ + styles: [xSmallFallback(textSize * 18)], + logo: false, + headline: [ + { + tag: 'medium', + br: ['on'], + replace: [['00.', '00']] + }, + { + tag: 'xsmall.2', + replace: [['later.', 'later']] + } + ] + }) + ], + [ + 'logo.type:inline', + ({ textSize }) => ({ + styles: [xSmallFallback(textSize * 18), `.message__logo { width: ${textSize * 4}px }`], + logo: Logo.NO_PP_MONOGRAM.COLOR, + headline: [ + { + tag: 'medium', + br: ['on'], + replace: [['00.', '00']] + }, + { + tag: 'xsmall.2', + replace: [['later.', 'later']] + } + ] + }) + ], + ...textLogoMutations + ] +}; diff --git a/src/server/locale/CA/mutations/short_term_q.js b/src/server/locale/CA/mutations/short_term_q.js new file mode 100644 index 0000000000..5bf3e2adb2 --- /dev/null +++ b/src/server/locale/CA/mutations/short_term_q.js @@ -0,0 +1,175 @@ +import Logo from '../../../message/logos'; +import { + textWrap, + messageLogoWidth, + altNoWrap, + setLogoTop, + xSmallFallback, + logo20x1, + addPeriod +} from '../../../message/mediaQueries'; +import { flexLogoMutations, textLogoMutations } from '../../../message/logoMutations'; + +const flex = [ + [ + 'default', + { + logo: Logo.PP_PAYPAL.WHITE, + headline: [ + { + tag: 'xsmall' + }, + { + tag: 'medium' + } + ], + disclaimer: ['default'], + styles: [ + '.message__headline .tag--medium > span:first-child:after { content: "."; }', + '.message__headline .tag--medium .weak { display: none; }' + ] + } + ], + [ + 'ratio:20x1', + { + styles: [ + logo20x1(), + '.message__headline .tag--medium > span:first-child:after { content: "."; }', + '.message__headline .tag--medium .weak { display: none; }' + ] + } + ], + [ + 'ratio:8x1', + { + headline: [ + { + tag: 'xsmall' + }, + { + tag: 'medium', + br: ['payments'] + } + ], + styles: [ + '.message__headline .tag--medium > span:first-child > span:last-child:after { content: "."; }', + '.message__headline .tag--medium .weak { display: none; }' + ] + } + ], + ['color:white-no-border', { logo: Logo.PP_PAYPAL.COLOR }], + ...flexLogoMutations +]; + +export default { + 'layout:flex': flex, + 'layout:text': [ + [ + 'default', + ({ textSize }) => ({ + styles: [ + textWrap(textSize * 32, textSize, 'CA'), + xSmallFallback(textSize * 16), + messageLogoWidth(false, textSize * 4, textSize * 1.25), + setLogoTop(textSize * 16), + `.message__headline > .tag--medium > span:not(.weak):first-child {white-space: nowrap;}`, + `.weak { display: none}`, + addPeriod() + ], + logo: Logo.PP_PAYPAL.COLOR, + headline: [ + { + tag: 'medium', + br: ['payments'] + }, + { tag: 'xsmall' } + ], + disclaimer: ['default'] + }) + ], + [ + 'logo.type:primary && logo.position:right', + ({ textSize }) => ({ + styles: [ + `@media screen and (max-width: ${ + textSize * 18.5 + }px) { .message__headline > .tag--medium > span > span:first-child { white-space: normal; } } + .message__headline > .tag--medium > span:not(.weak):first-child {white-space: nowrap;}`, + xSmallFallback(textSize * 10.75), + setLogoTop(textSize * 32), + messageLogoWidth(textSize * 6, textSize * 4, textSize * 1.25), + `.weak { display: none}`, + addPeriod() + ] + }) + ], + [ + 'logo.type:primary && logo.position:top', + ({ textSize }) => ({ + styles: [ + `@media screen and (max-width: ${ + textSize * 18.5 + }px) { .message__headline > .tag--medium > span > span:first-child { white-space: normal; } } + .message__headline > .tag--medium > span:not(.weak):first-child {white-space: nowrap;}`, + xSmallFallback(textSize * 10.75), + messageLogoWidth(textSize * 6, textSize * 4, textSize * 1.25), + `.weak { display: none}`, + addPeriod() + ] + }) + ], + [ + 'logo.type:alternative', + ({ textSize }) => ({ + styles: [ + `@media screen and (max-width: ${textSize * 10.6}px) { .message__content { white-space: nowrap; }}`, + textWrap(textSize * 32, textSize, 'CA'), + xSmallFallback(textSize * 11.5), + altNoWrap(textSize * 10.6), + messageLogoWidth(textSize * 1.75, textSize * 4, textSize * 1.25), + `.weak { display: none}`, + addPeriod() + ], + logo: Logo.PP_PAYPAL.COLOR[0] + }) + ], + [ + 'logo.type:none', + ({ textSize }) => ({ + styles: [xSmallFallback(textSize * 18)], + logo: false, + headline: [ + { + tag: 'medium', + br: ['on'], + replace: [['purchases.', 'purchases']] + }, + { + tag: 'xsmall.2', + replace: [['later.', 'later']] + } + ] + }) + ], + [ + 'logo.type:inline', + ({ textSize }) => ({ + styles: [xSmallFallback(textSize * 18), `.message__logo { width: ${textSize * 4}px }`], + logo: Logo.NO_PP_MONOGRAM.COLOR, + headline: [ + { + tag: 'medium', + br: ['on'], + replace: [['purchases.', 'purchases']] + }, + { + tag: 'xsmall.2', + replace: [['later.', 'later']] + } + ] + }) + ], + ...textLogoMutations + ] +}; diff --git a/src/server/locale/CA/styles/flex/base.css b/src/server/locale/CA/styles/flex/base.css new file mode 100644 index 0000000000..445d774119 --- /dev/null +++ b/src/server/locale/CA/styles/flex/base.css @@ -0,0 +1,61 @@ +.message__logo-container { + display: flex; + align-items: center; +} + +.message__headline { + font-size: 8.4vw; + font-weight: 500; + line-height: 1.6em; +} + +.message__disclaimer { + position: static; +} + +.message__disclaimer > span { + font-weight: 400; + text-decoration: none; + white-space: normal; +} + +.message__disclaimer > span > span { + white-space: nowrap; +} + +.message__disclaimer > span > span:only-child, +.message__disclaimer > span > span.em { + text-decoration: underline; +} + +.message__logo:nth-of-type(1) { + width: 27px; + display: inline-block; + margin-right: 10px; +} + +.message__logo:nth-of-type(2) { + width: 89px; + display: inline-block; +} + +.message__headline strong::after { + content: '.'; + color: white; + font-style: normal; + font-weight: normal; +} + +.message__headline > span:nth-child(2) > strong { + font-weight: 500; +} + +.message__headline > span:nth-child(3) > strong { + font-weight: 500; +} + +@media (min-width: 220px) { + .message__disclaimer { + font-size: 0.9rem; + } +} diff --git a/src/server/locale/CA/styles/flex/index.js b/src/server/locale/CA/styles/flex/index.js new file mode 100644 index 0000000000..fde5efa898 --- /dev/null +++ b/src/server/locale/CA/styles/flex/index.js @@ -0,0 +1,14 @@ +import base from './base.css'; +import ratio1x1 from './ratio--1x1.css'; +import ratio1x4 from './ratio--1x4.css'; +import ratio6x1 from './ratio--6x1.css'; +import ratio8x1 from './ratio--8x1.css'; +import ratio20x1 from './ratio--20x1.css'; + +export default [ + ['default', base], + ['ratio:1x1', ratio1x1], + ['ratio:1x4', ratio1x4], + ['ratio:8x1', [ratio6x1, ratio8x1].join('\n')], + ['ratio:20x1', [ratio6x1, ratio20x1].join('\n')] +]; diff --git a/src/server/locale/CA/styles/flex/ratio--1x1.css b/src/server/locale/CA/styles/flex/ratio--1x1.css new file mode 100644 index 0000000000..29d6dfa4c4 --- /dev/null +++ b/src/server/locale/CA/styles/flex/ratio--1x1.css @@ -0,0 +1,47 @@ +.message__disclaimer span.multi:nth-of-type(1) { + display: none; +} + +.message__headline span.multi:nth-of-type(2) { + display: none; +} + +.message__logo-container { + width: 100%; + margin-bottom: 12%; +} + +.message__logo:nth-of-type(1) { + width: 29px; + max-width: 15%; + margin-right: 0px; +} + +.message__logo:nth-of-type(2) { + width: 91px; + max-width: 45%; + margin-left: 3%; +} + +.message__headline { + font-size: 10vw; + line-height: 1.55em; +} + +@media (min-width: 140px) { + .message__headline { + font-size: 8.4vw; + } + + .message__headline span.multi:nth-of-type(1) { + display: none; + } + + .message__headline span.multi:nth-of-type(2) { + display: inline; + } + + .message__disclaimer span.multi:nth-of-type(1) { + display: inline; + } +} diff --git a/src/server/locale/CA/styles/flex/ratio--1x4.css b/src/server/locale/CA/styles/flex/ratio--1x4.css new file mode 100644 index 0000000000..2c89e80822 --- /dev/null +++ b/src/server/locale/CA/styles/flex/ratio--1x4.css @@ -0,0 +1,46 @@ +.message__logo-container { + width: 100%; + margin-top: 3%; + margin-bottom: 0; +} + +.message__messaging { + height: 100%; + transform: translateY(-80px); + display: flex; + flex-direction: column; + justify-content: center; +} + +.message__headline { + font-size: 1.1rem; + margin-bottom: 10%; +} + +.message__sub-headline { + display: none; +} + +.message__disclaimer { + font-size: 0.9rem; +} + +.message__disclaimer span.multi:nth-of-type(1) { + display: inline; +} + +.message__headline .tag--xsmall { + display: none; +} + +@media (min-height: 500px) { + .message__headline { + font-size: 1.7rem; + } +} + +@media (aspect-ratio: 1/2) { + .message__messaging { + transform: translateY(-40px); + } +} diff --git a/src/server/locale/CA/styles/flex/ratio--20x1.css b/src/server/locale/CA/styles/flex/ratio--20x1.css new file mode 100644 index 0000000000..a2fb507fb5 --- /dev/null +++ b/src/server/locale/CA/styles/flex/ratio--20x1.css @@ -0,0 +1,111 @@ +@media (min-aspect-ratio: 200/11) { + .message__logo-container { + margin-bottom: -3px; + max-width: 12%; + margin-right: 1.5vw; + } + + .message__logo:nth-of-type(1) { + width: 15%; + margin-right: 3%; + } + + .message__logo:nth-of-type(2) { + width: 55%; + } + + .message__promo-container { + width: unset; + } + + .message__messaging { + flex: none; + display: inline; + } + + .message__content { + justify-content: center; + } + + .message__sub-headline { + margin-left: 0; + } + + .message__disclaimer { + margin-left: 7px; + } +} + +@media (min-aspect-ratio: 200/11) and (min-width: 351px) { + .message__disclaimer { + font-size: 0.8rem; + } +} +@media (min-aspect-ratio: 200/11) and (min-width: 903px) { + .message__logo-container { + margin-bottom: -6px; + } +} +@media (min-aspect-ratio: 200/11) and (min-width: 400px) { + .message__headline { + font-size: 2vw; + } + + .message__headline > span:nth-of-type(3) { + display: inline; + } + + .message__logo:nth-of-type(1) { + width: 20%; + margin-right: 5%; + } + + .message__logo:nth-of-type(2) { + display: inline-block; + width: 60%; + } +} + +@media (min-aspect-ratio: 200/11) and (min-width: 523px) { + .message__headline span.multi:nth-of-type(1) { + display: none; + } + + .message__headline span.multi:nth-of-type(2) { + display: inline; + } +} + +@media (min-aspect-ratio: 200/11) and (max-width: 600px) { + .message__logo:nth-of-type(2) { + display: none; + } + + .message__logo:nth-of-type(1) { + width: auto; + } + + .message__logo-container { + max-width: 18%; + } +} + +@media (min-aspect-ratio: 200/11) and (min-width: 401px) and (max-width: 522px) { + .message__logo-container { + max-width: 18%; + } + + .message__headline { + font-size: 2.75vw; + } + + .message__headline > span:nth-of-type(3) { + display: none; + } +} + +@media (min-aspect-ratio: 200/11) and (max-width: 350px) { + .message__headline { + font-size: 10px; + } +} diff --git a/src/server/locale/CA/styles/flex/ratio--6x1.css b/src/server/locale/CA/styles/flex/ratio--6x1.css new file mode 100644 index 0000000000..3c5ba63f5f --- /dev/null +++ b/src/server/locale/CA/styles/flex/ratio--6x1.css @@ -0,0 +1,97 @@ +/* Not a valid style option ratio, but used as the mobile base for 8x1 and 20x1 */ + +.message__logo:nth-of-type(2) { + display: none; +} + +.message__headline { + font-size: 4vw; +} + +/* remove extra "with Flex" */ +.message__headline > span:nth-of-type(3) { + display: none; +} + +.message__disclaimer { + font-size: 0.7rem; +} + +@media (max-aspect-ratio: 61/10) and (min-width: 324px) { + .message__headline span.multi:nth-of-type(2) { + display: inline; + } + .message__headline span.multi:nth-of-type(1) { + display: none; + } + .message__headline > span:nth-of-type(3) { + display: inline; + } + .message__headline .tag--medium .br:first-child { + display: block; + } + .message__logo:nth-of-type(1) { + width: 45%; + } +} + +@media (max-aspect-ratio: 61/10) { + .message__headline { + font-size: 5vw; + line-height: 1.3em; + display: inline; + } + .message__logo-container { + flex-basis: 12%; + margin-bottom: -6px; + justify-content: flex-start; + margin-left: 5px; + } + .message__logo:nth-of-type(1) { + margin-left: 10px; + margin-right: 0; + } +} + +@media (max-aspect-ratio: 61/10) and (max-width: 374px) { + .message__logo:nth-of-type(1) { + width: 50%; + } +} + +@media (max-width: 374px) { + .message__headline { + font-size: 5vw; + } + + .message__logo:nth-of-type(1) { + width: 55%; + } + + .message__logo-container { + margin-right: 2.5%; + } + + .weak { + margin-left: -1.6%; + } +} + +@media (max-aspect-ratio: 61/10) and (max-width: 767px) { + .message__headline::after { + content: ' '; + } +} + +@media (max-aspect-ratio: 61/10) and (max-width: 323px) { + .message__logo-container { + margin-right: 7%; + } + .message__logo:nth-of-type(1) { + margin: 0 5px; + width: 30%; + } + .message__logo:nth-of-type(2) { + display: inline; + } +} diff --git a/src/server/locale/CA/styles/flex/ratio--8x1.css b/src/server/locale/CA/styles/flex/ratio--8x1.css new file mode 100644 index 0000000000..836e4da74b --- /dev/null +++ b/src/server/locale/CA/styles/flex/ratio--8x1.css @@ -0,0 +1,69 @@ +@media (min-aspect-ratio: 80/11) { + .message__headline { + display: inline; + padding-right: 0; + margin-right: 0; + line-height: 1.3em; + } + + .message__logo-container { + flex-basis: 12%; + margin-bottom: -6px; + justify-content: flex-start; + margin-left: 5px; + } + + .message__logo:nth-of-type(1) { + width: 50%; + margin-left: 10px; + margin-right: 0; + } + + .message__disclaimer { + margin-left: 7px; + } +} + +@media (min-aspect-ratio: 80/11) and (min-width: 501px) { + .message__logo-container { + flex-basis: 22%; + } + + .message__logo:nth-of-type(1) { + width: 18%; + margin-right: 5%; + } + + .message__logo:nth-of-type(2) { + display: inline-block; + width: 55%; + } + + .message__disclaimer { + font-size: 0.9rem; + } +} + +@media (min-aspect-ratio: 80/11) and (min-width: 375px) { + .message__headline > span:nth-of-type(3) { + display: inline; + } +} + +@media (min-aspect-ratio: 80/11) and (min-width: 351px) { + .message__headline { + font-size: 3.5vw; + } +} + +@media (min-aspect-ratio: 80/11) and (max-width: 350px) { + .message__headline { + font-size: 10px; + } +} + +@media (min-aspect-ratio: 80/11) and (min-width: 360px) { + .message__messaging { + line-height: 1.3rem; + } +} diff --git a/src/server/locale/CA/styles/index.js b/src/server/locale/CA/styles/index.js new file mode 100644 index 0000000000..ece1e4a42b --- /dev/null +++ b/src/server/locale/CA/styles/index.js @@ -0,0 +1,7 @@ +import text from './text'; +import flex from './flex'; + +export default { + 'layout:flex': flex, + 'layout:text': text +}; diff --git a/src/server/locale/CA/styles/text/index.js b/src/server/locale/CA/styles/text/index.js new file mode 100644 index 0000000000..f76a3b916d --- /dev/null +++ b/src/server/locale/CA/styles/text/index.js @@ -0,0 +1,3 @@ +import sharedGPLTextStyles from '../../../common/styles/GPL/text'; + +export default [...sharedGPLTextStyles]; diff --git a/src/server/locale/CA/validOptions.js b/src/server/locale/CA/validOptions.js new file mode 100644 index 0000000000..9f9d5fa2a6 --- /dev/null +++ b/src/server/locale/CA/validOptions.js @@ -0,0 +1,32 @@ +import { Types } from '../../types'; + +export default { + text: { + logo: { + type: [Types.STRING, ['primary', 'alternative', 'inline', 'none']], + position: [Types.STRING, ['left', 'right', 'top']] + }, + text: { + color: [Types.STRING, ['black', 'white', 'monochrome', 'grayscale|greyscale']], + size: [Types.NUMBER, [12, 10, 11, 13, 14, 15, 16]], + align: [Types.STRING, ['left', 'right', 'center']], + fontFamily: [Types.ANY], + fontSource: [Types.ANY] + } + }, + flex: { + color: [ + Types.STRING, + ['blue', 'black', 'white', 'white-no-border', 'gray|grey', 'monochrome', 'grayscale|greyscale'] + ], + ratio: [Types.STRING, ['1x1', '1x4', '8x1', '20x1']], + text: { + fontFamily: [Types.ANY], + fontSource: [Types.ANY] + } + }, + custom: { + markup: [Types.STRING], + ratio: [Types.ANY] + } +}; From 50894863040d135c22fa1947ab3cf7d7c88d2842 Mon Sep 17 00:00:00 2001 From: suweinberg Date: Sat, 6 Sep 2025 12:20:32 -0700 Subject: [PATCH 03/14] add ca test accts --- .../v2/config/CA/DEV_CA_SHORT_TERM.js | 36 ++++++++ .../config/CA/DEV_CA_SHORT_TERM_CHECKOUT.js | 37 ++++++++ tests/functional/v2/config/CA/index.js | 2 + tests/functional/v2/config/index.js | 1 + utils/devServerProxy/config/CA/index.js | 86 +++++++++++++++++++ .../config/devAccountsV2.config.js | 4 +- 6 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 tests/functional/v2/config/CA/DEV_CA_SHORT_TERM.js create mode 100644 tests/functional/v2/config/CA/DEV_CA_SHORT_TERM_CHECKOUT.js create mode 100644 tests/functional/v2/config/CA/index.js create mode 100644 utils/devServerProxy/config/CA/index.js diff --git a/tests/functional/v2/config/CA/DEV_CA_SHORT_TERM.js b/tests/functional/v2/config/CA/DEV_CA_SHORT_TERM.js new file mode 100644 index 0000000000..3a8a11ef0e --- /dev/null +++ b/tests/functional/v2/config/CA/DEV_CA_SHORT_TERM.js @@ -0,0 +1,36 @@ +export const DEV_CA_SHORT_TERM = { + testFileName: 'shortTerm', + country: 'CA', + description: 'CA merchant eligible for short term only', + minAmount: 30, + maxAmount: 1500, + amounts: [ + { + value: '0.00', + message: 'Non-qualifying Pay in 4', + expectedValue: 'Pay in 4 interest-free payments on qualifying purchases', + modalContent: { + subheadline: 'No impact on credit score and no late fees. Available for purchases of $30 to $1,500.', + periodicPayment: null + } + }, + { + value: '30.00', + message: 'Qualifying Pay in 4', + expectedValue: 'Pay in 4 interest-free payments of $7.50', + modalContent: { + subheadline: 'Split your purchase of $30.00 into 4 with no impact on credit score and no late fees.', + periodicPayment: '$7.50' + } + }, + { + value: '1500.01', + message: 'Non-qualifying Pay in 4', + expectedValue: 'Pay in 4 interest-free payments on qualifying purchases', + modalContent: { + subheadline: 'No impact on credit score and no late fees. Available for purchases of $30 to $1,500.', + periodicPayment: '' + } + } + ] +}; diff --git a/tests/functional/v2/config/CA/DEV_CA_SHORT_TERM_CHECKOUT.js b/tests/functional/v2/config/CA/DEV_CA_SHORT_TERM_CHECKOUT.js new file mode 100644 index 0000000000..cba39db80e --- /dev/null +++ b/tests/functional/v2/config/CA/DEV_CA_SHORT_TERM_CHECKOUT.js @@ -0,0 +1,37 @@ +export const DEV_CA_SHORT_TERM_CHECKOUT = { + testFileName: 'shortTerm', + country: 'CA', + description: 'CA merchant eligible for short term only', + minAmount: 30, + maxAmount: 1500, + amounts: [ + { + value: '0.00', + message: 'Non-qualifying Pay in 4', + expectedValue: 'Pay in 4 interest-free payments on qualifying purchases', + modalContent: { + subheadline: 'No impact on credit score and no late fees. Available for purchases of $30 to $1,500.', + periodicPayment: null + } + }, + { + value: '30.00', + message: 'Qualifying Pay in 4', + expectedValue: 'Pay in 4 interest-free payments of $7.50', + modalContent: { + subheadline: + 'Split $30.00 into 4 interest-free payments with no impact on credit score and no late fees.', + periodicPayment: '$7.50' + } + }, + { + value: '1500.01', + message: 'Non-qualifying Pay in 4', + expectedValue: 'Pay in 4 interest-free payments on qualifying purchases', + modalContent: { + subheadline: 'No impact on credit score and no late fees. Available for purchases of $30 to $1,500.', + periodicPayment: '' + } + } + ] +}; diff --git a/tests/functional/v2/config/CA/index.js b/tests/functional/v2/config/CA/index.js new file mode 100644 index 0000000000..40939a1103 --- /dev/null +++ b/tests/functional/v2/config/CA/index.js @@ -0,0 +1,2 @@ +export { DEV_CA_SHORT_TERM } from './DEV_CA_SHORT_TERM'; +export { DEV_CA_SHORT_TERM_CHECKOUT } from './DEV_CA_SHORT_TERM_CHECKOUT'; diff --git a/tests/functional/v2/config/index.js b/tests/functional/v2/config/index.js index baebf4c682..4cfda967f3 100644 --- a/tests/functional/v2/config/index.js +++ b/tests/functional/v2/config/index.js @@ -6,3 +6,4 @@ export * as ES from './ES'; export * as IT from './IT'; export * as FR from './FR'; export * as DE from './DE'; +export * as CA from './CA'; diff --git a/utils/devServerProxy/config/CA/index.js b/utils/devServerProxy/config/CA/index.js new file mode 100644 index 0000000000..dbfd2c67f8 --- /dev/null +++ b/utils/devServerProxy/config/CA/index.js @@ -0,0 +1,86 @@ +export default { + DEV_CA_SHORT_TERM: { + country: 'CA', + modalViews: [ + { + template: 'short_term.json', + product: 'PAY_LATER_SHORT_TERM' + } + ], + messageThresholds: [ + { + amount: 1500.01, + template: 'short_term_nq.json', + product: 'PAY_LATER_SHORT_TERM' + }, + { + amount: 30, + template: 'short_term_q.json', + product: 'PAY_LATER_SHORT_TERM' + }, + { + amount: 0.01, + template: 'short_term_nq.json', + product: 'PAY_LATER_SHORT_TERM' + }, + { + amount: 0, + template: 'generic.json', + product: 'PAY_LATER_SHORT_TERM' + } + ], + offers: { + PAY_LATER_SHORT_TERM: [ + { + totalPayments: 4, + apr: 0, + nominalRate: 0, + minAmount: 30, + maxAmount: 1500 + } + ] + } + }, + DEV_CA_SHORT_TERM_CHECKOUT: { + country: 'CA', + modalViews: [ + { + template: 'short_term_xo.json', + product: 'PAY_LATER_SHORT_TERM' + } + ], + messageThresholds: [ + { + amount: 1500.01, + template: 'short_term_nq.json', + product: 'PAY_LATER_SHORT_TERM' + }, + { + amount: 30, + template: 'short_term_q.json', + product: 'PAY_LATER_SHORT_TERM' + }, + { + amount: 0.01, + template: 'short_term_nq.json', + product: 'PAY_LATER_SHORT_TERM' + }, + { + amount: 0, + template: 'generic.json', + product: 'PAY_LATER_SHORT_TERM' + } + ], + offers: { + PAY_LATER_SHORT_TERM: [ + { + totalPayments: 4, + apr: 0, + nominalRate: 0, + minAmount: 30, + maxAmount: 1500 + } + ] + } + } +}; diff --git a/utils/devServerProxy/config/devAccountsV2.config.js b/utils/devServerProxy/config/devAccountsV2.config.js index 6324791a6a..d45fdd83f7 100644 --- a/utils/devServerProxy/config/devAccountsV2.config.js +++ b/utils/devServerProxy/config/devAccountsV2.config.js @@ -5,6 +5,7 @@ import ES from './ES'; import IT from './IT'; import FR from './FR'; import DE from './DE'; +import CA from './CA'; // Note that these values are solely mock structures for development purposes // that are not guaranteed to be reflective of what is in production @@ -15,5 +16,6 @@ export default { ...ES, ...IT, ...FR, - ...DE + ...DE, + ...CA }; From 8dc2764e53366490410d9513250e4609b9c3b401 Mon Sep 17 00:00:00 2001 From: suweinberg Date: Sat, 6 Sep 2025 12:21:14 -0700 Subject: [PATCH 04/14] add msg lang param support --- src/components/message/Message.js | 4 ++++ src/library/controllers/message/interface.js | 3 +++ src/library/zoid/message/component.js | 6 ++++++ 3 files changed, 13 insertions(+) diff --git a/src/components/message/Message.js b/src/components/message/Message.js index bc1db48d79..cce2b6dd83 100644 --- a/src/components/message/Message.js +++ b/src/components/message/Message.js @@ -20,6 +20,7 @@ const Message = function ({ markup, meta, parentStyles, warnings }) { amount: window.xprops.amount ?? null, currency: window.xprops.currency ?? null, buyerCountry: window.xprops.buyerCountry ?? null, + language: window.xprops.language ?? null, ignoreCache: window.xprops.ignoreCache ?? null, style: window.xprops.style, offer: window.xprops.offer ?? null, @@ -115,6 +116,7 @@ const Message = function ({ markup, meta, parentStyles, warnings }) { amount, currency, buyerCountry, + language, ignoreCache, offer, payerId, @@ -137,6 +139,7 @@ const Message = function ({ markup, meta, parentStyles, warnings }) { amount, currency, buyerCountry, + language, ignoreCache, style, offer, @@ -159,6 +162,7 @@ const Message = function ({ markup, meta, parentStyles, warnings }) { amount, currency, buyer_country: buyerCountry, + language, ignore_cache: ignoreCache, style, credit_type: offer, diff --git a/src/library/controllers/message/interface.js b/src/library/controllers/message/interface.js index 278da78215..ef4af84d8b 100644 --- a/src/library/controllers/message/interface.js +++ b/src/library/controllers/message/interface.js @@ -100,6 +100,7 @@ export default (options = {}) => ({ style, offer, buyerCountry, + language, ignoreCache, onClick, onRender, @@ -120,6 +121,7 @@ export default (options = {}) => ({ currency, amount, buyerCountry, + language, ignoreCache, channel, ecToken, @@ -180,6 +182,7 @@ export default (options = {}) => ({ style: ${JSON.stringify(style)}, amount: ${amount}, buyerCountry: ${buyerCountry}, + language: ${language}, pageType: ${pageType}, renderStart: ${new Date(renderStart).toLocaleString()}, diff --git a/src/library/zoid/message/component.js b/src/library/zoid/message/component.js index 8246249d64..ff64e0e52d 100644 --- a/src/library/zoid/message/component.js +++ b/src/library/zoid/message/component.js @@ -108,6 +108,12 @@ export default createGlobalVariableGetter('__paypal_credit_message__', () => required: false, value: validate.buyerCountry }, + language: { + type: 'string', + queryParam: true, + required: false, + value: validate.language + }, ignoreCache: { type: 'boolean', queryParam: 'ignore_cache', From 866bedfdf4b115b1dd7a72bda75827c36ee309a7 Mon Sep 17 00:00:00 2001 From: suweinberg Date: Sat, 6 Sep 2025 12:22:16 -0700 Subject: [PATCH 05/14] wrap donut long text --- src/components/modal/v2/parts/Donut.jsx | 2 +- src/components/modal/v2/styles/components/_donut.scss | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/modal/v2/parts/Donut.jsx b/src/components/modal/v2/parts/Donut.jsx index 976629807e..11bc098f0d 100644 --- a/src/components/modal/v2/parts/Donut.jsx +++ b/src/components/modal/v2/parts/Donut.jsx @@ -91,7 +91,7 @@ const Donut = ({