woocommerce / woocommerce-gateway-stripe

The official Stripe Payment Gateway for WooCommerce
https://wordpress.org/plugins/woocommerce-gateway-stripe/
228 stars 201 forks source link

[Enhancement]: How to disable action – woocommerce_gateway_stripe_init on product page #3366

Open whatcodehaveyougit opened 3 weeks ago

whatcodehaveyougit commented 3 weeks ago

Describe the solution you'd like

In the plugin ‘woocommerce-gateway-stripe’ there is a file called woocommerce-gateway-stripe.php On line 734 there is this line: add_action( ‘plugins_loaded’, ‘woocommerce_gateway_stripe_init’ ); I want to REMOVE this action as I don’t want the scripts it triggers to run. It basically instantiates a new class which requires lots of scripts, 1 of which I do not want as it makes a GET request to stripe for payment JS (a very heavy file - 600kb) and as I am not processing any payment on the product page, I should not needs these scripts.

It seems that I am not the first person to have this issue after doing some research.. Was not able to find a solution that worked after following the threads to the end. If you google 'Stripe JS on WooCommerce Product page destroys page speed' you will see.

I have tried various ways to remove it including things like this:

add_action(‘plugins_loaded’, ‘remove_stripe_action_wp_loaded’, 200);

function remove_stripe_action_wp_loaded() {
// Remove the action if it exists
if ( has_action('plugins_loaded', 'woocommerce_gateway_stripe_init') ) {
remove_action('plugins_loaded', 'woocommerce_gateway_stripe_init');
error_log('Successfully removed woocommerce_gateway_stripe_init from plugins_loaded on wp_loaded.');
}

However, it is very stubborn and nothing I try is working. Is there a specific WooCommerce hook which I can hook into in order to stop this from running? I only want it to not run on certain pages which is why I am doing this and not just disabling it.

You will know that you have disabled it correctly if there is no API called made to – https://js.stripe.com/v3/?ver=3.0

Right now this is being called on this page and it is really slowing it down

Describe alternatives you've considered

The alternative involves downloading another plugin which will disable a certain plugin on a certain page which does work but is not the nicest solution.

The ideal is that this script does not load on this page by default.

After that if there is just a hook that enables me to disable it on a certain type of page that would be great.

Additional context

No response

NicolaModugno commented 3 weeks ago

Hello @whatcodehaveyougit , I am facing the same issue.

The original code of the gateway is: add_action( 'plugins_loaded', 'woocommerce_gateway_stripe_init' ); .. it means that the callback functions is registered with a standard priority of 10.

So in your code you should pass a lower priority (less then 10). This is a working code (I do not check with has_action as remove_action checks itself):

    add_action( 'plugins_loaded', function() {
        if ( ! \boolval( preg_match( "/carrello|checkout|cassa|wp-admin|wp-json|wp-ajax/i", $_SERVER['REQUEST_URI'] ) ) ) {
            remove_action( 'plugins_loaded', 'woocommerce_gateway_stripe_init' );
            remove_action( 'woocommerce_blocks_loaded', 'woocommerce_gateway_stripe_woocommerce_block_support' );
        }
    }, 0 );

As you can see, I remove the Stripe init only if the visit is NOT for certain pages.

Hope it helps.

whatcodehaveyougit commented 3 weeks ago

Hello, @NicolaModugno , thanks for your reply.

I have just tried this solution but I am still seeing the heavy Stripe script loading.

I even took out the if statement just to see if it was an issues with that but even then it was still loading on the page. Just to confirm you have the WooCommerce Plugin installed with the WooCommerce stripe gateway plugin too? And this solution is working on your website ?

If so would you be able to send a link? :) thanks

aheckler commented 3 weeks ago

You can stop the Stripe JS from being loaded on product pages with a simple filter:

add_filter( 'wc_stripe_load_scripts_on_product_page_when_prbs_disabled', '__return_false' );

See https://github.com/woocommerce/woocommerce-gateway-stripe/issues/2065 for a lot more discussion on this.

Of course, that filter will be overridden/ignored if you have PRBs (Apple Pay, Google Pay) enabled on product pages. It also means you run the risk of increased fraud, since the Stripe JS is one mechanism used to detect suspicious behavior. More info at these links:

https://docs.stripe.com/js/including

https://docs.stripe.com/disputes/prevention/advanced-fraud-detection#when-signals-are-collected

whatcodehaveyougit commented 3 weeks ago

Thanks for your reply @aheckler

That is really good to know that disabling this script runs this risk, looked at that post and will continue to read it in more detail.

I did try that filter however I am still seeing the GET request to 'https://js.stripe.com/v3/?ver=3.0' on this page - https://lucyketcham.com/wp/online-course/abrasive-wheels/

Just to confirm that is the script which it should be stopping ? (I have checked and Apple/Google Pay are not activated on this merchants WooCommerce )

NicolaModugno commented 3 weeks ago

@whatcodehaveyougit I confirm WooCommerce + WooCommerce Gateway Stripe, but I can't share a link (site of customer). Maybe in your case it is the WooCommerce mini cart block that requires the Stripe script.

@aheckler thank you for the clarifications and pointing us in the right direction. Please, consider that with the filter you suggested the "wc-stripe-blocks-checkout-style" css is still loaded. It is a little resource, I know, but with optimization in mind is that necessary?

Maybe an enhancement could be that Stripe script is loaded (for fraud risk limitation) without all dependencies actually loaded. Consider that in this moment stripe requires wc-checkout that requires countries (about 50KB of unnecessary scripts)...

Thank you!!

aheckler commented 3 weeks ago

@whatcodehaveyougit

I did try that filter however I am still seeing the GET request to 'https://js.stripe.com/v3/?ver=3.0' on this page - https://lucyketcham.com/wp/online-course/abrasive-wheels/

I think this may be because you have a mini-cart, as @NicolaModugno indicated, but you should also be able to disable the script on cart using the second filter:

add_filter( 'wc_stripe_load_scripts_on_cart_page_when_prbs_disabled', '__return_false' );

Maybe try that and see if it still loads?

@NicolaModugno

Please, consider that with the filter you suggested the "wc-stripe-blocks-checkout-style" css is still loaded. It is a little resource, I know, but with optimization in mind is that necessary?

There's already an open issue for this here: https://github.com/woocommerce/woocommerce-gateway-stripe/issues/3317

Maybe an enhancement could be that Stripe script is loaded (for fraud risk limitation) without all dependencies actually loaded. Consider that in this moment stripe requires wc-checkout that requires countries (about 50KB of unnecessary scripts)...

I'll leave addressing this up to our developer team, of which I am not a member. :) I imagine they'll triage this issue sooner or later and post a response.

Thanks!

NicolaModugno commented 3 weeks ago

I saw that issue but it has no activity. However, thank you for the support @aheckler . Hope to hear good news soon about the thread :)

whatcodehaveyougit commented 3 weeks ago

Hello @aheckler

I had already tried this infact and it also doesn't work sadly!

Just looked at the Network tab again and it does seem to be that the API call is being made in the file: wp-content/plugins/woocommerce/assets/client/blocks/mini-cart-frontend.js?ver=eba896c62201a23c4175

So this is not even in the woocommerce stripe gateway plugin. I am unable to see where this script is loaded in though..

That is strange as I the script did stop loading when I made sure that the class I mentioned above was not instantiated.
So when I comment out the line in the woocommerce-gateway-stripe plugin
add_action( 'plugins_loaded', 'woocommerce_gateway_stripe_init' ); it does not load the stripe js script. So this plugin has something to do with it even though the file is not being loaded from the plugin itself.

The best solution I think would be to just defer the script due to the potential security implications you open yourself up to by taking it off product pages completely. I did see an open PR for that but there seems to be a lot of testing still to do so I can't imagine that will be completed soon..

Any other ideas would be welcome but seems like I may just have to do some more research in order to see I defer this script: content/plugins/woocommerce/assets/client/blocks/mini-cart-frontend.js and hopefully speed up my product pages..!