woocommerce/plugins/woocommerce-blocks/docs/third-party-developers/extensibility/checkout-block/how-checkout-processes-an-o...

148 lines
13 KiB
Markdown
Raw Normal View History

# How The Checkout Block Processes an Order
This document will shed some light on the inner workings of the Checkout flow. More specifically, what happens after a user hits the “Place Order” button.
## Structure
The following areas are associated with processing the checkout for a user.
### The Payment Registry [:file_folder:](https://href.li/?https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/blocks-registry/payment-methods/registry.ts#L1)
The payment registry stores all the configuration information for each payment method. We can register a new payment method here with the `registerPaymentMethod` and `registerExpressPaymentMethod `functions, also available to other plugins.
### Data Stores
Data stores are used to keep track of data that is likely to change during a users session, such as the active payment method, whether the checkout has an error, etc. We split these data stores by areas of concern, so we have 2 data stores related to the checkout: `wc/store/checkout` [:file_folder:](https://href.li/?https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/data/checkout/index.ts#L1) and `wc/store/payment` [:file_folder:](https://href.li/?https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/data/payment-methods/index.ts#L1) . Data stores live in the `assets/js/data` folder.
### Contexts
Contexts are used to make data available to the Checkout block. Each of these provide data and functions related to a specific area of concern, via the use of a hook. For example, if we wanted to use the `onPaymentSetup` handler from the `PaymentEventsContext` context, we can do it like this:
```js
const { onPaymentSetup } = usePaymentEventsContext();
```
The other job of contexts is to run side effects for our Checkout block. What typically happens is that the `CheckoutEvents` and `PaymentEvents` will listen for changes in the checkout and payment data stores, and dispatch actions on those stores based on some logic.
For example, in the `CheckoutEvents` context, we dispatch the `emitValidateEvent` action when the checkout status is `before_processing`. There is a lot of similar logic that reacts to changes in status and other state data from these two stores.
The Checkout contexts are:
| Context | Description |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| [CheckoutEvents](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/base/context/providers/cart-checkout/checkout-events/index.tsx#L4) | Provides some checkout related event handlers |
| [ PaymentEvents ](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/base/context/providers/cart-checkout/payment-methods/payment-method-events-context.tsx#L3) | Provides event handlers related to payments |
| [ CustomerData ](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/base/context/providers/cart-checkout/customer/index.tsx#L1) | Provides data related to the current customer |
| [ ShippingData ](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/base/context/providers/cart-checkout/shipping/index.js#L1) | Provides data and actions related to shipping errors |
### The Checkout Processor (checkout-processor.js)
The checkout processor component subscribes to changes in the checkout or payment data stores, packages up some of this data and calls the StoreApi `/checkout` endpoint when the conditions are right.
## The Checkout Provider
The [checkout provider](https://github.com/woocommerce/woocommerce-blocks/blob/trunk/assets/js/base/context/providers/cart-checkout/checkout-provider.js), wraps all the contexts mentioned above around the `CheckoutProcessor` component.
---
## Checkout User Flow
Below is the complete checkout flow
### 1\. Click the "Place Order" button
The checkout process starts when a user clicks the button
### 2\. Checkout status is set to `before_processing` [:file_folder:](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/base/context/providers/cart-checkout/checkout-events/index.tsx#L167)
As soon as the user clicks the "Place Order" button, we change the checkout status to _"before_processing"_. This is where we handle the validation of the checkout information.
### 3\. Emit the `checkout_validation_before_processing` event [:file_folder:](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/base/context/providers/cart-checkout/checkout-events/index.tsx#L113)
This is where the WooCommerce Blocks plugin and other plugins can register event listeners for dealing with validation. The event listeners for this event will run and if there are errors, we set checkout status to `idle` and display the errors to the user.
If there are no errors, we move to step 4 below.
### 4\. Checkout status is set to `processing` [:file_folder:](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/data/checkout/thunks.ts#L76)
The processing status is used by step 5 below to change the payment status
### 5\. Payment status is set to `processing` [:file_folder:](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/base/context/providers/cart-checkout/payment-methods/payment-method-events-context.tsx#L94)
Once all the checkout processing is done and if there are no errors, the payment processing begins
### 6\. Emit the `payment_processing` event [:file_folder:](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/data/payment-methods/thunks.ts#L42)
The `payment_processing` event is emitted. Otherplugins can register event listeners for this event and run their own code.
For example, the Stripe plugin checks the address and payment details here, and uses the stripe APIs to create a customer and payment reference within Stripe.
**Important note: The actual payment is not taken here**. **It acts like a pre-payment hook to run any payment plugin code before the actual payment is attempted.**
### 7\. Execute the `payment_processing` event listeners and set the payment and checkout states accordingly [:file_folder:](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/data/payment-methods/thunks.ts#L54-L132)
If the registered event listeners return errors, we will display this to the user.
If the event listeners are considered successful, we sync up the address of the checkout with the payment address, store the `paymentMethodData` in the payment store, and set the payment status property `{ isProcessing: true }`.
### 8\. POST to `/wc/store/v1/checkout` [:file_folder:](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/base/context/providers/cart-checkout/checkout-processor.js#L234)
The `/checkout` StoreApi endpoint is called if there are no payment errors. This will take the final customer addresses and chosen payment method, and any additional payment data, then attempts payment and returns the result.
**Important: payment is attempted through the StoreApi, NOT through the `payment_processing` event that is sent from the client**
### 9\. The `processCheckoutResponse` action is triggered on the checkout store [:file_folder:](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/data/checkout/thunks.ts#L33)
Once the fetch to the StoreApi `/checkout` endpoint returns a response, we pass this to the `processCheckoutResponse` action on the `checkout` data store.
It will perform the following actions:
- It sets the redirect url to redirect to once the order is complete
- It stores the payment result in the `checkout` data store.
- It changes the checkout status to `after_processing` (step 10)
### 10\. Checkout status is set to `after_processing` [:file_folder:](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/data/checkout/thunks.ts#L42)
The `after_processing` status indicates that we've finished the main checkout processing step. In this step, we run cleanup actions and display any errors that have been triggered during the last step.
### 11\. Emit the `checkout_after_processing_with_success` event [:file_folder:](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/data/checkout/thunks.ts#L118-L128)
If there are no errors, the `checkout_after_processing_with_success` event is triggered. This is where other plugins can run some code after the checkout process has been successful.
Any event listeners registered on the `checkout_after_processing_with_success` event will be executed. If there are no errors from the event listeners, `setComplete` action is called on the `checkout` data store to set the status to `complete` (step 13). An event listener can also return an error here, which will be displayed to the user.
### 12\. Emit the `checkout_after_processing_with_error` event [:file_folder:](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/data/checkout/thunks.ts#L104-L116)
If there has been an error from step 5, the `checkout_after_processing_with_error` event will be emitted. Other plugins can register event listeners to run here to display an error to the user. The event listeners are processed and display any errors to the user.
### 13\. Set checkout status to `complete` [:file_folder:](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/data/checkout/utils.ts#L146)
If there are no errors, the `status` property changes to `complete` in the checkout data store. This indicates that the checkout process is complete.
### 14\. Redirect [:file_folder:](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/base/context/providers/cart-checkout/checkout-processor.js#L193-L197)
Once the checkout status is set to `complete`, if there is a `redirectUrl` in the checkout data store, then we redirect the user to the URL.
## Other notable things
### Checking payment methods
A payment method is registered with a [configuration object](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/types/type-defs/payments.ts#L60-L83). It must include a function named `canMakePayment`. This function should return true if the payment method can be used to pay for the current cart. The current cart (items, addresses, shipping methods etc.) is passed to this function, and each payment method is responsible for reporting whether it can be used.
The `checkPaymentMethodsCanPay()` [function](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/data/payment-methods/check-payment-methods.ts#L26) goes through all the registered payment methods, checks if they can pay, and if so, adds them to the `availablePaymentMethods` property on the payment data store.
The `checkPaymentMethodsCanPay()` [function](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/data/payment-methods/check-payment-methods.ts#L26) must be called in a few places in order to validate the payment methods before they can be displayed to the user as viable options.
- [Here](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/data/cart/index.ts#L46-L57), once the cart loads, we want to be able to display express payment methods, so we need to validate them first.
- [Here](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/data/cart/index.ts#L42-L43), once the cart changes, we may want to enable/disable certain payment methods
- [Here](https://github.com/woocommerce/woocommerce-blocks/blob/4af2c0916a936369be8a4f0044683b90b3af4f0d/assets/js/data/checkout/index.ts#L44-L49), once the checkout loads, we want to verify all registered payment methods
2023-02-24 12:08:34 +00:00
<!-- FEEDBACK -->
---
[Docs] Update links from WooCommerce.com to Woo.com for the Woo Blocks documentation (#43055) * Update woocommerce.com URLs in documentation and code files * Add changelog * Fix github repository link in extend-rest-api-add-custom-fields.md Co-authored-by: Albert Juhé Lluveras <contact@albertjuhe.com> * Add github reporter (#42974) * Add github reporter * Add changelog --------- Co-authored-by: Jon Lane <jon.lane@automattic.com> * Fix product task redirect to support grouped and external products (#43051) * Rearrange product redirection logic to better accept grouped and external produc types * Add changelog * Modify feedback modal actions (#43005) * Adapt feedback modal actions * Add changelogs * Modify comments * Fix tests * Fix test * Update class-wc-gateway-bacs.php (#43054) * Update class-wc-gateway-bacs.php Fix typo in textdomain * Add changefile(s) from automation for the following project(s): woocommerce --------- Co-authored-by: github-actions <github-actions@github.com> * [Product Block Editor]: Add `Linked product` tab (#43009) * add linked-products to group IDs * add Linked Products tab * tweak hideConditions condition * changelog * fix typo in doc comment * Introduce a product type selection within the new experience (#41823) * Create a relation between the product type and the product block template * Add 'patterns' to name the kind of products that can be created for a specific template * Resolve template using its id as a template query param * Rename ProductEditPattern to ProductTemplate * Rename get_patterns hook to woocommerce_product_editor_get_product_templates * Return the list of templates to the client * Set layout template events as array * Register the layout template based on the product template or the post type in case of product variations * Registering non supported product types * Create and register the woocommerce/product-details-section-description block * Add the product type to the section description * Create product type selector * Fix menu item style * Highlight selected menu item * Set the selected product template * Set product template title to lowercase in the content description * Rename blocks by blockTemplates under the AbstractBlockTemplate class * Rename to woocommerce_product_editor_product_templates filter * Remove product_template_ prefix from the supported_product_types map * Rename get_formatted to to_JSON and convert the props to client side like * Refactor get_product_templates * Fix icon resolution * Add a confirmation modal for unsupported product templates * Add changelog files * Remove product types using for testing * Fix redirection when changing to a non supported product template * Set the change button state to busy when it is saving the product * Fix php linter errors * Fix rebase conflict * Move ProductTemplate to Automattic\WooCommerce\Admin\Features\ProductBlockEditor namespace * Add the to_json definition to the BlockTemplateInterface * Create default product template by custom product type if it does not have a template associated yet * Fix some comments and product template creation validation * Add support to load the product template icon from an external resource * Fix php linter * Fix the changelog description * [Experimental] Interactivity Dropdown multi-select mode, ratings filter and introduce each directive (#42981) --------- Co-authored-by: David Arenas <david.arenas@automattic.com> * Introduce the transient files engine (#42877) Co-authored-by: Corey McKrill <916023+coreymckrill@users.noreply.github.com> * Change marketplace install API request to POST instead of GET (#43033) * Change marketplace install API to using POST instead of GET * Fix linting error * Add changefile(s) from automation for the following project(s): woocommerce --------- Co-authored-by: github-actions <github-actions@github.com> * Prep trunk for 8.6 cycle (#43021) Prep trunk for 8.6 cycle with version bump to 8.6.0-dev Co-authored-by: WooCommerce Bot <no-reply@woo.com> * Add Playwright tests for All Reviews, Reviews by Product and Reviews by Category blocks (#42903) * Remove Reviews blocks Puppeteer tests * Minor code cleanup * Typos * Create publishAndVisitPost() editor util * Fix subcategories when importing products in Playwright and add reviews * Add Reviews blocks tests in Playwright * More typos * Add changefile(s) from automation for the following project(s): woocommerce-blocks * Create a 'reviews' object in data.ts so we can store reviews data in one single place * Update test so instead of creating a new post in each test, we go to the already-created post * Add source comments to reviews data to match it with the script --------- Co-authored-by: github-actions <github-actions@github.com> * Release: Remove 8.5 change files (#43022) Delete changelog files from 8.5 release Co-authored-by: WooCommerce Bot <no-reply@woo.com> Co-authored-by: Alex López <alex.lopez@automattic.com> * Delete changelog files based on PR 43033 (#43079) Delete changelog files for 43033 Co-authored-by: WooCommerce Bot <no-reply@woo.com> * Delete changelog files based on PR 43051 (#43081) Delete changelog files for 43051 Co-authored-by: WooCommerce Bot <no-reply@woo.com> * Interactive Price Filter: use `context` instead of `state` (#42980) * feat: use context instead of state * fix: temporary move the context to inner element for diffing to work * fix: update context before navigation for optimistic UI * Load google analytics gtag script asynchronously in WooCommerce Blocks (#43040) Co-authored-by: github-actions <github-actions@github.com> * set WOOCOMMERCE_BLOCKS_PHASE to 1 for the production build (#43074) * set WOOCOMMERCE_BLOCKS_PHASE to 1 for the production build * Add changefile(s) from automation for the following project(s): woocommerce --------- Co-authored-by: github-actions <github-actions@github.com> * Revert "Fix schedule sales error" (#43094) Revert "Fix schedule sales error (#42700)" This reverts commit 9b800aa179b25bafebfed0da8c00eec892272cb4. * [Product Block Editor]: add Linked product sections. First approach. (#43013) * add Linked products, Upsell section * changelog * add Cross-lens section * add links to the Upsell sections * changelog * fix lint issues * fix lint issus * fix linting issue :-| * check whether the linked product group is defined * [Product Block Editor]: introduce ShoppingBags component (#43042) * add ShoppingBags component * Add ShoppingBag story * changelog * Fix: Collection data being leaked between Collection Filters blocks (#43044) * fix: CYS - change heading color (#43076) * fix: CYS - change heading color * Add changefile(s) from automation for the following project(s): woocommerce --------- Co-authored-by: github-actions <github-actions@github.com> Co-authored-by: Patricia Hillebrandt <patriciahillebrandt@gmail.com> * Delete changelog files based on PR 43074 (#43118) Delete changelog files for 43074 Co-authored-by: WooCommerce Bot <no-reply@woo.com> * [Product Block Editor]: fix feature flag to hide the Linked products (#43119) * fix flag to hide/show product editor * changelog * Add changelog --------- Co-authored-by: Albert Juhé Lluveras <contact@albertjuhe.com> Co-authored-by: Jonathan Lane <lanej0@users.noreply.github.com> Co-authored-by: Jon Lane <jon.lane@automattic.com> Co-authored-by: louwie17 <lourensschep@gmail.com> Co-authored-by: Fernando Marichal <fernando.marichal@automattic.com> Co-authored-by: Marc Guay <marc.guay@gmail.com> Co-authored-by: github-actions <github-actions@github.com> Co-authored-by: Damián Suárez <rdsuarez@gmail.com> Co-authored-by: Maikel David Pérez Gómez <maikel.perez@automattic.com> Co-authored-by: Sam Seay <samueljseay@gmail.com> Co-authored-by: Néstor Soriano <konamiman@konamiman.com> Co-authored-by: Corey McKrill <916023+coreymckrill@users.noreply.github.com> Co-authored-by: Kyle Nel <22053773+kdevnel@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: WooCommerce Bot <no-reply@woo.com> Co-authored-by: Alex López <alex.lopez@automattic.com> Co-authored-by: Tung Du <dinhtungdu@gmail.com> Co-authored-by: Thomas Roberts <5656702+opr@users.noreply.github.com> Co-authored-by: Luigi Teschio <gigitux@gmail.com> Co-authored-by: Patricia Hillebrandt <patriciahillebrandt@gmail.com>
2023-12-29 15:28:11 +00:00
[We're hiring!](https://woo.com/careers/) Come work with us!
2023-02-24 12:08:34 +00:00
🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/checkout-block/how-checkout-processes-an-order.md)
<!-- /FEEDBACK -->