Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update: payment method test mode label behavior #9647

Merged
merged 13 commits into from
Nov 7, 2024
4 changes: 4 additions & 0 deletions changelog/update-payment-method-test-mode-label
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: update

update: payment method "test mode" label at checkout to be displayed only when payment method is selected
5 changes: 4 additions & 1 deletion client/checkout/blocks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,10 @@ Object.entries( enabledPaymentMethodsConfig )
label: (
<PaymentMethodLabel
api={ api }
upeConfig={ upeConfig }
title={ upeConfig.title }
countries={ upeConfig.countries }
iconLight={ upeConfig.icon }
iconDark={ upeConfig.darkIcon }
Comment on lines +113 to +116
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just like to be explicit 🤷

upeName={ upeName }
upeAppearanceTheme={ upeAppearanceTheme }
/>
Expand Down
109 changes: 71 additions & 38 deletions client/checkout/blocks/payment-method-label.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,50 @@ import './style.scss';
import { useEffect, useState } from '@wordpress/element';
import { getAppearance } from 'wcpay/checkout/upe-styles';

export default ( { api, upeConfig, upeName, upeAppearanceTheme } ) => {
const bnplMethods = [ 'affirm', 'afterpay_clearpay', 'klarna' ];
const PaymentMethodMessageWrapper = ( {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be on its own file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally don't think so, because it's not going to be used anywhere else - I just extracted it from the previous implementation because I thought it would make things slightly easier to scroll through, since there are a lot of if conditions to check for. 🤷

upeName,
countries,
currentCountry,
amount,
appearance,
children,
} ) => {
if ( ! bnplMethods.includes( upeName ) ) {
return null;
}

if ( amount <= 0 ) {
return null;
}

if ( ! currentCountry ) {
return null;
}

if ( ! appearance ) {
return null;
}

if ( countries.length !== 0 && ! countries.includes( currentCountry ) ) {
return null;
}

return (
<div className="payment-method-label__pmme-container">{ children }</div>
);
};

export default ( {
api,
title,
countries,
iconLight,
iconDark,
upeName,
upeAppearanceTheme,
} ) => {
const cartData = wp.data.select( 'wc/store/cart' ).getCartData();
const bnplMethods = [ 'affirm', 'afterpay_clearpay', 'klarna' ];
const isTestMode = getUPEConfig( 'testMode' );
const [ appearance, setAppearance ] = useState(
getUPEConfig( 'wcBlocksUPEAppearance' )
Expand All @@ -35,8 +76,6 @@ export default ( { api, upeConfig, upeName, upeAppearanceTheme } ) => {
window.wcBlocksCheckoutData?.storeCountry ||
'US';

const isCreditCard = upeName === 'card';

useEffect( () => {
async function generateUPEAppearance() {
// Generate UPE input styles.
Expand All @@ -56,50 +95,44 @@ export default ( { api, upeConfig, upeName, upeAppearanceTheme } ) => {
return (
<>
<div className="payment-method-label">
<span className="payment-method-label__label">
{ upeConfig.title }
</span>
{ isCreditCard && isTestMode && (
<span className="payment-method-label__label">{ title }</span>
{ isTestMode && (
<span className="test-mode badge">
{ __( 'Test Mode', 'woocommerce-payments' ) }
</span>
) }
<img
className="payment-methods--logos"
src={
upeAppearanceTheme === 'night'
? upeConfig.darkIcon
: upeConfig.icon
upeAppearanceTheme === 'night' ? iconDark : iconLight
}
alt={ upeConfig.title }
alt={ title }
/>
</div>
{ bnplMethods.includes( upeName ) &&
( upeConfig.countries.length === 0 ||
upeConfig.countries.includes( currentCountry ) ) &&
amount > 0 &&
currentCountry &&
appearance && (
<div className="bnpl-message">
<Elements
stripe={ api.getStripeForUPE( upeName ) }
options={ {
appearance: appearance,
} }
>
<PaymentMethodMessagingElement
options={ {
amount: amount || 0,
currency:
cartData.totals.currency_code || 'USD',
paymentMethodTypes: [ upeName ],
countryCode: currentCountry,
displayType: 'promotional_text',
} }
/>
</Elements>
</div>
) }
<PaymentMethodMessageWrapper
upeName={ upeName }
countries={ countries }
amount={ amount }
currentCountry={ currentCountry }
appearance={ appearance }
>
<Elements
stripe={ api.getStripeForUPE( upeName ) }
options={ {
appearance: appearance,
} }
>
<PaymentMethodMessagingElement
options={ {
amount: amount || 0,
currency: cartData.totals.currency_code || 'USD',
paymentMethodTypes: [ upeName ],
countryCode: currentCountry,
displayType: 'promotional_text',
} }
/>
</Elements>
</PaymentMethodMessageWrapper>
</>
);
};
32 changes: 22 additions & 10 deletions client/checkout/blocks/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,21 @@ button.wcpay-stripelink-modal-trigger:hover {
}

.wc-block-checkout__payment-method {
input:checked ~ div {
.wc-block-components-radio-control__label {
> .payment-method-label {
.test-mode.badge {
// hiding the badge when the payment method is not selected
display: inline-block;
}

&__pmme-container {
display: none;
}
}
}
}

.wc-block-components-radio-control__label {
width: 100%;
display: block !important;
Expand Down Expand Up @@ -77,6 +92,7 @@ button.wcpay-stripelink-modal-trigger:hover {
color: #4d3716;
justify-self: start;
width: max-content;
display: none;
}

@include breakpoint( '<480px' ) {
Expand All @@ -88,13 +104,14 @@ button.wcpay-stripelink-modal-trigger:hover {
justify-self: end;
}
}
}

.bnpl-message {
width: 100%;
&__pmme-container {
width: 100%;
pointer-events: none;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added to ensure that clicking on the Payment Method Messaging Element expands the payment method


@include breakpoint( '<480px' ) {
margin-top: 8px;
@include breakpoint( '<480px' ) {
margin-top: 8px;
}
}
}
}
Expand All @@ -112,11 +129,6 @@ button.wcpay-stripelink-modal-trigger:hover {
}

#payment-method {
label.wc-block-components-radio-control__option-checked {
.StripeElement {
display: none;
}
}
/* stylelint-disable-next-line selector-id-pattern */
#radio-control-wc-payment-method-options-woocommerce_payments_affirm__label
img {
Expand Down
66 changes: 27 additions & 39 deletions client/checkout/classic/event-handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,55 +159,43 @@ jQuery( function ( $ ) {

async function injectStripePMMEContainers() {
const bnplMethods = [ 'affirm', 'afterpay_clearpay', 'klarna' ];
const labelBase = 'payment_method_woocommerce_payments_';
const paymentMethods = getUPEConfig( 'paymentMethodsConfig' );
const paymentMethodsKeys = Object.keys( paymentMethods );
const cartData = await api.pmmeGetCartData();

for ( const method of paymentMethodsKeys ) {
if ( bnplMethods.includes( method ) ) {
const targetLabel = document.querySelector(
`label[for="${ labelBase }${ method }"]`
);
const containerID = `stripe-pmme-container-${ method }`;
const container = document.getElementById( containerID );

if ( document.getElementById( containerID ) ) {
document.getElementById( containerID ).innerHTML = '';
if ( ! container ) {
continue;
}

if ( targetLabel ) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing this slightly - the container will always be present (generated from the backend), the JS will use it to mount the BNPL messaging.

let container = document.getElementById( containerID );
if ( ! container ) {
container = document.createElement( 'span' );
container.id = containerID;
container.dataset.paymentMethodType = method;
container.classList.add( 'stripe-pmme-container' );
targetLabel.appendChild( container );
}

const currentCountry =
cartData?.billing_address?.country ||
getUPEConfig( 'storeCountry' );

if (
paymentMethods[ method ]?.countries.length === 0 ||
paymentMethods[ method ]?.countries?.includes(
currentCountry
)
) {
await mountStripePaymentMethodMessagingElement(
api,
container,
{
amount: cartData?.totals?.total_price,
currency: cartData?.totals?.currency_code,
decimalPlaces:
cartData?.totals?.currency_minor_unit,
country: currentCountry,
},
'shortcode_checkout'
);
}
container.innerHTML = '';
container.dataset.paymentMethodType = method;

const currentCountry =
cartData?.billing_address?.country ||
getUPEConfig( 'storeCountry' );
if (
paymentMethods[ method ]?.countries.length === 0 ||
paymentMethods[ method ]?.countries?.includes(
currentCountry
)
) {
await mountStripePaymentMethodMessagingElement(
api,
container,
{
amount: cartData?.totals?.total_price,
currency: cartData?.totals?.currency_code,
decimalPlaces:
cartData?.totals?.currency_minor_unit,
country: currentCountry,
},
'shortcode_checkout'
);
}
}
}
Expand Down
Loading
Loading