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

Wait for Stripe js to load before using it #9770

Merged
merged 13 commits into from
Nov 26, 2024

Conversation

danielmx-dev
Copy link
Contributor

@danielmx-dev danielmx-dev commented Nov 20, 2024

Fixes #9709

Changes proposed in this Pull Request

  • Change the WCPayAPI#getStripe method from synchronous to asynchronous. This allow us to wait for Stripe.js to load in scenarios where the script download may be delayed due to third party plugins that ask for user's consent (see details in Handling of Stripe JS with GDPR & minifier plugins #9709).

Testing instructions

  • Enable the Cookiebot plugin
    • Configure it using the settings from this comment.
    • By default, the plugin may not block stripe-js in your site. To force it you'll need to do the following changes:
      • Use "Manual cookie-blocking mode" in the Cookiebot settings (WP Admin).
      • Update Script_Loader_Tag::__construct in the plugin code to always set the script_loader_tag filter.
      • Add the following line to the end of Cookiebot_Addons::build_container in the plugin code: $this->container->get( 'Script_Loader_Tag_Interface' )->add_tag( 'stripe', array( 'marketing', 'statistics' ) );
  • Enable Express Checkout (Google Pay/Apple Pay) and one of the BNPL payment methods.

Before

  • Go to the WooCommerce checkout page. Do not accept the cookie banner.
  • WooPayments, Express Checkout, and BNPL PMME elements are all missing.
  • The following error (or something similar, referring to an issue with the data type of stripe) should appear in the console: ReferenceError: Stripe is not defined
  • If you accept the consent banner, the problem persists. Until you reload the page the problem goes away.
  • Clear the consent cookie to continue testing: document.cookie = 'CookieConsent=; Path=/;';
  • The same happens for Classic Checkout, Cart and Product Pages.

After:

  • Go to the WooCommerce checkout page. Do not accept the cookie banner.
  • WooPayments, Express Checkout, and BNPL PMME elements are all missing/loading.
  • Accept the consent.
  • The elements now should load without having to reload the page.
  • Clear the cookie and repeat the process in Classic Checkout, Cart (Blocks and Classic), Product Pages, Add Payment Method, Pay for Order.

Regression Testing

Disable Cookiebot and verify that the same pages (Blocks/Classic Checkout, Cart (Blocks and Classic), Product Pages.) continue working as expected.


  • Run npm run changelog to add a changelog file, choose patch to leave it empty if the change is not significant. You can add multiple changelog files in one PR by running this command a few times.
  • Covered with tests (or have a good reason not to test in description ☝️)
  • Tested on mobile (or does not apply)

Post merge

@botwoo
Copy link
Collaborator

botwoo commented Nov 20, 2024

Test the build

Option 1. Jetpack Beta

  • Install and activate Jetpack Beta.
  • Use this build by searching for PR number 9770 or branch name fix/9709-load-stripe-asynchronously in your-test.site/wp-admin/admin.php?page=jetpack-beta&plugin=woocommerce-payments

Option 2. Jurassic Ninja - available for logged-in A12s

🚀 Launch a JN site with this branch 🚀

ℹ️ Install this Tampermonkey script to get more options.


Build info:

  • Latest commit: 6392934
  • Build time: 2024-11-26 15:36:29 UTC

Note: the build is updated when a new commit is pushed to this PR.

Copy link
Contributor

github-actions bot commented Nov 20, 2024

Size Change: +677 B (0%)

Total Size: 1.34 MB

Filename Size Change
release/woocommerce-payments/dist/blocks-checkout.js 54.4 kB +120 B (0%)
release/woocommerce-payments/dist/cart-block.js 16.9 kB +123 B (+1%)
release/woocommerce-payments/dist/checkout.js 33.1 kB +84 B (0%)
release/woocommerce-payments/dist/express-checkout.js 15 kB +97 B (+1%)
release/woocommerce-payments/dist/product-details.js 12.1 kB +80 B (+1%)
release/woocommerce-payments/dist/tokenized-express-checkout.js 16.2 kB +95 B (+1%)
release/woocommerce-payments/dist/woopay-express-button.js 24.6 kB +78 B (0%)
ℹ️ View Unchanged
Filename Size
release/woocommerce-payments/assets/css/admin.css 1.37 kB
release/woocommerce-payments/assets/css/admin.rtl.css 1.37 kB
release/woocommerce-payments/assets/css/success.css 182 B
release/woocommerce-payments/assets/css/success.rtl.css 184 B
release/woocommerce-payments/dist/blocks-checkout-rtl.css 2.66 kB
release/woocommerce-payments/dist/blocks-checkout.css 2.66 kB
release/woocommerce-payments/dist/cart.js 5.73 kB
release/woocommerce-payments/dist/checkout-rtl.css 939 B
release/woocommerce-payments/dist/checkout.css 939 B
release/woocommerce-payments/dist/express-checkout-rtl.css 229 B
release/woocommerce-payments/dist/express-checkout.css 229 B
release/woocommerce-payments/dist/frontend-tracks.js 854 B
release/woocommerce-payments/dist/index-rtl.css 52.6 kB
release/woocommerce-payments/dist/index.css 52.5 kB
release/woocommerce-payments/dist/index.js 302 kB
release/woocommerce-payments/dist/multi-currency-analytics.js 1.08 kB
release/woocommerce-payments/dist/multi-currency-rtl.css 4.46 kB
release/woocommerce-payments/dist/multi-currency-switcher-block.js 60.6 kB
release/woocommerce-payments/dist/multi-currency.css 4.46 kB
release/woocommerce-payments/dist/multi-currency.js 57.3 kB
release/woocommerce-payments/dist/order-rtl.css 730 B
release/woocommerce-payments/dist/order.css 730 B
release/woocommerce-payments/dist/order.js 42 kB
release/woocommerce-payments/dist/payment-gateways-rtl.css 1.32 kB
release/woocommerce-payments/dist/payment-gateways.css 1.32 kB
release/woocommerce-payments/dist/payment-gateways.js 38.4 kB
release/woocommerce-payments/dist/plugins-page-rtl.css 386 B
release/woocommerce-payments/dist/plugins-page.css 386 B
release/woocommerce-payments/dist/plugins-page.js 20.1 kB
release/woocommerce-payments/dist/product-details-rtl.css 433 B
release/woocommerce-payments/dist/product-details.css 436 B
release/woocommerce-payments/dist/settings-rtl.css 11.6 kB
release/woocommerce-payments/dist/settings.css 11.5 kB
release/woocommerce-payments/dist/settings.js 224 kB
release/woocommerce-payments/dist/subscription-edit-page.js 703 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal-rtl.css 524 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal.css 524 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal.js 20.2 kB
release/woocommerce-payments/dist/subscription-product-onboarding-toast.js 730 B
release/woocommerce-payments/dist/subscriptions-empty-state-rtl.css 120 B
release/woocommerce-payments/dist/subscriptions-empty-state.css 120 B
release/woocommerce-payments/dist/subscriptions-empty-state.js 19.3 kB
release/woocommerce-payments/dist/tokenized-express-checkout-rtl.css 229 B
release/woocommerce-payments/dist/tokenized-express-checkout.css 229 B
release/woocommerce-payments/dist/tos-rtl.css 235 B
release/woocommerce-payments/dist/tos.css 235 B
release/woocommerce-payments/dist/tos.js 21.8 kB
release/woocommerce-payments/dist/woopay-direct-checkout.js 6.13 kB
release/woocommerce-payments/dist/woopay-rtl.css 4.52 kB
release/woocommerce-payments/dist/woopay.css 4.49 kB
release/woocommerce-payments/dist/woopay.js 71.6 kB
release/woocommerce-payments/includes/subscriptions/assets/css/plugin-page.css 625 B
release/woocommerce-payments/includes/subscriptions/assets/js/plugin-page.js 814 B
release/woocommerce-payments/vendor/automattic/jetpack-assets/build/i18n-loader.js 2.46 kB
release/woocommerce-payments/vendor/automattic/jetpack-assets/build/jetpack-script-data.js 767 B
release/woocommerce-payments/vendor/automattic/jetpack-assets/build/react-jsx-runtime.js 553 B
release/woocommerce-payments/vendor/automattic/jetpack-assets/src/js/i18n-loader.js 1.02 kB
release/woocommerce-payments/vendor/automattic/jetpack-assets/src/js/script-data.js 69 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/babel.config.js 163 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/identity-crisis.css 2.45 kB
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/identity-crisis.js 14.2 kB
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/identity-crisis.rtl.css 2.45 kB
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-admin-create-user.css 198 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-admin-create-user.js 280 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-admin-create-user.rtl.css 198 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-login.css 625 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-login.js 333 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-login.rtl.css 626 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-users.js 417 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/tracks-ajax.js 521 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/tracks-callables.js 584 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-admin-create-user.css 215 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-admin-create-user.js 521 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-login.css 721 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-login.js 412 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-users.js 621 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/about.css 1.04 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin-empty-state.css 294 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin-order-statuses.css 408 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin.css 3.59 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/checkout.css 301 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/modal.css 746 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/view-subscription.css 574 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/wcs-upgrade.css 414 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/admin-pointers.js 543 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/admin.js 9.4 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/jstz.js 6.78 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/jstz.min.js 3.84 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/meta-boxes-coupon.js 545 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/meta-boxes-subscription.js 2.52 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/moment.js 22.2 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/moment.min.js 11.7 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/payment-method-restrictions.js 1.29 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/wcs-meta-boxes-order.js 507 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/payment-methods.js 358 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/single-product.js 428 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/view-subscription.js 1.38 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/wcs-cart.js 782 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/modal.js 1.09 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/wcs-upgrade.js 1.26 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/build/index.css 391 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/build/index.js 3.04 kB

compressed-size-action

@danielmx-dev danielmx-dev requested review from a team and mdmoore and removed request for a team November 22, 2024 15:16
@danielmx-dev danielmx-dev self-assigned this Nov 22, 2024
@danielmx-dev danielmx-dev marked this pull request as ready for review November 22, 2024 15:16
Copy link
Member

@mdmoore mdmoore left a comment

Choose a reason for hiding this comment

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

This was testing well with the initial test cases. When I attempted to test Pay for Order, I noticed the credit card form wasn't loading. Testing further while logged in, it seems Stripe JS isn't being loaded other pages like Checkout and Cart either. This is likely related to the the hardcoded changes in the Cookiebot plugin combined with the fact that the banner doesn't appear when logged in (so cookies can't be accepted), but I want to double check with you on this and whether you've been able to test while logged in?

@danielmx-dev
Copy link
Contributor Author

This was testing well with the initial test cases. When I attempted to test Pay for Order, I noticed the credit card form wasn't loading. Testing further while logged in, it seems Stripe JS isn't being loaded other pages like Checkout and Cart either. This is likely related to the the hardcoded changes in the Cookiebot plugin combined with the fact that the banner doesn't appear when logged in (so cookies can't be accepted), but I want to double check with you on this and whether you've been able to test while logged in?

I assume it may be related to this setting ? Cookiebot CMP on front-end while logged in

image

However, I'm not able to replicate the issue with the setting On or Off. I would assume that if the banner doesn't show up then the script shouldn't be blocked.

Copy link
Member

@mdmoore mdmoore left a comment

Choose a reason for hiding this comment

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

I assume it may be related to this setting ? Cookiebot CMP on front-end while logged in

Yeah that did the trick for displaying the banner. With that setting off, Stripe.js never loads for logged in users in my testing. I know you're unable to reproduce it, so maybe it's something with my settings. Do you think this is something to be concerned about? If not, this has my approval.

@danielmx-dev
Copy link
Contributor Author

Yeah that did the trick for displaying the banner. With that setting off, Stripe.js never loads for logged in users in my testing. I know you're unable to reproduce it, so maybe it's something with my settings. Do you think this is something to be concerned about? If not, this has my approval.

What happens if you test the faulty scenario on develop? Although the behavior of the Cookiebot is concerning, I don't think the changes in this PR make the situation worse, if another plugin is just blocking our dependencies there's little we can do about it.

@danielmx-dev danielmx-dev added this pull request to the merge queue Nov 26, 2024
Merged via the queue into develop with commit d8192f7 Nov 26, 2024
24 checks passed
@danielmx-dev danielmx-dev deleted the fix/9709-load-stripe-asynchronously branch November 26, 2024 16:13
jaclync added a commit that referenced this pull request Nov 27, 2024
* develop:
  Wait for Stripe js to load before using it (#9770)
  Remove redundant stripe payment elements mount for pay for order (#9813)
  Enforce proper return types for methods get_order_from_event_body (#9761)
  Update phpcompatibility to develop version to get sniffs for PHP 8 (#9697)
  Enable ECE Tracks Events when WooPay is disabled (#9793)
  chore: rename PRB constants to ECE (#9768)
  Amend changelog entries for release 8.5.1
  fix: remove 'test mode' badge from shortcode checkout (#9800)
  Update version and add changelog entries for release 8.5.1
),
} );
}
const cartData = await getCartApiHandler().getCart();
Copy link
Contributor

Choose a reason for hiding this comment

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

This change introduced a difference in how errors are handled.

Before the change, any errors by getCart() weren't propagated, and they could have just generated a warning in the console.

Now, there is no try/catch, so any errors from getCart() are being propagated and will lead to a termination of the execution.

@danielmx-dev let me know your thoughts - I reverted this in #9849

Comment on lines +61 to +75
async getStripe( forceAccountRequest = false ) {
const maxWaitTime = 600 * 1000; // 600 seconds
const waitInterval = 100;
let currentWaitTime = 0;
while ( ! window.Stripe ) {
await new Promise( ( resolve ) =>
setTimeout( resolve, waitInterval )
);
currentWaitTime += waitInterval;
if ( currentWaitTime > maxWaitTime ) {
throw new Error( 'Stripe object not found' );
}
}
return this.__getStripe( forceAccountRequest );
}
Copy link
Contributor

@frosso frosso Nov 29, 2024

Choose a reason for hiding this comment

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

While commenting on the try/catch below, I noticed this implementation: I was wondering if you had considered leveraging JavaScript Proxies to detect when Stripe is added to the window object, rather than using a timeout in a loop.

I was also wondering if you had considered raising the error in a more user-friendly fashion, like in the payment method box, to allow the customer to review the cookies consent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Handling of Stripe JS with GDPR & minifier plugins
4 participants