diff --git a/packages/js/components/changelog/add-onclick-plugins b/packages/js/components/changelog/add-onclick-plugins
new file mode 100644
index 00000000000..9be31ae01f2
--- /dev/null
+++ b/packages/js/components/changelog/add-onclick-plugins
@@ -0,0 +1,4 @@
+Significance: patch
+Type: update
+
+Add optional onclick to Plugins component
diff --git a/packages/js/components/src/plugins/index.tsx b/packages/js/components/src/plugins/index.tsx
index fc3971f0346..df2561ea28f 100644
--- a/packages/js/components/src/plugins/index.tsx
+++ b/packages/js/components/src/plugins/index.tsx
@@ -19,6 +19,7 @@ type PluginsProps = {
response: InstallPluginsResponse
) => void;
onError: ( errors: unknown, response: InstallPluginsResponse ) => void;
+ onClick?: () => void;
onSkip?: () => void;
skipText?: string;
autoInstall?: boolean;
@@ -37,6 +38,7 @@ export const Plugins = ( {
onAbort,
onComplete,
onError = () => null,
+ onClick = () => null,
pluginSlugs = [ 'woocommerce-services' ],
onSkip,
installText = __( 'Install & enable', 'woocommerce' ),
@@ -159,6 +161,7 @@ export const Plugins = ( {
}
disabled={ isRequesting && hasBeenClicked }
onClick={ () => {
+ onClick();
setHasBeenClicked( true );
installAndActivate();
} }
diff --git a/packages/js/data/changelog/add-stripe-tax-to task b/packages/js/data/changelog/add-stripe-tax-to task
new file mode 100644
index 00000000000..44d5916dff9
--- /dev/null
+++ b/packages/js/data/changelog/add-stripe-tax-to task
@@ -0,0 +1,4 @@
+Significance: patch
+Type: update
+
+Add stripe tax status to task type
diff --git a/packages/js/data/src/onboarding/types.ts b/packages/js/data/src/onboarding/types.ts
index 1e62f7036ca..a39fa627e63 100644
--- a/packages/js/data/src/onboarding/types.ts
+++ b/packages/js/data/src/onboarding/types.ts
@@ -29,8 +29,10 @@ export type TaskType = {
badge?: string;
additionalData?: {
woocommerceTaxCountries?: string[];
+ stripeTaxCountries?: string[];
taxJarActivated?: boolean;
avalaraActivated?: boolean;
+ stripeTaxActivated?: boolean;
woocommerceTaxActivated?: boolean;
woocommerceShippingActivated?: boolean;
};
diff --git a/plugins/woocommerce-admin/client/task-lists/fills/tax/avalara/card.tsx b/plugins/woocommerce-admin/client/task-lists/fills/tax/avalara/card.tsx
deleted file mode 100644
index d88b1c114aa..00000000000
--- a/plugins/woocommerce-admin/client/task-lists/fills/tax/avalara/card.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * External dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { getAdminLink } from '@woocommerce/settings';
-import interpolateComponents from '@automattic/interpolate-components';
-import { recordEvent } from '@woocommerce/tracks';
-
-/**
- * Internal dependencies
- */
-import { PartnerCard } from '../components/partner-card';
-import { TaxChildProps } from '../utils';
-import logo from './logo.png';
-
-export const Card: React.FC< TaxChildProps > = ( { task } ) => {
- const { additionalData: { avalaraActivated } = {} } = task;
-
- return (
- ,
- },
- } ),
- __(
- 'Cross-border and multi-channel compliance',
- 'woocommerce'
- ),
- __( 'Automate filing & remittance', 'woocommerce' ),
- __(
- 'Return-ready, jurisdiction-level reporting.',
- 'woocommerce'
- ),
- ] }
- terms={ '' }
- actionText={
- avalaraActivated
- ? __( 'Continue setup', 'woocommerce' )
- : __( 'Download', 'woocommerce' )
- }
- onClick={ () => {
- recordEvent( 'tasklist_tax_select_option', {
- selected_option: 'avalara',
- } );
-
- if ( avalaraActivated ) {
- window.location.href = getAdminLink(
- '/admin.php?page=wc-settings&tab=tax§ion=avatax'
- );
-
- return;
- }
-
- window.open(
- new URL(
- 'https://woocommerce.com/products/woocommerce-avatax/'
- ).toString(),
- '_blank'
- );
- } }
- />
- );
-};
diff --git a/plugins/woocommerce-admin/client/task-lists/fills/tax/avalara/logo.png b/plugins/woocommerce-admin/client/task-lists/fills/tax/avalara/logo.png
deleted file mode 100644
index 8430603eb9f..00000000000
Binary files a/plugins/woocommerce-admin/client/task-lists/fills/tax/avalara/logo.png and /dev/null differ
diff --git a/plugins/woocommerce-admin/client/task-lists/fills/tax/components/partner-card.scss b/plugins/woocommerce-admin/client/task-lists/fills/tax/components/partner-card.scss
index 7ad3feef6b7..9bcdb291555 100644
--- a/plugins/woocommerce-admin/client/task-lists/fills/tax/components/partner-card.scss
+++ b/plugins/woocommerce-admin/client/task-lists/fills/tax/components/partner-card.scss
@@ -41,7 +41,7 @@
.woocommerce-tax-partner-card__terms {
color: $gray-600;
- font-size: 9px;
+ font-size: 12px;
margin-bottom: $gap-smaller;
}
diff --git a/plugins/woocommerce-admin/client/task-lists/fills/tax/components/partner-card.tsx b/plugins/woocommerce-admin/client/task-lists/fills/tax/components/partner-card.tsx
index 30e2e1e5eb7..cef2b27b108 100644
--- a/plugins/woocommerce-admin/client/task-lists/fills/tax/components/partner-card.tsx
+++ b/plugins/woocommerce-admin/client/task-lists/fills/tax/components/partner-card.tsx
@@ -15,7 +15,8 @@ export const PartnerCard: React.FC< {
description: string;
benefits: ( string | JSX.Element )[];
terms: string | JSX.Element;
- actionText: string;
+ children?: React.ReactNode;
+ actionText?: string;
onClick: () => void;
isBusy?: boolean;
} > = ( {
@@ -27,6 +28,7 @@ export const PartnerCard: React.FC< {
actionText,
onClick,
isBusy,
+ children,
} ) => {
return (
@@ -59,14 +61,18 @@ export const PartnerCard: React.FC< {
{ terms }
-
+ { children ? (
+ children
+ ) : (
+
+ ) }
);
diff --git a/plugins/woocommerce-admin/client/task-lists/fills/tax/index.tsx b/plugins/woocommerce-admin/client/task-lists/fills/tax/index.tsx
index c4c95cdb95e..f98fd06a168 100644
--- a/plugins/woocommerce-admin/client/task-lists/fills/tax/index.tsx
+++ b/plugins/woocommerce-admin/client/task-lists/fills/tax/index.tsx
@@ -17,6 +17,7 @@ import {
useEffect,
useState,
createElement,
+ useMemo,
} from '@wordpress/element';
import { WooOnboardingTask } from '@woocommerce/onboarding';
@@ -25,6 +26,7 @@ import { WooOnboardingTask } from '@woocommerce/onboarding';
*/
import { redirectToTaxSettings } from './utils';
import { Card as WooCommerceTaxCard } from './woocommerce-tax/card';
+import { Card as StripeTaxCard } from './stripe-tax/card';
import { createNoticesFromResponse } from '../../../lib/notices';
import { getCountryCode } from '~/dashboard/utils';
import { ManualConfiguration } from './manual-configuration';
@@ -150,20 +152,21 @@ export const Tax: React.FC< TaxProps > = ( { onComplete, query, task } ) => {
} );
}, [ updateOptions ] );
- const getVisiblePartners = () => {
+ const partners = useMemo( () => {
const countryCode =
getCountryCode( generalSettings?.woocommerce_default_country ) ||
'';
const {
additionalData: {
woocommerceTaxCountries = [],
+ stripeTaxCountries = [],
taxJarActivated,
woocommerceTaxActivated,
woocommerceShippingActivated,
} = {},
} = task;
- const partners = [
+ const allPartners = [
{
id: 'woocommerce-tax',
card: WooCommerceTaxCard,
@@ -174,31 +177,35 @@ export const Tax: React.FC< TaxProps > = ( { onComplete, query, task } ) => {
! woocommerceShippingActivated &&
woocommerceTaxCountries.includes( countryCode ),
},
+ {
+ id: 'stripe-tax',
+ card: StripeTaxCard,
+
+ isVisible: stripeTaxCountries.includes( countryCode ),
+ },
];
- return partners.filter( ( partner ) => partner.isVisible );
- };
-
- const partners = getVisiblePartners();
+ return allPartners.filter( ( partner ) => partner.isVisible );
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- the partner list shouldn't be changing in the middle of interaction. for some reason the country is becoming null in a re-render and causing unexpected behaviour
+ }, [] );
+ const { auto } = query;
useEffect( () => {
- const { auto } = query;
-
if ( auto === 'true' ) {
onAutomate();
- return;
}
+ }, [ auto, onAutomate ] );
+ useEffect( () => {
if ( query.partner ) {
return;
}
-
recordEvent( 'tasklist_tax_view_options', {
options: partners.map( ( partner ) => partner.id ),
} );
- }, [ onAutomate, partners, query ] );
+ }, [ partners, query.partner ] );
- const getCurrentPartner = () => {
+ const currentPartner = useMemo( () => {
if ( ! query.partner ) {
return null;
}
@@ -206,7 +213,7 @@ export const Tax: React.FC< TaxProps > = ( { onComplete, query, task } ) => {
return (
partners.find( ( partner ) => partner.id === query.partner ) || null
);
- };
+ }, [ partners, query.partner ] );
const childProps = {
isPending,
@@ -220,8 +227,6 @@ export const Tax: React.FC< TaxProps > = ( { onComplete, query, task } ) => {
return ;
}
- const currentPartner = getCurrentPartner();
-
if ( ! partners.length ) {
return (
diff --git a/plugins/woocommerce-admin/client/task-lists/fills/tax/stripe-tax/card.tsx b/plugins/woocommerce-admin/client/task-lists/fills/tax/stripe-tax/card.tsx
new file mode 100644
index 00000000000..3795a7dee60
--- /dev/null
+++ b/plugins/woocommerce-admin/client/task-lists/fills/tax/stripe-tax/card.tsx
@@ -0,0 +1,107 @@
+/**
+ * External dependencies
+ */
+import { __ } from '@wordpress/i18n';
+import { getAdminLink } from '@woocommerce/settings';
+import { recordEvent } from '@woocommerce/tracks';
+import { Plugins } from '@woocommerce/components';
+import { dispatch, useDispatch } from '@wordpress/data';
+import { SETTINGS_STORE_NAME } from '@woocommerce/data';
+import { Button } from '@wordpress/components';
+
+/**
+ * Internal dependencies
+ */
+import { PartnerCard } from '../components/partner-card';
+import { TaxChildProps } from '../utils';
+import StripeTaxLogo from './stripe-tax-logo.svg';
+import { createNoticesFromResponse } from '~/lib/notices';
+
+const STRIPE_TAX_PLUGIN_SLUG = 'stripe-tax-for-woocommerce';
+
+const redirectToStripeTaxSettings = () => {
+ window.location.href = getAdminLink(
+ '/admin.php?page=wc-settings&tab=stripe_tax_for_woocommerce'
+ );
+};
+
+export const Card: React.FC< TaxChildProps > = ( {
+ task: {
+ additionalData: { stripeTaxActivated } = {
+ stripeTaxActivated: false,
+ },
+ },
+} ) => {
+ const { createSuccessNotice } = useDispatch( 'core/notices' );
+
+ return (
+ {} }
+ >
+ { stripeTaxActivated ? (
+
+ ) : (
+ {
+ recordEvent( 'tasklist_tax_select_option', {
+ selected_option: STRIPE_TAX_PLUGIN_SLUG,
+ } );
+ } }
+ onComplete={ () => {
+ recordEvent( 'tasklist_tax_install_plugin_success', {
+ selected_option: STRIPE_TAX_PLUGIN_SLUG,
+ } );
+ const { updateAndPersistSettingsForGroup } =
+ dispatch( SETTINGS_STORE_NAME );
+ updateAndPersistSettingsForGroup( 'general', {
+ general: {
+ woocommerce_calc_taxes: 'yes', // Stripe tax requires tax calculation to be enabled so let's do it here to save the user from doing it manually
+ },
+ } ).then( () => {
+ createSuccessNotice(
+ __(
+ "Stripe Tax for Woocommerce has been successfully installed. Let's configure it now.",
+ 'woocommerce'
+ )
+ );
+ redirectToStripeTaxSettings();
+ } );
+ } }
+ onError={ ( errors, response ) => {
+ recordEvent( 'tasklist_tax_install_plugin_error', {
+ selected_option: STRIPE_TAX_PLUGIN_SLUG,
+ errors,
+ } );
+ createNoticesFromResponse( response );
+ } }
+ installButtonVariant="secondary"
+ pluginSlugs={ [ STRIPE_TAX_PLUGIN_SLUG ] }
+ />
+ ) }
+
+ );
+};
diff --git a/plugins/woocommerce-admin/client/task-lists/fills/tax/stripe-tax/stripe-tax-logo.svg b/plugins/woocommerce-admin/client/task-lists/fills/tax/stripe-tax/stripe-tax-logo.svg
new file mode 100644
index 00000000000..d290cefc63f
--- /dev/null
+++ b/plugins/woocommerce-admin/client/task-lists/fills/tax/stripe-tax/stripe-tax-logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/plugins/woocommerce/changelog/add-stripe-tax-onboarding-tax-task b/plugins/woocommerce/changelog/add-stripe-tax-onboarding-tax-task
new file mode 100644
index 00000000000..7de97421d64
--- /dev/null
+++ b/plugins/woocommerce/changelog/add-stripe-tax-onboarding-tax-task
@@ -0,0 +1,4 @@
+Significance: minor
+Type: update
+
+Added Stripe tax in onboarding tax task
diff --git a/plugins/woocommerce/src/Admin/Features/OnboardingTasks/Tasks/Tax.php b/plugins/woocommerce/src/Admin/Features/OnboardingTasks/Tasks/Tax.php
index ee8f9ce99be..ba33d9b2362 100644
--- a/plugins/woocommerce/src/Admin/Features/OnboardingTasks/Tasks/Tax.php
+++ b/plugins/woocommerce/src/Admin/Features/OnboardingTasks/Tasks/Tax.php
@@ -129,9 +129,11 @@ class Tax extends Task {
return array(
'avalara_activated' => PluginsHelper::is_plugin_active( 'woocommerce-avatax' ),
'tax_jar_activated' => class_exists( 'WC_Taxjar' ),
+ 'stripe_tax_activated' => PluginsHelper::is_plugin_active( 'stripe-tax-for-woocommerce' ),
'woocommerce_tax_activated' => PluginsHelper::is_plugin_active( 'woocommerce-tax' ),
'woocommerce_shipping_activated' => PluginsHelper::is_plugin_active( 'woocommerce-shipping' ),
'woocommerce_tax_countries' => self::get_automated_support_countries(),
+ 'stripe_tax_countries' => self::get_stripe_tax_support_countries(),
);
}
@@ -162,4 +164,54 @@ class Tax extends Task {
return $tax_supported_countries;
}
+
+ /**
+ * Get an array of countries that support Stripe tax.
+ *
+ * @return array
+ */
+ private static function get_stripe_tax_support_countries() {
+ // https://docs.stripe.com/tax/supported-countries#supported-countries accurate as of 2024-08-26.
+ // countries with remote sales not included.
+ return array(
+ 'AU',
+ 'AT',
+ 'BE',
+ 'BG',
+ 'CA',
+ 'HR',
+ 'CY',
+ 'CZ',
+ 'DK',
+ 'EE',
+ 'FI',
+ 'FR',
+ 'DE',
+ 'GR',
+ 'HK',
+ 'HU',
+ 'IE',
+ 'IT',
+ 'JP',
+ 'LV',
+ 'LT',
+ 'LU',
+ 'MT',
+ 'NL',
+ 'NZ',
+ 'NO',
+ 'PL',
+ 'PT',
+ 'RO',
+ 'SG',
+ 'SK',
+ 'SI',
+ 'ES',
+ 'SE',
+ 'CH',
+ 'AE',
+ 'GB',
+ 'US',
+ );
+ }
}