# Checkout Page Flow

> How the checkout demo connects CheckoutProvider, CheckoutForm, address forms, selectors, terms, notices, order summary, and Store API order placement.

<!-- Sources: src/Testing/E2E/Woo/WooDemoStoreBuilder.php; src/Testing/E2E/Woo/WooScenarioProvider.php; src/Patterns/Testing/TestCheckoutDemo/TestCheckoutDemo.php; src/Patterns/Testing/TestCheckoutDemo/TestCheckoutDemo.css; src/Woo/CheckoutFieldSchema.php; src/Components/Woo/CheckoutProvider/CheckoutProvider.php; src/Components/Woo/CheckoutForm/CheckoutForm.php; src/Components/Woo/BillingAddressForm/BillingAddressForm.php; src/Components/Woo/ShippingAddressForm/ShippingAddressForm.php; src/Components/Woo/ShippingMethodSelector/ShippingMethodSelector.php; src/Components/Woo/PaymentMethodSelector/PaymentMethodSelector.php; src/Components/Woo/TermsCheckbox/TermsCheckbox.php; src/Components/Woo/CheckoutNotices/CheckoutNotices.php; src/Components/Woo/PlaceOrderButton/PlaceOrderButton.php; src/Components/Woo/OrderSummary/OrderSummary.php; client/src/domains/woo/checkout-store.ts; client/src/domains/woo/checkout-field-schema.ts; client/src/domains/woo/checkout-validation.ts; tests/e2e/components/woo/behavior.spec.ts; tests/e2e/components/woo/lifecycle.spec.ts -->

# Checkout Page Flow

The checkout page flow is built from `TestCheckoutDemo`. It combines form-controlled checkout primitives with a read-only order summary that reuses cart item and total atoms.

## Flow Structure

```text
CheckoutProvider
  CheckoutForm
    BillingAddressForm
    ShippingAddressForm
    ShippingMethodSelector
    PaymentMethodSelector
    TermsCheckbox
    CheckoutNotices
    PlaceOrderButton
  OrderSummary
    Product row slot
      CartItemTitle
      CartAttributeList
      CartItemSubtotal
    Totals slot
      OrderSummaryTotalsList
        TotalsSubtotal
        TotalsDiscount
        TotalsShipping
        TotalsTax
        TotalsTotal
```

`CheckoutProvider` scopes checkout state for the form and child controls. `CheckoutForm` owns the submit event and the final Store API checkout request.

## Address Forms

`BillingAddressForm` and `ShippingAddressForm` share address form props and markup generation. They render fields from the checkout field schema, not from hard-coded field lists in the docs.

The checkout runtime handles:

- required billing fields,
- email validation,
- country and state selectors,
- state field visibility when the selected country has no state options,
- the shipping-address toggle and its embedded field group,
- local blocking before Store API submit when known-invalid fields are present.

E2E verifies country/state refresh and local validation behavior before checkout requests are sent.

## Selectors

`ShippingMethodSelector` and `PaymentMethodSelector` use the shared UIChoice mode logic. Both support select and button-radio presentation. In checkout, selected values are written into checkout state before the form is submitted.

Shipping method options come from package-aware Store API rates. Payment options come from Store API payment methods. The demo checkout uses select mode for both.

## Terms, Notices, And Submit

`TermsCheckbox` blocks submit when it is required and unchecked. `CheckoutNotices` renders checkout-scoped error messages. `PlaceOrderButton` triggers the parent `CheckoutForm`.

The form sets `data-ome-state` during validation, pending submit, success, and error states so authors can style the visible state without replacing the native Woo order lifecycle.

## Order Summary

`OrderSummary` is read-only. It renders current cart products and totals inside checkout, but it does not submit or mutate checkout data. The demo uses the `full_atoms` mode so product rows and totals are authored through slots:

| Slot | Components used |
| --- | --- |
| `products` | `CartItemTitle`, `CartAttributeList`, `CartItemSubtotal`. |
| `totals` | `OrderSummaryTotalsList` with subtotal, discount, shipping, tax, and total atoms. |

This reuse keeps cart and checkout total display aligned with the same normalized cart data.

## Store API And Native Hooks

Checkout submission goes through Woo Store API checkout. Lifecycle E2E verifies native Woo hooks still run through this path, including `woocommerce_store_api_checkout_update_order_from_request` and `woocommerce_rest_checkout_process_payment_with_context`.

That means Etch components can be authored visually while Woo plugins that rely on native checkout hooks still see the checkout lifecycle.

## E2E Coverage

| Scenario | Verified behavior |
| --- | --- |
| `checkout_success` | A full checkout form submits a real order. |
| `checkout_validation_error` | Invalid required fields are marked locally. |
| `checkout_terms_blocked` | Required terms block checkout and render notices. |
| `checkout_terms_success` | Checked terms allow the normal success flow. |
| `payment_selector_button_radio` | Payment selector button-radio mode renders and selects values. |
| `payment_selector_select` | Payment selector select mode renders trigger/content and selected values. |
| `shipping_selector_select` | Checkout-compatible shipping selection works in select mode. |
| `lifecycle_checkout` | Store API checkout completes through native Woo lifecycle hooks. |
