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

Refresh cart/checkout page when ECE or PRBs are dismissed #9794

Closed
frosso opened this issue Nov 22, 2024 · 7 comments · Fixed by #9888
Closed

Refresh cart/checkout page when ECE or PRBs are dismissed #9794

frosso opened this issue Nov 22, 2024 · 7 comments · Fixed by #9888
Assignees
Labels
component: checkout Issues related to Checkout component: payment request button Apple Pay, Google Pay, etc focus: checkout payments type: enhancement The issue is a request for an enhancement.

Comments

@frosso
Copy link
Contributor

frosso commented Nov 22, 2024

Description

When GooglePay/ApplePay dialogs are triggered on the cart or checkout pages (both shortcode and block-based), the customer's shipping address is submitted to the backend to update the cart. Within these dialogs, the customer can further interact with the ECE, such as:

  • Changing the shipping address
  • Selecting a different shipping method

If the customer dismisses the payment dialog without completing the payment, the underlying cart/checkout page remains in its original state without reflecting any updates from the GooglePay/ApplePay dialog interaction.

This behavior leads to an inconsistency: the changes appear lost on the cart/checkout page but are correctly stored and shown after a page refresh or navigation.

To improve user experience and maintain state consistency:

  • Either the cart/checkout page should revert to its prior state (before the dialog interaction), or
  • It should reflect the most up-to-date state from the GooglePay/ApplePay dialog.

This affects both blocks and shortcode implementation.
This affects both cart and checkout pages.

Screen.Recording.2024-11-22.at.5.53.25.PM.mov

Acceptance criteria

  • Consistent State After Dialog Dismissal:
    • When a customer dismisses the ECE dialog, the cart/checkout page must either:
      • Revert to the pre-dialog state, or
      • Reflect the updates from the dialog interaction (e.g., updated shipping rate, address).
  • Consistency Between Implementations:
    • Behavior is consistent on both shortcode-based and block-based implementations of cart and checkout pages.
  • No Manual Refresh Required:
    • Changes should reflect in real time without requiring the user to refresh the page or navigate away and back.

Designs

N/A

Testing instructions

  1. As a merchant, enable GooglePay/ApplePay in the WooPayments settings
  2. As a merchant, ensure you have a couple of shipping options
  3. As a customer, add a physical product to the cart
  4. Navigate to the cart/checkout page
  5. Enter an address to get some shipping rates
  6. Select a shipping rate
  7. Click the GooglePay/ApplePay buttons to trigger their dialog
  8. Interact with the addresses to get different shipping rates
  9. Select a different shipping rate
  10. Dismiss the dialog
  11. Confirm that the underlying page either reverts to the pre-dialog state or reflects the updated state correctly without requiring a refresh
  12. Manually refresh the page to ensure the previous information is persisted
  13. Complete a payment using ECE to ensure the payment flow remains unaffected by the enhancement
  14. Verify that the correct shipping details and order totals are submitted during the payment process

Dev notes

Additional context

@frosso frosso added component: checkout Issues related to Checkout component: payment request button Apple Pay, Google Pay, etc focus: checkout payments type: enhancement The issue is a request for an enhancement. labels Nov 22, 2024
@bborman22
Copy link
Contributor

@rafaelzaleski
Copy link
Contributor

@pierorocca, following a discussion with @bborman22, we believe it would be helpful to run the proposed flow by you to clarify a few specific points:

  1. Would a simple page refresh be an acceptable solution? While it’s easier to maintain and more resistant to bugs, it may result in a suboptimal user experience.
  2. Should the cart update only when the shopper makes changes on the payment sheet, or every time the payment sheet is opened, regardless of changes?

@frosso, how would this implementation interact with tokenized carts, especially in scenarios where they are kept separate from the session cart?

@frosso
Copy link
Contributor Author

frosso commented Dec 10, 2024

Should the cart update only when the shopper makes changes on the payment sheet, or every time the payment sheet is opened, regardless of changes?

Keep in mind that the interaction with the ECE dialog would not exclude changes to the shipping address.
When the dialog is opened, a request is made to the server with the primary GooglePay/ApplePay shipping address. This address is stored in the customer's cart and used to fetch shipping rates.
The customer might further interact with the dialog to make additional changes to the selected address (if they have more than one) or the chosen shipping rates.

i.e.: the shipping address might be updated for physical cart contents as soon as the dialog is opened.

how would this implementation interact with tokenized carts, especially in scenarios where they are kept separate from the session cart?

The tokenized cart is kept separate from the main customer's cart only when the ECE dialog is opened on the product page - on the product page scenario, the main customer's cart remains unaffected.

I guess it could be considered an inconsistency with the express checkout button behavior on cart and checkout since the main cart is interacted with on those pages.
But it's also worth noting that the customer's cart is separate on product pages regardless, so there might be an expectation from the behavior being indeed different.

@pierorocca
Copy link
Contributor

pierorocca commented Dec 10, 2024

@rafaelzaleski can we technically replicate this behavior, excluding the fact there's no lightbox overlay?
https://github.com/user-attachments/assets/cb3aaa3b-ce15-45ec-9586-da366f33cca8

@frosso
Copy link
Contributor Author

frosso commented Dec 11, 2024

Interestingly, Shopify doesn't seem to have the limitation we have with Stripe & ECE buttons w/ UK (or CA) addresses.

Currently, we need to account for possibly redacted data coming from ECE when a UK or CA shipping address is selected:

/**
* Normalizes postal code in case of redacted data from Apple Pay.
*
* @param string $postcode Postal code.
* @param string $country Country.
*/
public function get_normalized_postal_code( $postcode, $country ) {
/**
* Currently, Apple Pay truncates the UK and Canadian postal codes to the first 4 and 3 characters respectively
* when passing it back from the shippingcontactselected object. This causes WC to invalidate
* the postal code and not calculate shipping zones correctly.
*/
if ( Country_Code::UNITED_KINGDOM === $country ) {
// Replaces a redacted string with something like N1C0000.
return str_pad( preg_replace( '/\s+/', '', $postcode ), 7, '0' );
}
if ( Country_Code::CANADA === $country ) {
// Replaces a redacted string with something like H3B000.
return str_pad( preg_replace( '/\s+/', '', $postcode ), 6, '0' );
}
return $postcode;
}

This behavior can be observed in the test WooPayments test environment when selecting a UK address:
Image

You'll notice that the ECE/GooglePay/ApplePay won't provide full address data - the ZIP code in particular is also redacted (the value provided is N1C, instead of N1C 0ZZ like displayed in the dialog):
Image

Similar behavior for CA addresses:
Image
Image

I tested the flow on Shopify by adding a GB address.
Interestingly, the non-redacted ZIP code data is sent to Shopify
Image

I wonder if this could become a limitation on our end 😬 but normally, updating the screen in the background of the block-based cart & checkout shouldn't be too tricky. We can just dispatch the wp.data.dispatch('wc/store/cart').setShippingAddress({...}) action.

Image
Image

The problem arises more on the shortcode cart & checkout, since they don't have a similar action we could use (AFAIK).
There's jQuery('form.woocommerce-shipping-calculator').trigger('submit'), which we could manually fire, I guess 🤷 but that just resets the form to its previous state, discarding any changes made in the ECE dialog. Which would become inconsistent with the block-based implementation.
We'd need to manually update the address in the hidden WC fields - it becomes messy 😬

And still, I don't know what the implications of the address being potentially redacted could be.

@pierorocca
Copy link
Contributor

Redacted zip aside, for Blocks which the goal is to increase adoption this year, let's go with the real-time refresh. For shortcode, page refresh on modal close or any other option that shows the data selected in the payment sheet.

Thanks for the research @frosso and the visuals.

@pierorocca
Copy link
Contributor

Nice UX optimization all. The little touches matter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: checkout Issues related to Checkout component: payment request button Apple Pay, Google Pay, etc focus: checkout payments type: enhancement The issue is a request for an enhancement.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants