woocommerce / woocommerce-blocks

(Deprecated) This plugin has been merged into woocommerce/woocommerce
https://wordpress.org/plugins/woo-gutenberg-products-block/
GNU General Public License v3.0
403 stars 219 forks source link

Checkout Block does not render cart errors #5971

Closed manospsyx closed 1 year ago

manospsyx commented 2 years ago

Is your feature request related to a problem? Please describe.

Currently, the Checkout Block:

This issue is about (1). A separate issue has been opened to tackle (2).

An erroneous cart state might be a result of:

Certain types of errors create the need to prevent users from accessing the checkout block.

However, other types of errors might be designed to be rendered inside the Checkout Block. For example, developers often implement business rules such as "allow Delivery by Bike to be used if the shipping post code is 17235". In this scenario, when a customer selects Local Pickup after typing post code 17235 an error will be added in the errors field of the Store API response that may look like this:

Delivery by Bike is only available when shipping to an address inside the 17235 postcode area. If your address is within a 2km radius from our store, you can still reach out and make a special delivery arrangement.

Describe the solution you'd like

Currently, the Checkout Block does not create notices for the errors in cart route responses. Given that the errors field contents can change while filling in the checkout form, the Checkout Block should respond to changes in the errors field.

Ideally, the Checkout Block should also support multiple contexts for rendering errors:

Good UX design practices suggest that notices must be rendered close to where the interaction happens (temporally and spatially), and as close as possible to the specific field/element responsible for the error. The legacy Checkout was problematic in the way it handled errors, as it rendered all notices at the top of the page, and scrolled the user’s viewport there as soon as the checkout went into an error state.

The new Checkout improves the user experience significantly by introducing a new notice context inside the Payment Options section. To satisfy extensibility needs and encourage developers to follow solid UX practices, additional contexts could be introduced in:

By default all errors should be rendered at the top of the Checkout Block. However, we could introduce support for more notice rendering contexts by following a similar, error-code based approach as the one proposed for controlling access to the Checkout Block.

The idea is that a filterable wcSettings field could be used to specify different rendering locations/contexts for different error codes. Developers could hook into a filter to define where their error codes should be rendered by the Checkout Block.

Finally, as part of this work, we could improve the handling of errors returned by the Store API during failed order payment attempts (multiple errors can be returned once this PR is merged): Currently, all errors are rendered at the top of the block. Ideally, the Checkout Block could support a notice context (by error code, as before) for these errors, and render these, too, in the right location.

github-actions[bot] commented 2 years ago

This issue has been marked as stale because it has not seen any activity within the past 60 days. Our team uses this tool to help surface issues for review. If you are the author of the issue there's no need to comment as it will be looked at.

Internal: After 10 days with no activity this issue will be automatically be closed.
ralucaStan commented 1 year ago

@opr what are your thoughts on this point after the data store refactoring:

Does not provide a formal way to developers who need to control access to it.

opr commented 1 year ago

Hi @ralucaStan and @manospsyx

What Manos says (Currently, the Checkout Block: Does not convert the errors in cart responses to notices.) is true.

We can group error the current error handling in the Checkout block into:

Just to reiterate what Manos already said, a cart error is one that describes a problem with the state of the cart, i.e. cart item errors (stock, quantities etc.), coupon errors, other errors added by third party extensions, these exist permanently on the cart until the error is resolved.

A checkout error is one that is encountered when processing the checkout, i.e. when the place order button is pressed. Some of these errors could be: a payment method erroring when processing, having an incorrect or invalid address, an item being out of stock at the point of checkout.

Currently, we do not add "cart" errors to the Checkout block which isn't something that would have been solved by the refactor/implementation of data stores, rather it is something we need to purposely implement. We currently have a CheckoutProcessor component which is responsible for making requests to the checkout API which is where "checkout errors" get added to the store for rendering, but no equivalent for cart updates.

I tried adding some code to the Checkout block which renders the errors in the cart response, which works OK, but when trying to check out you get duplicate errors (because of the checkout endpoint and cart endpoint errors being shown).

I also noticed that we only seem to display the first error encountered during checkout (asked about this in Slack - p1667569781168059-slack-C8X6Q7XQU), which could lead to a frustrating UX since not all errors are shown, possibly needing multiple submission -> fix cycles from the shopper 😢 .

Without digging too deep into it at this stage, I believe there are two actionable points here at least:

  1. Refactor Store API Checkout processing to aggregate all errors encountered during the checkout process, not just the first
  2. Refactor the front-end error handling system in the Checkout block to:
    • Show errors currently in the wc/store/cart data store
    • Show only one error for each error code (e.g. an error about out of stock products with the code woocommerce_rest_product_out_of_stock will exist on the wc/store/cart data store and will be returned by the checkout endpoint. It should not be shown twice, so one of them will need to take precedence.) This won't be an issue for multiple out of stock items, since all item names are included in the same error: image
mikejolley commented 1 year ago

I've moved this to https://github.com/woocommerce/woocommerce-blocks/issues/7721 so the steps to resolve the issue are clearer.