# Store API and Native Hooks

> How Woo components use Store API while preserving native WooCommerce hooks.

<!-- Sources: client/src/domains/woo/store-api-client.ts; client/src/domains/woo/cart-store.ts; client/src/domains/woo/checkout-store.ts; src/Woo/StoreApiExtension.php; src/Testing/E2E/Woo/WooLifecycleProbe.php; tests/e2e/components/woo/lifecycle.spec.ts; tests/e2e/components/woo/setup.ts -->

# Store API and Native Hooks

Woo components send cart and checkout mutations through WooCommerce Store API. That is important because Store API still runs Woo's native cart, pricing, checkout, payment, order, and status hooks.

The lifecycle E2E suite proves this with a test-only Woo hook probe.

## Cart Requests

`WooStoreApiClient` sends cart requests with a nonce and cart token. The cart store queues mutations so the UI is not racing multiple responses.

| UI action | Store API request | Native behavior tested |
| --- | --- | --- |
| Product add | `POST /cart/add-item` | Add-to-cart validation can block, add item data can be injected, and add actions fire. |
| Quantity change | `POST /cart/update-item` | Cart totals refresh after Woo recalculates cart state. |
| Remove item | `POST /cart/remove-item` | Cart item rows and totals refresh before empty state appears. |
| Apply coupon | `POST /cart/apply-coupon` | Discount totals and coupon rows update. |
| Remove coupon | `DELETE /cart/coupons?code=...` | Coupon rows and totals update. |
| Shipping selection | `POST /cart/select-shipping-rate` | Selected package rate and totals update. |

## Checkout Requests

`WooCheckoutStore` also queues requests:

| UI action | Store API request | State |
| --- | --- | --- |
| Boot checkout | `GET /checkout` | `loading` then `idle`. |
| Persist field changes | `PUT /checkout?__experimental_calc_totals=true` | `updating` then `idle`. |
| Place order | `POST /checkout` | `processing` then `success` or `error`. |

If a payment result has a redirect URL, the checkout form redirects after the successful response.

## Native Hook Coverage

`WooLifecycleProbe` records deterministic hook events. E2E then checks the order and visible UI effects.

| E2E scenario | What it proves |
| --- | --- |
| `lifecycle_add_to_cart` with block mode | `woocommerce_add_to_cart_validation` can block cart mutation and the Woo notice renders as text. |
| `lifecycle_add_to_cart` with allow mode | `woocommerce_add_cart_item_data`, `woocommerce_add_to_cart_validation`, `woocommerce_add_cart_item`, and `woocommerce_add_to_cart` fire for Etch form submissions. |
| `shipping_selector` with pricing mode | `woocommerce_before_calculate_totals` changes item price and `woocommerce_cart_calculate_fees` changes totals rendered by cart and order summary components. |
| `lifecycle_checkout` | Store API checkout creates an order through native hooks, writes order meta, records payment context, and reaches an order-received flow. |

## Error Handling

Store API errors are converted into safe notices:

- Cart errors become cart notices with a source such as `add-to-cart`, `quantity`, `remove`, `coupon`, `shipping`, `stock`, or `variation`.
- Checkout errors become checkout notices and field error markers when Woo exposes field keys.
- Known Woo checkout error codes are mapped to field keys when Store API does not include `data.params`.
- Notice message text is normalized and rendered with text content, not injected as HTML.

## Store API Extension Data

`StoreApiExtension` registers an `ohmyetch` namespace on the Store API cart endpoint when Woo Blocks APIs are available. It exposes capability metadata:

| Capability | Meaning |
| --- | --- |
| `cart_count` | OME cart count components are supported for the response. |
| `add_to_cart` | OME add-to-cart components are supported for the response. |

This metadata is read-only and does not replace Woo's native cart schema.
