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

Allow WooPay to request session data from merchant #8268

Merged
merged 24 commits into from
Mar 21, 2024

Conversation

bborman22
Copy link
Contributor

@bborman22 bborman22 commented Feb 23, 2024

Changes proposed in this Pull Request

This PR is to address a performance optimization in the WooPay Direct Checkout feature. This PR is one half of the fix for https://github.com/Automattic/woopay/issues/2480. This PR should be tested in tandem with https://github.com/Automattic/woopay/pull/2529.

The overall feature is to send a minimum amount of session data to WooPay to start, then let WooPay request the rest of the session data only if it is needed (i.e. the shopper is already logged into WooPay). If the shopper is not logged into WooPay the full session data should not be requested and the shopper should be taken to the merchant checkout page. More details about the feature and this optimization can be found in https://github.com/Automattic/woopay/issues/2480.

To accomplish that goal, this PR adds the following:

  • The ability to retrieve the minimum session data either on page load or through AJAX if necessary.
  • Pass the minimum session data to the connect page and receive a redirect URL.
  • Pass the encrypted and signed minimum session data to WooPay with a redirect.
  • A new REST endpoint that allows WooPay to request the full session data from the merchant.

The points of failure I focused on in this PR:

  • Inability to get the minimum session data.
  • Inability to retrieve full session data from the merchant.

In all cases when there is a failure there, we should default to taking the shopper to the merchant checkout page.

Notes
One key thing to note is the need to unset the preloaded_requests on the full session data response. This is unfortunate as it reduces some of the performance benefits. The reason this had to be unset is that the preloaded requests use rest_preload_api_request which just replicates a REST request but with no headers, which means no Cart-Token. This leads the cart not being found and instead returning an empty cart object breaking things on WooPay. I experimented with other ways to request the cart data doing something like this:

add_filter( 'woocommerce_store_api_disable_nonce_check', '__return_true' );
$cart_request = new WP_REST_Request('GET', '/wc/store/v1/cart' );
$cart_request->set_headers( $woopay_request->get_headers() );
$cart_data = rest_do_request( $cart_request );

$checkout_request = new WP_REST_Request('GET', '/wc/store/v1/checkout' );
$checkout_request->set_headers( $woopay_request->get_headers() );
$checkout_data = rest_do_request( $checkout_request );
remove_filter( 'woocommerce_store_api_disable_nonce_check', '__return_true' );

But ran into the problem that the initial requests had been fired and so WooCommerce wasn't trying to load the cart again since it already loaded it on the first requests in get_init_session_request and it generally seemed "too late" to update the current session to use the Cart Token. Given the time constraints I opted to leave the unset in for now and revisit in a separate issue, but if we find a good solution I'd love to add it to this PR!

Testing instructions

All tests should start with WooPay enabled, the _wcpay_feature_woopay_direct_checkout option set to 1 (enabled), and an item in the cart.

  • When the shopper is logged out of WooPay, clicking the Proceed to Checkout button should take the shopper to the merchant checkout. If third party cookies are disabled, there will be a request to woopay/?checkout_redirect=1&blog_id=... that results in a 302 redirect to the merchant checkout. In this case nothing should ever get stored on WooPay for the session.
  • When the shopper is logged in to WooPay, clicking the Proceed to Checkout button should take the shopper to the WooPay checkout. If third party cookies are disabled, there will be a request to woopay/?checkout_redirect=1&blog_id=... that results in a 302 redirect to WooPay with a platform_checkout_key.
  • Test the existing flows are unaffected:
    • Using the WooPay Express checkout button on the cart and checkout page.
    • Using the OTP modal on checkout page after entering an email address.
    • Checking out without WooPay.
  • Test in both blocks and shortcode cart.
  • Test with a shopper that is logged into the merchant store.
  • Test with the WooPay PR running on the staging sandbox to confirm environment compatibility.

  • 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 Feb 23, 2024

Test the build

Option 1. Jetpack Beta

  • Install and activate Jetpack Beta.
  • Use this build by searching for PR number 8268 or branch name add/woopay-merchant-request 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: a265f79
  • Build time: 2024-03-21 22:44:09 UTC

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

Copy link
Contributor

github-actions bot commented Feb 23, 2024

Size Change: +506 B (0%)

Total Size: 1.19 MB

Filename Size Change
release/woocommerce-payments/dist/cart.js 4.45 kB +250 B (+6%) 🔍
release/woocommerce-payments/dist/woopay-direct-checkout.js 4.58 kB +256 B (+6%) 🔍
ℹ️ View Unchanged
Filename Size
release/woocommerce-payments/assets/css/admin.css 1.06 kB
release/woocommerce-payments/assets/css/admin.rtl.css 1.06 kB
release/woocommerce-payments/assets/css/success.css 158 B
release/woocommerce-payments/assets/css/success.rtl.css 158 B
release/woocommerce-payments/dist/blocks-checkout-rtl.css 1.92 kB
release/woocommerce-payments/dist/blocks-checkout.css 1.91 kB
release/woocommerce-payments/dist/blocks-checkout.js 54 kB
release/woocommerce-payments/dist/checkout-rtl.css 405 B
release/woocommerce-payments/dist/checkout.css 406 B
release/woocommerce-payments/dist/checkout.js 36.9 kB
release/woocommerce-payments/dist/index-rtl.css 40 kB
release/woocommerce-payments/dist/index.css 40 kB
release/woocommerce-payments/dist/index.js 292 kB
release/woocommerce-payments/dist/multi-currency-analytics.js 1.05 kB
release/woocommerce-payments/dist/multi-currency-rtl.css 3.28 kB
release/woocommerce-payments/dist/multi-currency-switcher-block.js 59.4 kB
release/woocommerce-payments/dist/multi-currency.css 3.29 kB
release/woocommerce-payments/dist/multi-currency.js 54.4 kB
release/woocommerce-payments/dist/order-rtl.css 719 B
release/woocommerce-payments/dist/order.css 721 B
release/woocommerce-payments/dist/order.js 41.7 kB
release/woocommerce-payments/dist/payment-gateways-rtl.css 1.21 kB
release/woocommerce-payments/dist/payment-gateways.css 1.21 kB
release/woocommerce-payments/dist/payment-gateways.js 38.4 kB
release/woocommerce-payments/dist/payment-request-rtl.css 155 B
release/woocommerce-payments/dist/payment-request.css 155 B
release/woocommerce-payments/dist/payment-request.js 12.4 kB
release/woocommerce-payments/dist/product-details-rtl.css 155 B
release/woocommerce-payments/dist/product-details.css 155 B
release/woocommerce-payments/dist/product-details.js 9.09 kB
release/woocommerce-payments/dist/settings-rtl.css 11 kB
release/woocommerce-payments/dist/settings.css 10.8 kB
release/woocommerce-payments/dist/settings.js 199 kB
release/woocommerce-payments/dist/subscription-edit-page.js 669 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal-rtl.css 527 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal.css 527 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal.js 19.4 kB
release/woocommerce-payments/dist/subscription-product-onboarding-toast.js 710 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 18.5 kB
release/woocommerce-payments/dist/tos-rtl.css 235 B
release/woocommerce-payments/dist/tos.css 236 B
release/woocommerce-payments/dist/tos.js 21 kB
release/woocommerce-payments/dist/woopay-express-button-rtl.css 155 B
release/woocommerce-payments/dist/woopay-express-button.css 155 B
release/woocommerce-payments/dist/woopay-express-button.js 21.1 kB
release/woocommerce-payments/dist/woopay-rtl.css 4.44 kB
release/woocommerce-payments/dist/woopay.css 4.41 kB
release/woocommerce-payments/dist/woopay.js 71 kB
release/woocommerce-payments/includes/subscriptions/assets/css/plugin-page.css 622 B
release/woocommerce-payments/includes/subscriptions/assets/js/plugin-page.js 812 B
release/woocommerce-payments/vendor/automattic/jetpack-assets/build/i18n-loader.js 2.43 kB
release/woocommerce-payments/vendor/automattic/jetpack-assets/src/js/i18n-loader.js 1.01 kB
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/tracks-ajax.js 522 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/tracks-callables.js 581 B
release/woocommerce-payments/vendor/automattic/jetpack-identity-crisis/babel.config.js 160 B
release/woocommerce-payments/vendor/automattic/jetpack-identity-crisis/build/index.css 2.37 kB
release/woocommerce-payments/vendor/automattic/jetpack-identity-crisis/build/index.js 13.5 kB
release/woocommerce-payments/vendor/automattic/jetpack-identity-crisis/build/index.rtl.css 2.37 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/about.css 1.03 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin-empty-state.css 291 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin-order-statuses.css 403 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin.css 3.6 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/checkout.css 299 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/modal.css 742 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/view-subscription.css 572 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/wcs-upgrade.css 411 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/admin-pointers.js 544 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.8 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/jstz.min.js 3.83 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/meta-boxes-coupon.js 544 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.1 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/moment.min.js 11.6 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 502 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/payment-methods.js 355 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/single-product.js 429 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 781 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/modal.js 1.1 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/wcs-upgrade.js 1.27 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/build/index.css 392 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/build/index.js 3.05 kB

compressed-size-action

@bborman22 bborman22 marked this pull request as ready for review March 6, 2024 15:27
@bborman22 bborman22 requested a review from ricardo March 6, 2024 17:19
@bborman22
Copy link
Contributor Author

Adding @ricardo as a reviewer given the round robin assignment from the WooPay PR.

Copy link
Member

@ricardo ricardo left a comment

Choose a reason for hiding this comment

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

Dropped the main comment in the WooPay repo, but the approach looks good to me. Nice work!

Only left pretty minor questions on this PR.

All tests have passed:

✅ With third party cookies disabled, there's a request to woopay/?cache_checkout_key that redirects to the merchant checkout if the user is logged out.
✅ With third party cookies disabled, there's a request to woopay/?cache_checkout_key that redirects to the WooPay checkout if the user is logged in.
✅ Existing flows work as expected.
✅ Tested both in blocks and shortcode cart.
✅ Tested with a user logged in to the merchant store.
✅ Tested in sandbox with Jetpack blog auth.

@bborman22 bborman22 requested a review from ricardo March 13, 2024 14:22
Copy link
Member

@ricardo ricardo left a comment

Choose a reason for hiding this comment

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

LGTM and tests well.

@bborman22
Copy link
Contributor Author

@ricardo I have now updated the implementation to use an encrypted and signed session data passed through the redirect URL to WooPay instead of storing a temporary session on WooPay. This was based on my discussion with Systems and their recommendation that the storage could be unreliable in this use case. I have updated https://github.com/Automattic/woopay/pull/2529 as well to handle this implementation and so they should be tested again together.

Sorry for the back and forth on this PR, but this should be the last reworking of the implementation now that we've had discussions more broadly.

@bborman22 bborman22 requested a review from ricardo March 19, 2024 18:52
Copy link
Member

@ricardo ricardo left a comment

Choose a reason for hiding this comment

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

Thank you for all the thought and effort on this new approach. It indeed looks better than the previous cache idea. 🚀

I left 2 minor comments, but overall LGTM and tests well! 🎉

includes/woopay/class-woopay-session.php Outdated Show resolved Hide resolved
@bborman22 bborman22 requested a review from ricardo March 21, 2024 15:36
Copy link
Member

@ricardo ricardo left a comment

Choose a reason for hiding this comment

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

LGTM!

@bborman22 bborman22 added this pull request to the merge queue Mar 21, 2024
Merged via the queue into develop with commit c363808 Mar 21, 2024
22 checks passed
@bborman22 bborman22 deleted the add/woopay-merchant-request branch March 21, 2024 22:57
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.

3 participants