WooCommerce

WooCommerce Store API for block cart and checkout

WooCommerce

The WooCommerce Store API is the JSON surface behind Cart and Checkout blocks, mini-cart blocks, and any headless cart you build on WordPress without admin keys. I am Alan Vo, a Gold Coast web developer with 18 years on WooCommerce catalogues. In 2026 if your shop still posts to admin-ajax.php for cart fragments while checkout speaks /wc/store/v1/, you are maintaining two carts. This note is how I read the Store API on staging, extend it without breaking blocks, and debug production when totals or nonces lie.

WooCommerce documents the public contract in the Store API overview. It is unauthenticated, cookie-session based for browser shoppers, and scoped to the current customer. It is not the authenticated WC REST API that ERP jobs use. Treat it as the wire format the block checkout React tree already trusts.

Why the WooCommerce Store API matters in 2026

The WooCommerce Store API matters in 2026 because WooCommerce ships new checkout and cart features on this namespace first. Classic shortcode checkout still exists, but block cart, block checkout, express payment buttons, and many extension updates assume /wp-json/wc/store/v1/ responses. When a plugin author says their gateway "supports blocks," they mean it registers with the block payment registry and completes orders through Store API checkout, not that they patched checkout.js.

If you migrated checkout already, read how to migrate to WooCommerce block checkout for the page and gateway checklist. This article is the network tab underneath that migration: which routes fire, what headers they need, and why a 409 response is sometimes correct behaviour.

Headless and hybrid setups also depend on the same API. WooCommerce exposes Cart Tokens so a decoupled front end can hold cart state in a header instead of relying on WordPress cookies alone. WooCommerce 9.8 documented CORS exposure for that token so browser clients can read it without a proxy. That is a production detail for teams building a React storefront against the same WordPress cart session.

Performance work still intersects here. Block checkout debounces address updates into Store API calls. Heavy plugins that hook every cart recalculation show up as long /cart/update-customer or /checkout requests and hurt INP. I tie that to WooCommerce checkout INP when the symptom is sluggish fields, not a blank payment area.

How the WooCommerce Store API actually works

The WooCommerce Store API actually works as a WordPress REST namespace at /wp-json/wc/store/v1/. Version v1 is the only published version today. Read routes such as products, cart, and checkout draft data use GET. Cart mutations use POST on /cart/add-item, /cart/remove-item, /cart/update-item, /cart/apply-coupon, /cart/remove-coupon, /cart/update-customer, and /cart/select-shipping-rate. Checkout uses GET to read state, PUT to persist fields, and POST to place the order and run payment. The Cart API and Checkout API documents list payloads and error shapes.

WooCommerce Store API checkout fields on a laptop in a studio

Every POST to cart endpoints and every checkout request needs either a valid nonce or a Cart Token. WooCommerce documents Nonce Tokens with the header name Nonce, created in PHP via wp_create_nonce( 'wc_store_api' ). Successful responses return an updated Nonce header the client must store for the next write. Cart Tokens come back on successful cart responses as a Cart-Token header from GET /cart; send that header on later writes and you can skip the nonce on those routes.

That split is how I debug "invalid nonce" tickets. A theme or optimization plugin caches a cart GET and serves a stale nonce to the block. A security plugin strips response headers. A headless client forgets to rotate the nonce after each POST. The fix is almost never "disable security." It is align caching rules with Cache-Control: no-store behaviour WooCommerce expects on cart routes, or move the headless client to Cart Tokens.

Block cart and checkout do not treat the browser as source of truth for totals. WooCommerce's data flow guide describes hydration from the server on load, then debounced pushes when shoppers edit addresses or checkout fields. Customer address edits batch to /cart/update-customer. Additional checkout fields may use PUT /checkout. The server returns a full cart object; the client replaces store state. Extensions that only update PHP session data without returning it in that response create ghost discounts: the classic mini-cart shows one total, the block another.

For extensions that must recalculate the cart when a shopper clicks something in the block UI, WooCommerce forbids ad hoc AJAX that mutates cart state on the client. You register an update callback and call extensionCartUpdate from block JavaScript so the hit goes to /cart/extensions with a namespace. WooCommerce documents that pattern in Updating the cart on-demand. I use it for fee lines, redemption flows, and complex shipping rules that must run before payment. Skipping it and writing directly to wc/store/cart in custom React breaks the next core update.

Checkout POST sends billing and shipping address objects, payment_method, optional payment_data for the gateway, and optionally expected_total as a string in minor currency units. When expected_total is present, WooCommerce can reject the order with HTTP 409 and code woocommerce_rest_checkout_total_mismatch if tax, shipping, or coupons changed between the shopper confirming the total and submitting payment. The refreshed cart in that error is intentional. Do not treat every 409 as a bug.

Shopping bags on a counter used while testing WooCommerce Store API

Products and collection blocks read /products and related routes for catalog data. That is the same API family but a read-heavy path. Confusing Store API product queries with the authenticated REST API is a common staging mistake. Store API cannot enumerate other customers' orders or change store settings. ERP sync stays on authenticated keys and HPOS tables, which I covered in WooCommerce HPOS for the order storage side, not for cart JSON.

Batching exists for multiple cart operations in one round trip via /batch. Variation add-to-cart requires variation arrays with attribute and value keys; the Cart API doc warns that attribute names must match what the API expects, not always the slug you use in templates. I reproduce failed adds on staging with curl using a fresh nonce from a logged-in session before I blame the theme.

Conflict responses on cart actions return HTTP 409 with a machine-readable reason and often embed the current cart so the UI can reconcile. That design replaces the old checkout HTML refresh. Your monitoring should log 409 rate separately from 500s. A spike after a sale starts is often coupon exhaustion, not server meltdown.

Production checklist for WooCommerce Store API integrations

Store API work is not done when add-to-cart works once in Chrome. I run this list before go-live on any block cart or hybrid headless project.

  1. Confirm WooCommerce and WooCommerce Blocks versions match the gateway's block support matrix. A classic-only shipping plugin is a checkout stopper even if cart GET works.
  2. Map every plugin that touches cart, fees, shipping, or checkout. Note which register Store API extensions versus which still hook woocommerce_cart_calculate_fees only.
  3. In devtools, filter wc/store/v1 on cart, checkout, and mini-cart pages. Save a HAR from empty cart through paid order for regression tests.
  4. Verify POST requests include Nonce or Cart-Token and that responses rotate nonce headers. Fail a request on purpose and confirm the UI recovers.
  5. Test variable products, mixed carts, coupons, free shipping thresholds, and tax-inclusive display. Totals should match the order admin screen.
  6. Test logged-out and logged-in shoppers, plus account creation at checkout if enabled.
  7. For headless or subdomain fronts, exercise Cart Token from GET /cart and confirm CORS exposes Cart-Token if the browser must read it (WooCommerce 9.8+).
  8. Ensure page caches and CDNs do not cache /wp-json/wc/store/v1/cart or checkout routes. Respect no-store on cart responses.
  9. Register extension cart updates through register_update_callback instead of custom admin-ajax cart writers.
  10. Gateways: confirm block payment method registration and that payment_data fields match the gateway docs for Store API checkout.
  11. If you use expected_total, confirm the client sends minor units consistent with totals.total_price in the cart object.
  12. Compare Store API order payloads with webhooks and ERP plugins. Custom checkout fields must appear in the order meta the warehouse expects.
  13. After deploy, watch 409 and 403 rates on store API routes for 24 hours during a small promotion.
WordPress admin on a screen during WooCommerce Store API work

What breaks when the WooCommerce Store API is ignored

Custom AJAX endpoints that add fees or change quantities without going through Store API update callbacks desync block state. Shoppers see one total in the order summary and pay another. Support teams reproduce it inconsistently because classic fragments still update the header mini-cart.

Caching plugins that treat REST like static JSON break nonces first. Symptoms include "Unable to add to cart" on first click and success on second. Full-page cache on checkout is worse: shoppers see another user's empty cart shape in HTML even when API calls are private.

Mixing shortcode cart with block checkout is still common on Elementor sites. The Store API checkout assumes its cart session. A shortcode cart page that never hit /cart/add-item leaves checkout empty or missing line items. I standardise both pages on blocks or wire the headless front entirely through Store API, as in WooCommerce blocks vs shortcodes in 2026.

Shipping plugins that compute rates only on classic checkout events may return stale packages when the address block debounces. The cart shows an old flat rate until the shopper blurs a field hard enough to trigger update-customer. I fix the plugin or add a Store API extension callback, not disable debouncing globally.

Security tools that block REST wholesale return 403 on /wc/store/v1/checkout. Merchants blame the gateway. The fix is allowlist the namespace, not swap payment providers.

Disabling nonce checks with woocommerce_store_api_disable_nonce_check on staging and forgetting to remove it is a critical finding on penetration tests. WooCommerce documents that filter for development only.

Product photography on a table for a WooCommerce PDP

Headless teams sometimes store Cart Tokens in localStorage without rotation logic and wonder why carts merge on shared devices. Tokens identify sessions; treat them like session identifiers, not public cache keys.

How I measure WooCommerce Store API health

I measure completed orders, payment failure rate, and cart error codes together. Gateway dashboards and WooCommerce orders should match GA4 purchase events when tags are healthy. If orders succeed and analytics drop, measurement broke, not Store API.

For API-specific signals I log counts of 403, 409, and 500 on /wc/store/v1/cart and /wc/store/v1/checkout in the reverse proxy or application monitoring. A climb in 409 after merchandising changes usually means coupons or shipping rules changed mid-checkout, which is fixable UX copy and refreshed totals, not infrastructure firefighting.

Latency percentiles on update-customer and checkout POST correlate with checkout INP in CrUX when the rest of the page is lean. I compare before and after removing a plugin that hooked every cart recalculation.

I sample ten live orders per day for line items, fees, shipping method, tax, and custom meta. Warehouse tickets beat synthetic monitoring for catching extension gaps.

I do not invent conversion lift from understanding Store API. It is plumbing. The business outcome is fewer abandoned carts because totals and payment methods stay truthful.

Related work on this site

WooCommerce Store API debugging shows up on every catalogue where photography sells the product but JSON sells the order. The Skanvi furniture storefront pairs editorial room sets with a cart that has to survive mobile networks. Janet and Janet is campaign footwear imagery where checkout cannot stall on nonce errors during a drop. Stitching Stories is a maker catalogue with variable products and tight shipping rules, the shape of store where variation add-to-cart and shipping rate selection must match Store API responses. Block themes or classic, the API layer is what keeps those orders consistent.

FAQ

Is the WooCommerce Store API the same as the WooCommerce REST API?

The WooCommerce Store API is not the same as the authenticated WooCommerce REST API. Store API is public, customer-scoped, and built for cart, checkout, and catalog reads in the storefront. The REST API with consumer keys is for integrations that manage products, orders, and settings server to server. Use Store API for shoppers and keys for back-office jobs.

Do Cart and Checkout blocks require the WooCommerce Store API?

Cart and Checkout blocks require the WooCommerce Store API for cart mutations, checkout field persistence, and order placement. Classic shortcode checkout can still run without Store API writes, but block checkout cannot function if /wc/store/v1/ routes are blocked or cached incorrectly.

Mobile checkout on a phone after WooCommerce Store API changes

When should I use a Cart Token instead of a nonce with the WooCommerce Store API?

Use a Cart Token when a decoupled front end or mobile wrapper cannot rely on WordPress cookie nonces rotating in the browser, after you obtain the token from a successful GET /cart response header. Browser block checkout typically uses nonces automatically. Headless setups often combine cookies and Cart Token headers; follow WooCommerce cart token docs and never disable nonce checks in production to avoid implementing rotation.

What does a 409 error from WooCommerce Store API checkout mean?

A 409 from WooCommerce Store API checkout often means the cart changed since the shopper last saw totals, such as a coupon expiring, shipping updating, or expected_total no longer matching the server calculation. The response may include the refreshed cart so the block can update. Teach support to ask the shopper to review the order summary and retry rather than treating it as a payment gateway outage.

WooCommerce Store API checkout fields on a laptop in a studio

Keep reading

Contact if you want this kind of work on a live store.