Skip to content

Commit 53233bc

Browse files
authored
Adding a notice to highlight OC (#4562)
* Adding a notice to highlight OC * Changelog and readme entries * Remove the need to refresh screen * Making the notice dismissible * Fix comparison when deciding to track OC toggle
1 parent ebe3af3 commit 53233bc

File tree

13 files changed

+178
-9
lines changed

13 files changed

+178
-9
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
*** Changelog ***
22

33
= 9.8.0 - xxxx-xx-xx =
4+
* Add - Includes a new notice to highlight the Optimized Checkout feature above the payment methods list in the Stripe settings page
45
* Update - Increases the default font size for the Optimized Checkout payment element to match the rest of the checkout form
56
* Fix - Checks for the subscription payment method (if it is Stripe) when verifying for the payment method detachment
67
* Update - Removes the ability to change the title for the Optimized Checkout payment element, as it is now set to "Stripe" by default

client/settings/advanced-settings-section/__tests__/optimized-checkout-feature.test.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@ import UpeToggleContext from 'wcstripe/settings/upe-toggle/context';
77
jest.useFakeTimers();
88

99
describe( 'Optimized Checkout Element feature setting', () => {
10+
const setIsOCEnabled = jest.fn().mockImplementation();
11+
1012
it( 'should render', () => {
11-
render( <OptimizedCheckoutFeature /> );
13+
render(
14+
<OptimizedCheckoutFeature setIsOCEnabled={ setIsOCEnabled } />
15+
);
1216

1317
expect(
1418
screen.queryByText(
@@ -29,7 +33,7 @@ describe( 'Optimized Checkout Element feature setting', () => {
2933
render(
3034
<div>
3135
<UpdateUpeDisabledFlagMock />
32-
<OptimizedCheckoutFeature />
36+
<OptimizedCheckoutFeature setIsOCEnabled={ setIsOCEnabled } />
3337
</div>
3438
);
3539

client/settings/advanced-settings-section/index.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,20 @@ const AdvancedSettingsDescription = () => (
2020
</>
2121
);
2222

23-
const AdvancedSettings = () => {
23+
const AdvancedSettings = ( { isOCEnabled, setIsOCEnabled } ) => {
2424
const isOcAvailable = wc_stripe_settings_params.is_oc_available; // eslint-disable-line camelcase
2525
return (
2626
<SettingsSection Description={ AdvancedSettingsDescription }>
2727
<LoadableSettingsSection numLines={ 10 }>
2828
<Card>
2929
<CardBody>
3030
<DebugMode />
31-
{ isOcAvailable && <OptimizedCheckoutFeature /> }
31+
{ isOcAvailable && (
32+
<OptimizedCheckoutFeature
33+
isOCEnabled={ isOCEnabled }
34+
setIsOCEnabled={ setIsOCEnabled }
35+
/>
36+
) }
3237
</CardBody>
3338
</Card>
3439
</LoadableSettingsSection>

client/settings/advanced-settings-section/optimized-checkout-feature.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@ import { createInterpolateElement } from '@wordpress/element';
33
import { CheckboxControl, ExternalLink } from '@wordpress/components';
44
import React, { useEffect, useRef } from 'react';
55
import { getQuery } from '@woocommerce/navigation';
6-
import { useIsOCEnabled, useIsUpeEnabled } from '../../data';
6+
import { useIsUpeEnabled } from '../../data';
77

8-
const OptimizedCheckoutFeature = () => {
9-
const [ isOCEnabled, setIsOCEnabled ] = useIsOCEnabled();
8+
const OptimizedCheckoutFeature = ( { isOCEnabled, setIsOCEnabled } ) => {
109
const [ isUpeEnabled ] = useIsUpeEnabled();
1110
const headingRef = useRef( null );
1211

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import React from 'react';
2+
import { screen, render, act } from '@testing-library/react';
3+
import apiFetch from '@wordpress/api-fetch';
4+
import userEvent from '@testing-library/user-event';
5+
import OptimizedCheckoutNotice from '..';
6+
7+
jest.mock( '@wordpress/api-fetch' );
8+
9+
describe( 'OptimizedCheckoutNotice', () => {
10+
const globalValues = global.wc_stripe_settings_params;
11+
beforeEach( () => {
12+
apiFetch.mockImplementation(
13+
jest.fn( () => Promise.resolve( { data: {} } ) )
14+
);
15+
global.wc_stripe_settings_params = {
16+
...globalValues,
17+
show_optimized_checkout_notice: true,
18+
};
19+
} );
20+
21+
afterEach( () => {
22+
jest.clearAllMocks();
23+
global.wc_stripe_settings_params = globalValues;
24+
} );
25+
26+
it( 'should render the notice when OC is enabled', () => {
27+
render( <OptimizedCheckoutNotice isOCEnabled={ true } /> );
28+
29+
const noticeText = screen.queryAllByText(
30+
"You're using Stripe's Optimized Checkout Suite to dynamically display the most relevant payment methods you've enabled to each customer."
31+
)?.[ 0 ];
32+
expect( noticeText ).toBeInTheDocument();
33+
} );
34+
35+
it( 'should make an API call to dismiss the banner on button click', async () => {
36+
const dismissNoticeMock = jest.fn( () =>
37+
Promise.resolve( { data: {} } )
38+
);
39+
apiFetch.mockImplementation( dismissNoticeMock );
40+
41+
render( <OptimizedCheckoutNotice isOCEnabled={ true } /> );
42+
43+
const dismissButton = screen.queryByRole( 'button', {
44+
'aria-label': 'Dismiss the notice',
45+
} );
46+
expect( dismissButton ).toBeInTheDocument();
47+
await act( async () => {
48+
await userEvent.click( dismissButton );
49+
} );
50+
expect( dismissNoticeMock ).toHaveBeenCalled();
51+
} );
52+
53+
it( 'should not render the notice when OC is disabled', () => {
54+
const { container } = render(
55+
<OptimizedCheckoutNotice isOCEnabled={ false } />
56+
);
57+
58+
expect( container.firstChild ).toBeNull();
59+
} );
60+
61+
it( 'should not render the notice when `show_optimized_checkout_notice` is false', () => {
62+
global.wc_stripe_settings_params = {
63+
...globalValues,
64+
show_optimized_checkout_notice: false,
65+
};
66+
67+
const { container } = render(
68+
<OptimizedCheckoutNotice isOCEnabled={ true } />
69+
);
70+
71+
expect( container.firstChild ).toBeNull();
72+
} );
73+
} );
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/* global wc_stripe_settings_params */
2+
import { __ } from '@wordpress/i18n';
3+
import styled from '@emotion/styled';
4+
import React, { useState } from 'react';
5+
import { Icon, Notice } from '@wordpress/components';
6+
import { info } from '@wordpress/icons';
7+
import interpolateComponents from 'interpolate-components';
8+
import apiFetch from '@wordpress/api-fetch';
9+
10+
const NoticeWrapper = styled( Notice )`
11+
margin: 0 0 24px 0;
12+
`;
13+
14+
const NoticeContent = styled.div`
15+
display: inline-grid;
16+
grid-template-columns: auto auto auto;
17+
gap: 12px;
18+
19+
> svg {
20+
fill: var( --wp-admin-theme-color );
21+
}
22+
`;
23+
24+
const OptimizedCheckoutNotice = ( { isOCEnabled } ) => {
25+
const [ showNotice, setShowNotice ] = useState(
26+
// eslint-disable-next-line camelcase
27+
wc_stripe_settings_params.show_optimized_checkout_notice
28+
);
29+
30+
if ( ! isOCEnabled || ! showNotice ) {
31+
return null;
32+
}
33+
34+
const handleDismissNotice = () => {
35+
apiFetch( {
36+
path: '/wc/v3/wc_stripe/settings/notice',
37+
method: 'POST',
38+
data: { wc_stripe_show_optimized_checkout_notice: 'no' },
39+
} ).finally( () => {
40+
setShowNotice( false );
41+
} );
42+
};
43+
44+
return (
45+
<NoticeWrapper isDismissible={ true } onRemove={ handleDismissNotice }>
46+
<NoticeContent>
47+
<Icon icon={ info } size={ 24 } />
48+
<div>
49+
{ interpolateComponents( {
50+
mixedString: __(
51+
"You're using Stripe's Optimized Checkout Suite to dynamically display the most relevant payment methods you've enabled to each customer. {{docLink}}Learn more{{/docLink}}",
52+
'woocommerce-gateway-stripe'
53+
),
54+
components: {
55+
docLink: (
56+
// eslint-disable-next-line jsx-a11y/anchor-has-content
57+
<a
58+
target="_blank"
59+
rel="noreferrer"
60+
href="https://woocommerce.com/document/stripe/admin-experience/optimized-checkout-suite/"
61+
/>
62+
),
63+
},
64+
} ) }
65+
</div>
66+
</NoticeContent>
67+
</NoticeWrapper>
68+
);
69+
};
70+
71+
export default OptimizedCheckoutNotice;

client/settings/payment-methods/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import LoadableSettingsSection from '../loadable-settings-section';
99
import DisplayOrderCustomizationNotice from '../display-order-customization-notice';
1010
import { NEW_CHECKOUT_EXPERIENCE_BANNER } from 'wcstripe/settings/payment-settings/constants';
1111
import PromotionalBanner from 'wcstripe/settings/payment-settings/promotional-banner';
12+
import OptimizedCheckoutNotice from 'wcstripe/settings/optimized-checkout-notice';
1213

1314
const PaymentMethodsDescription = () => {
1415
return (
@@ -52,6 +53,7 @@ const PaymentMethodsPanel = ( {
5253
setShowPromotionalBanner,
5354
showPromotionalBanner,
5455
promotionalBannerType,
56+
isOCEnabled,
5557
setIsOCEnabled,
5658
setIsUpeEnabled,
5759
} ) => {
@@ -77,6 +79,7 @@ const PaymentMethodsPanel = ( {
7779
) }
7880
<SettingsSection Description={ PaymentMethodsDescription }>
7981
<DisplayOrderCustomizationNotice />
82+
<OptimizedCheckoutNotice isOCEnabled={ isOCEnabled } />
8083
<GeneralSettingsSection
8184
onSaveChanges={ onSaveChanges }
8285
showLegacyExperienceTransitionNotice={

client/settings/payment-settings/index.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ const PaymentSettingsPanel = ( {
7070
showPromotionalBanner,
7171
setShowPromotionalBanner,
7272
promotionalBannerType,
73+
isOCEnabled,
7374
setIsOCEnabled,
7475
setIsUpeEnabled,
7576
} ) => {
@@ -145,7 +146,10 @@ const PaymentSettingsPanel = ( {
145146
<PaymentsAndTransactionsSection />
146147
</LoadableSettingsSection>
147148
</SettingsSection>
148-
<AdvancedSettingsSection />
149+
<AdvancedSettingsSection
150+
isOCEnabled={ isOCEnabled }
151+
setIsOCEnabled={ setIsOCEnabled }
152+
/>
149153
</>
150154
);
151155
};

client/settings/settings-manager/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ const SettingsManager = () => {
111111
setShowPromotionalBanner
112112
}
113113
promotionalBannerType={ promotionalBannerType }
114+
isOCEnabled={ isOCEnabled }
114115
setIsOCEnabled={ setIsOCEnabled }
115116
setIsUpeEnabled={ setIsUpeEnabled }
116117
/>
@@ -122,6 +123,7 @@ const SettingsManager = () => {
122123
setShowPromotionalBanner
123124
}
124125
promotionalBannerType={ promotionalBannerType }
126+
isOCEnabled={ isOCEnabled }
125127
setIsOCEnabled={ setIsOCEnabled }
126128
setIsUpeEnabled={ setIsUpeEnabled }
127129
/>

includes/admin/class-wc-rest-stripe-settings-controller.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,7 @@ public function dismiss_customization_notice( WP_REST_Request $request ) {
617617
*/
618618
public function dismiss_notice( WP_REST_Request $request ) {
619619
if ( null === $request->get_param( 'wc_stripe_show_customization_notice' )
620+
&& null === $request->get_param( 'wc_stripe_show_optimized_checkout_notice' )
620621
&& null === $request->get_param( 'wc_stripe_show_bnpl_promotion_banner' )
621622
&& null === $request->get_param( 'wc_stripe_show_oc_promotion_banner' ) ) {
622623
return new WP_REST_Response( [], 200 );
@@ -626,6 +627,10 @@ public function dismiss_notice( WP_REST_Request $request ) {
626627
update_option( 'wc_stripe_show_customization_notice', 'no' );
627628
}
628629

630+
if ( null !== $request->get_param( 'wc_stripe_show_optimized_checkout_notice' ) ) {
631+
update_option( 'wc_stripe_show_optimized_checkout_notice', 'no' );
632+
}
633+
629634
if ( null !== $request->get_param( 'wc_stripe_show_bnpl_promotion_banner' ) ) {
630635
update_option( 'wc_stripe_show_bnpl_promotion_banner', 'no' );
631636
}

0 commit comments

Comments
 (0)