Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* Fix - Ensure state and postal code are optional in express checkout for Gulf countries (UAE, Bahrain, Kuwait, Oman, Qatar)
* Dev - Removes the `_wcstripe_feature_upe` feature flag and the related method from the `WC_Stripe_Feature_Flags` class
* Dev - Fixes some incorrect subscriptions support implementations for payment methods
* Add - New promotional banner to highlight the Stripe Tax extension for OCS-enabled merchants
* Fix - Ensure correct express checkout prices in block cart and checkout with non-default decimal configuration
* Fix - Disable express checkout when Amazon Pay is disabled and the only method
* Fix - Don't allow WP-Cron jobs to detach payment methods on staging sites
Expand Down
1 change: 1 addition & 0 deletions client/settings/payment-settings/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export const NEW_CHECKOUT_EXPERIENCE_APMS_BANNER =
'new-checkout-experience-apms';
export const BNPL_PROMOTION_BANNER = 'bnpl_promotion_banner';
export const OC_PROMOTION_BANNER = 'oc_promotion_banner';
export const STRIPE_TAX_BANNER = 'stripe-tax-banner';
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
NEW_CHECKOUT_EXPERIENCE_BANNER,
OC_PROMOTION_BANNER,
RECONNECT_BANNER,
STRIPE_TAX_BANNER,
} from 'wcstripe/settings/payment-settings/constants';
import {
PAYMENT_METHOD_CARD,
Expand Down Expand Up @@ -33,6 +34,30 @@ describe( 'getPromotionalBannerType', () => {
)
).toBe( RECONNECT_BANNER );
} );
it( 'Stripe Tax banner', () => {
global.wc_stripe_settings_params = {
is_oc_available: true,
};

const accountData = {
testmode: false,
oauth_connections: {
live: { connected: true },
},
};
const isUpeEnabled = true;
const isOCEnabled = true;
const enabledPaymentMethodIds = [ PAYMENT_METHOD_CARD ];

expect(
getPromotionalBannerType(
accountData,
isUpeEnabled,
isOCEnabled,
enabledPaymentMethodIds
)
).toBe( STRIPE_TAX_BANNER );
} );
it( 'OC promotion banner', () => {
global.wc_stripe_settings_params = {
is_oc_available: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,6 @@ describe( 'OC promotional banner', () => {
} );

it( 'should make an API call to dismiss the banner on button click', async () => {
// Keep the original function.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just removing this as it is not needed

const reload = window.location.reload;
Object.defineProperty( window, 'location', {
value: { reload: jest.fn() },
} );

const dismissNoticeMock = jest.fn( () =>
Promise.resolve( { data: {} } )
);
Expand All @@ -77,11 +71,6 @@ describe( 'OC promotional banner', () => {
await userEvent.click( dismissButton );
} );
expect( dismissNoticeMock ).toHaveBeenCalled();

// Set the original function back to keep further tests working as expected.
Object.defineProperty( window, 'location', {
value: { reload },
} );
} );

it( 'should attempt to enable OC when clicking the "Activate now" button', async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { act, render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { StripeTaxBanner } from '../stripe-tax-banner';
import apiFetch from '@wordpress/api-fetch';
import { recordEvent } from 'wcstripe/tracking';

jest.mock( '@wordpress/api-fetch' );

jest.mock( 'wcstripe/tracking', () => ( {
recordEvent: jest.fn(),
} ) );

describe( 'Stripe Tax banner', () => {
const setShowPromotionalBanner = jest.fn();

beforeEach( () => {
apiFetch.mockImplementation(
jest.fn( () => Promise.resolve( { data: {} } ) )
);
} );

afterEach( () => {
jest.clearAllMocks();
} );

it( 'should render the Stripe Tax banner', () => {
const { getByText } = render(
<StripeTaxBanner
setShowPromotionalBanner={ setShowPromotionalBanner }
/>
);
expect(
getByText( 'Automate tax compliance with Stripe Tax' )
).toBeInTheDocument();
expect(
getByText(
/Automatically calculate and collect sales tax, value-added tax \(VAT\), and goods and services tax \(GST\) wherever you sell./
)
).toBeInTheDocument();
} );

it( 'should make an API call to dismiss the banner on button click', async () => {
const dismissNoticeMock = jest.fn( () =>
Promise.resolve( { data: {} } )
);
apiFetch.mockImplementation( dismissNoticeMock );

const { getByText } = render(
<StripeTaxBanner
setShowPromotionalBanner={ setShowPromotionalBanner }
/>
);
const dismissButton = getByText( 'Dismiss' );

await act( async () => {
await userEvent.click( dismissButton );
} );
expect( dismissNoticeMock ).toHaveBeenCalled();
} );

it( 'should open the main page when clicking the "Get Stripe Tax" button', async () => {
// Keep the original function at hand.
const open = window.open;

Object.defineProperty( window, 'open', {
value: jest.fn(),
} );

const { getByText } = render(
<StripeTaxBanner
setShowPromotionalBanner={ setShowPromotionalBanner }
/>
);
const activateButton = getByText( 'Get Stripe Tax' );

await act( async () => {
await userEvent.click( activateButton );
} );

expect( recordEvent ).toHaveBeenCalledWith(
'wcstripe_stripe_tax_banner_button_click',
{}
);

expect( window.open ).toHaveBeenCalledWith(
'https://woocommerce.com/products/stripe-tax/',
'_blank'
);

// Set the original function back to keep further tests working as expected.
Object.defineProperty( window, 'open', {
value: open,
} );
} );
} );
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
NEW_CHECKOUT_EXPERIENCE_BANNER,
OC_PROMOTION_BANNER,
RECONNECT_BANNER,
STRIPE_TAX_BANNER,
} from 'wcstripe/settings/payment-settings/constants';
import {
BNPL_METHODS,
Expand Down Expand Up @@ -39,6 +40,12 @@ export const getPromotionalBannerType = (

if ( oauthConnected === false ) {
return RECONNECT_BANNER;
} else if (
// eslint-disable-next-line camelcase
wc_stripe_settings_params?.is_oc_available &&
isOCEnabled
) {
return STRIPE_TAX_BANNER;
} else if (
// eslint-disable-next-line camelcase
wc_stripe_settings_params?.is_oc_available &&
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions client/settings/payment-settings/promotional-banner/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import {
BNPL_PROMOTION_BANNER,
NEW_CHECKOUT_EXPERIENCE_APMS_BANNER,
OC_PROMOTION_BANNER,
STRIPE_TAX_BANNER,
} from '../constants';
import { ReConnectAccountBanner } from 'wcstripe/settings/payment-settings/promotional-banner/re-connect-account-banner';
import { NewCheckoutExperienceAPMsBanner } from 'wcstripe/settings/payment-settings/promotional-banner/new-checkout-experience-apms-banner';
import { NewCheckoutExperienceBanner } from 'wcstripe/settings/payment-settings/promotional-banner/new-checkout-experience-banner';
import { BNPLPromotionBanner } from 'wcstripe/settings/payment-settings/promotional-banner/bnpl-promotion-banner';
import { BannerCard } from 'wcstripe/settings/payment-settings/promotional-banner/banner-layout';
import { OCPromotionBanner } from 'wcstripe/settings/payment-settings/promotional-banner/oc-promotion-banner';
import { StripeTaxBanner } from 'wcstripe/settings/payment-settings/promotional-banner/stripe-tax-banner';

const PromotionalBanner = ( {
setShowPromotionalBanner,
Expand All @@ -31,6 +33,13 @@ const PromotionalBanner = ( {
/>
);
break;
case STRIPE_TAX_BANNER:
BannerContent = (
<StripeTaxBanner
setShowPromotionalBanner={ setShowPromotionalBanner }
/>
);
break;
case OC_PROMOTION_BANNER:
BannerContent = (
<OCPromotionBanner
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ export const OCPromotionBanner = ( {
) }
</TitleBNPL>
<p>
{ __( '', 'woocommerce-gateway-stripe' ) }
{ interpolateComponents( {
mixedString: __(
"Optimize your checkout experience for more sales by dynamically displaying the most relevant payment methods you've enabled for each customer. {{docLink}}Learn more{{/docLink}} about Stripe's Optimized Checkout Suite.",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { React } from 'react';
import styled from '@emotion/styled';
import interpolateComponents from '@automattic/interpolate-components';
import { __ } from '@wordpress/i18n';
import apiFetch from '@wordpress/api-fetch';
import CardBody from 'wcstripe/settings/card-body';
import illustration from 'wcstripe/settings/payment-settings/promotional-banner/illustrations/stripe-tax.svg';
import {
BannerIllustration,
ButtonsRow,
CardColumn,
CardInner,
DismissButton,
MainCTALink,
} from 'wcstripe/settings/payment-settings/promotional-banner/banner-layout';
import { recordEvent } from 'wcstripe/tracking';
import { ExternalLink } from '@wordpress/components';

const BannerIllustrationStripeTax = styled( BannerIllustration )`
width: 80px;
margin: 10px;

@media ( min-width: 600px ) {
margin-bottom: -30px;
}
`;

const ButtonsRowStripeTax = styled( ButtonsRow )`
@media ( min-width: 600px ) {
margin-bottom: 0.7em;
}
`;

const ColumnIllustration = styled( CardColumn )`
@media ( max-width: 599px ) {
text-align: center;
}
`;

const TitleStripeTax = styled.h4`
margin-top: 0.6em !important;
font-weight: 500;
`;

export const StripeTaxBanner = ( { setShowPromotionalBanner } ) => {
const handleBannerDismiss = () => {
apiFetch( {
path: '/wc/v3/wc_stripe/settings/notice',
method: 'POST',
data: { wc_stripe_show_stripe_tax_banner: 'no' },
} ).finally( () => {
setShowPromotionalBanner( false );
} );
};

const handleButtonClick = () => {
recordEvent( 'wcstripe_stripe_tax_banner_button_click', {} );
window.open( 'https://woocommerce.com/products/stripe-tax/', '_blank' );
};

return (
<CardBody>
<CardInner>
<CardColumn>
<TitleStripeTax>
{ __(
'Automate tax compliance with Stripe Tax',
'woocommerce-gateway-stripe'
) }
</TitleStripeTax>
<p>
{ interpolateComponents( {
mixedString: __(
'Automatically calculate and collect sales tax, value-added tax (VAT), and goods and services tax (GST) wherever you sell. {{docLink}}Learn more{{/docLink}} about how Stripe Tax keeps you compliant.',
'woocommerce-gateway-stripe'
),
components: {
docLink: (
<ExternalLink href="https://stripe.com/tax" />
),
},
} ) }
</p>
</CardColumn>
<ColumnIllustration>
<BannerIllustrationStripeTax
src={ illustration }
alt={ __(
'Get Stripe Tax',
'woocommerce-gateway-stripe'
) }
/>
</ColumnIllustration>
</CardInner>
<ButtonsRowStripeTax>
<MainCTALink variant="secondary" onClick={ handleButtonClick }>
{ __( 'Get Stripe Tax', 'woocommerce-gateway-stripe' ) }
</MainCTALink>
<DismissButton
variant="secondary"
onClick={ handleBannerDismiss }
data-testid="dismiss"
>
{ __( 'Dismiss', 'woocommerce-gateway-stripe' ) }
</DismissButton>
</ButtonsRowStripeTax>
</CardBody>
);
};
8 changes: 8 additions & 0 deletions client/settings/settings-manager/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { getPromotionalBannerType } from 'wcstripe/settings/payment-settings/pro
import {
BNPL_PROMOTION_BANNER,
OC_PROMOTION_BANNER,
STRIPE_TAX_BANNER,
} from 'wcstripe/settings/payment-settings/constants';

const StyledTabPanel = styled( TabPanel )`
Expand Down Expand Up @@ -59,6 +60,13 @@ const SettingsManager = () => {
) {
initialBannerState = true;
}
if (
promotionalBannerType === STRIPE_TAX_BANNER &&
// eslint-disable-next-line camelcase
wc_stripe_settings_params?.show_stripe_tax_banner === '1'
) {
initialBannerState = true;
}
if (
promotionalBannerType === OC_PROMOTION_BANNER &&
// eslint-disable-next-line camelcase
Expand Down
5 changes: 5 additions & 0 deletions includes/admin/class-wc-stripe-settings-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,10 @@ public function admin_scripts( $hook_suffix ) {
// Show the OC promotional banner only if OC is disabled
&& ! $is_oc_enabled;

$show_stripe_tax_banner = get_option( 'wc_stripe_show_stripe_tax_banner', 'yes' ) === 'yes'
// Show the Stripe Tax banner only if OC is enabled
&& $is_oc_enabled;

$params = [
'time' => time(),
'i18n_out_of_sync' => $message,
Expand All @@ -273,6 +277,7 @@ public function admin_scripts( $hook_suffix ) {
'show_optimized_checkout_notice' => get_option( 'wc_stripe_show_optimized_checkout_notice', 'yes' ) === 'yes' ? true : false,
'show_bnpl_promotional_banner' => $show_bnpl_promotion_banner,
'show_oc_promotional_banner' => $show_oc_promotion_banner,
'show_stripe_tax_banner' => $show_stripe_tax_banner,
'is_test_mode' => $this->get_gateway()->is_in_test_mode(),
'plugin_version' => WC_STRIPE_VERSION,
'account_country' => $this->account->get_account_country(),
Expand Down
1 change: 1 addition & 0 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ If you get stuck, you can ask for help in the [Plugin Forum](https://wordpress.o
* Fix - Ensure state and postal code are optional in express checkout for Gulf countries (UAE, Bahrain, Kuwait, Oman, Qatar)
* Dev - Removes the `_wcstripe_feature_upe` feature flag and the related method from the `WC_Stripe_Feature_Flags` class
* Dev - Fixes some incorrect subscriptions support implementations for payment methods
* Add - New promotional banner to highlight the Stripe Tax extension for OCS-enabled merchants
* Fix - Ensure correct express checkout prices in block cart and checkout with non-default decimal configuration
* Fix - Disable express checkout when Amazon Pay is disabled and the only method
* Fix - Don't allow WP-Cron jobs to detach payment methods on staging sites
Expand Down
Loading