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

Added a notice about custom checkout fields conflicting with express checkout #8339

Merged
merged 13 commits into from
Mar 19, 2024
Merged
4 changes: 4 additions & 0 deletions changelog/express-checkout-incompatibility-notice
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: add

Added a notice about custom checkout fields conflicting with express checkouut
5 changes: 5 additions & 0 deletions client/data/settings/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,11 @@ export const useWooPayShowIncompatibilityNotice = () =>
select( STORE_NAME ).getShowWooPayIncompatibilityNotice()
);

export const useExpressCheckoutShowIncompatibilityNotice = () =>
useSelect( ( select ) =>
select( STORE_NAME ).getShowExpressCheckoutIncompatibilityNotice()
);

export const useStripeBilling = () => {
const { updateIsStripeBillingEnabled } = useDispatch( STORE_NAME );

Expand Down
7 changes: 7 additions & 0 deletions client/data/settings/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,13 @@ export const getShowWooPayIncompatibilityNotice = ( state ) => {
return getSettings( state ).show_woopay_incompatibility_notice || false;
};

export const getShowExpressCheckoutIncompatibilityNotice = ( state ) => {
return (
getSettings( state ).show_express_checkout_incompatibility_notice ||
false
);
};

export const getIsStripeBillingEnabled = ( state ) => {
return getSettings( state ).is_stripe_billing_enabled || false;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import GeneralPaymentRequestButtonSettings from './general-payment-request-butto
import {
usePaymentRequestEnabledSettings,
usePaymentRequestLocations,
useExpressCheckoutShowIncompatibilityNotice,
} from 'wcpay/data';
import { ExpressCheckoutIncompatibilityNotice } from 'wcpay/settings/settings-warnings/incompatibility-notice';

const PaymentRequestSettings = ( { section } ) => {
const [
Expand All @@ -40,10 +42,15 @@ const PaymentRequestSettings = ( { section } ) => {
}
};

const showIncompatibilityNotice = useExpressCheckoutShowIncompatibilityNotice();

return (
<Card>
{ section === 'enable' && (
<CardBody>
{ showIncompatibilityNotice && (
<ExpressCheckoutIncompatibilityNotice />
) }
<CheckboxControl
checked={ isPaymentRequestEnabled }
onChange={ updateIsPaymentRequestEnabled }
Expand Down
3 changes: 3 additions & 0 deletions client/settings/express-checkout-settings/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ jest.mock( '../../../data', () => ( {
.fn()
.mockReturnValue( [ [ true, true, true ], jest.fn() ] ),
useWooPayShowIncompatibilityNotice: jest.fn().mockReturnValue( false ),
useExpressCheckoutShowIncompatibilityNotice: jest
.fn()
.mockReturnValue( false ),
} ) );

jest.mock( '@wordpress/data', () => ( {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
usePaymentRequestButtonSize,
usePaymentRequestButtonTheme,
useWooPayEnabledSettings,
useExpressCheckoutShowIncompatibilityNotice,
} from '../../../data';

jest.mock( '../../../data', () => ( {
Expand All @@ -27,6 +28,7 @@ jest.mock( '../../../data', () => ( {
usePaymentRequestButtonSize: jest.fn().mockReturnValue( [ 'small' ] ),
usePaymentRequestButtonTheme: jest.fn().mockReturnValue( [ 'dark' ] ),
useWooPayEnabledSettings: jest.fn(),
useExpressCheckoutShowIncompatibilityNotice: jest.fn(),
useWooPayShowIncompatibilityNotice: jest.fn().mockReturnValue( false ),
} ) );

Expand Down Expand Up @@ -254,4 +256,28 @@ describe( 'PaymentRequestSettings', () => {
updatePaymentRequestLocationsHandler
).toHaveBeenLastCalledWith( [ 'checkout', 'product' ] );
} );

it( 'triggers the hooks when the enable setting is being interacted with', () => {
useExpressCheckoutShowIncompatibilityNotice.mockReturnValue( true );

render( <PaymentRequestSettings section="enable" /> );

expect(
screen.queryByText(
'One or more of your extensions alters checkout fields. This might cause issues with this payment method.'
)
).toBeInTheDocument();
} );

it( 'triggers the hooks when the enable setting is being interacted with', () => {
useExpressCheckoutShowIncompatibilityNotice.mockReturnValue( false );

render( <PaymentRequestSettings section="enable" /> );

expect(
screen.queryByText(
'One or more of your extensions alters checkout fields. This might cause issues with this payment method.'
)
).not.toBeInTheDocument();
} );
} );
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
useWooPayShowIncompatibilityNotice,
} from 'wcpay/data';
import GeneralPaymentRequestButtonSettings from './general-payment-request-button-settings';
import WooPayIncompatibilityNotice from '../settings-warnings/incompatibility-notice';
import { WooPayIncompatibilityNotice } from '../settings-warnings/incompatibility-notice';

const WooPaySettings = ( { section } ) => {
const [
Expand Down
11 changes: 10 additions & 1 deletion client/settings/express-checkout/apple-google-pay-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,22 @@ import React from 'react';
* Internal dependencies
*/
import { getPaymentMethodSettingsUrl } from '../../utils';
import { usePaymentRequestEnabledSettings } from 'wcpay/data';
import {
usePaymentRequestEnabledSettings,
useExpressCheckoutShowIncompatibilityNotice,
} from 'wcpay/data';
import { PaymentRequestEnabledSettingsHook } from './interfaces';
import { ApplePayIcon, GooglePayIcon } from 'wcpay/payment-methods-icons';
import { ExpressCheckoutIncompatibilityNotice } from 'wcpay/settings/settings-warnings/incompatibility-notice';

const AppleGooglePayExpressCheckoutItem = (): React.ReactElement => {
const [
isPaymentRequestEnabled,
updateIsPaymentRequestEnabled,
] = usePaymentRequestEnabledSettings() as PaymentRequestEnabledSettingsHook;

const showIncompatibilityNotice = useExpressCheckoutShowIncompatibilityNotice();

return (
<li
className="express-checkout"
Expand Down Expand Up @@ -160,6 +166,9 @@ const AppleGooglePayExpressCheckoutItem = (): React.ReactElement => {
</div>
</div>
</div>
{ showIncompatibilityNotice && (
<ExpressCheckoutIncompatibilityNotice />
) }
</li>
);
};
Expand Down
24 changes: 23 additions & 1 deletion client/settings/express-checkout/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import userEvent from '@testing-library/user-event';
import ExpressCheckout from '..';
import {
useEnabledPaymentMethodIds,
useExpressCheckoutShowIncompatibilityNotice,
useGetAvailablePaymentMethodIds,
usePaymentRequestEnabledSettings,
useWooPayEnabledSettings,
Expand All @@ -25,6 +26,7 @@ jest.mock( 'wcpay/data', () => ( {
useEnabledPaymentMethodIds: jest.fn(),
useGetAvailablePaymentMethodIds: jest.fn(),
useWooPayShowIncompatibilityNotice: jest.fn(),
useExpressCheckoutShowIncompatibilityNotice: jest.fn(),
} ) );

const getMockPaymentRequestEnabledSettings = (
Expand Down Expand Up @@ -191,7 +193,7 @@ describe( 'ExpressCheckout', () => {
expect( screen.getByLabelText( 'Link by Stripe' ) ).toBeChecked();
} );

it( 'should show incompatibility warning', async () => {
it( 'should show WooPay incompatibility warning', async () => {
const updateIsWooPayEnabledHandler = jest.fn();
useWooPayEnabledSettings.mockReturnValue(
getMockWooPayEnabledSettings( false, updateIsWooPayEnabledHandler )
Expand All @@ -214,4 +216,24 @@ describe( 'ExpressCheckout', () => {
)
).toBeInTheDocument();
} );

it( 'should show Express Checkout incompatibility warning', async () => {
const context = { featureFlags: { woopay: true } };
useGetAvailablePaymentMethodIds.mockReturnValue( [ 'link', 'card' ] );
useEnabledPaymentMethodIds.mockReturnValue( [ [ 'card', 'link' ] ] );

useExpressCheckoutShowIncompatibilityNotice.mockReturnValue( true );

render(
<WCPaySettingsContext.Provider value={ context }>
<ExpressCheckout />
</WCPaySettingsContext.Provider>
);

expect(
screen.queryByText(
'One or more of your extensions alters checkout fields. This might cause issues with this payment method.'
)
).toBeInTheDocument();
} );
} );
2 changes: 1 addition & 1 deletion client/settings/express-checkout/woopay-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
} from 'wcpay/data';
import WCPaySettingsContext from '../wcpay-settings-context';
import NoticeOutlineIcon from 'gridicons/dist/notice-outline';
import WooPayIncompatibilityNotice from '../settings-warnings/incompatibility-notice';
import { WooPayIncompatibilityNotice } from '../settings-warnings/incompatibility-notice';

import { WooPayEnabledSettingsHook } from './interfaces';
import { WooIcon } from 'wcpay/payment-methods-icons';
Expand Down
30 changes: 23 additions & 7 deletions client/settings/settings-warnings/incompatibility-notice.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Notice } from '@wordpress/components';
import NoticeOutlineIcon from 'gridicons/dist/notice-outline';
import './style.scss';

const WooPayIncompatibilityNotice = () => (
const IncompatibilityNotice = ( { message, learnMoreLinkHref } ) => (
<Notice
status="warning"
isDismissible={ false }
Expand All @@ -29,10 +29,7 @@ const WooPayIncompatibilityNotice = () => (
/>
</span>
<span>
{ __(
'One or more of your extensions are incompatible with WooPay.',
'woocommerce-payments'
) }
{ message }
<br />
{ interpolateComponents( {
mixedString: __(
Expand All @@ -45,7 +42,7 @@ const WooPayIncompatibilityNotice = () => (
<a
target="_blank"
rel="noreferrer"
href="https://woo.com/document/woopay-merchant-documentation/#compatibility"
href={ learnMoreLinkHref }
/>
),
},
Expand All @@ -54,4 +51,23 @@ const WooPayIncompatibilityNotice = () => (
</Notice>
);

export default WooPayIncompatibilityNotice;
export const WooPayIncompatibilityNotice = () => (
<IncompatibilityNotice
message={ __(
'One or more of your extensions are incompatible with WooPay.',
'woocommerce-payments'
) }
learnMoreLinkHref="https://woo.com/document/woopay-merchant-documentation/#compatibility"
/>
);

export const ExpressCheckoutIncompatibilityNotice = () => (
<IncompatibilityNotice
message={ __(
'One or more of your extensions alters checkout fields. This might cause issues with this payment method.',
'woocommerce-payments'
) }
// eslint-disable-next-line max-len
learnMoreLinkHref="https://woo.com/document/woopayments/payment-methods/apple-pay-and-google-pay-compatibility/#faq-extra-fields-on-checkout"
/>
);
35 changes: 35 additions & 0 deletions includes/admin/class-wc-rest-payments-settings-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ public function get_settings(): WP_REST_Response {
'is_card_present_eligible' => $this->wcpay_gateway->is_card_present_eligible() && isset( WC()->payment_gateways()->get_available_payment_gateways()['cod'] ),
'is_woopay_enabled' => 'yes' === $this->wcpay_gateway->get_option( 'platform_checkout' ),
'show_woopay_incompatibility_notice' => get_option( 'woopay_invalid_extension_found', false ),
'show_express_checkout_incompatibility_notice' => $this->should_show_express_checkout_incompatibility_notice(),
'woopay_custom_message' => $this->wcpay_gateway->get_option( 'platform_checkout_custom_message' ),
'woopay_store_logo' => $this->wcpay_gateway->get_option( 'platform_checkout_store_logo' ),
'woopay_enabled_locations' => $this->wcpay_gateway->get_option( 'platform_checkout_button_locations', array_keys( $wcpay_form_fields['payment_request_button_locations']['options'] ) ),
Expand Down Expand Up @@ -1080,4 +1081,38 @@ private function update_reporting_export_language( WP_REST_Request $request ) {

$this->wcpay_gateway->update_option( 'reporting_export_language', $reporting_export_language );
}

/**
* Whether to show the express checkout incompatibility notice.
*
* @return bool
*/
private function should_show_express_checkout_incompatibility_notice() {
// Apply filters to empty arrays to check if any plugin is modifying the checkout fields.
$after_apply_billing = apply_filters( 'woocommerce_billing_fields', [], '' );
$after_apply_shipping = apply_filters( 'woocommerce_shipping_fields', [], '' );
$after_apply_checkout = array_filter(
apply_filters(
'woocommerce_checkout_fields',
[
'billing' => [],
'shipping' => [],
'account' => [],
'order' => [],
]
)
);
// All the input values are empty, so if any of them is not empty, it means that the checkout fields are being modified.
$is_modifying_checkout_fields = ! empty(
array_filter(
[
'after_apply_billing' => $after_apply_billing,
'after_apply_shipping' => $after_apply_shipping,
'after_apply_checkout' => $after_apply_checkout,
]
)
);

return $is_modifying_checkout_fields;
}
}
Loading