Skip to main content
Unwan’s Checkout Blocks integration is built entirely on WooCommerce’s own official extension points — the Blocks integration registry and the Store API — rather than injecting markup into the page after the fact.

Forced inner blocks

Unwan registers two blocks: Both are registered as forced inner blocks (inserter: false, locked against removal or moving) of WooCommerce’s own address blocks, so they render automatically, in the right place, on any checkout page built from Checkout Blocks — store owners don’t need to manually add anything in the block editor, and can’t accidentally delete the selector while editing the page.

Store API extension data

Unwan registers a writable extension namespace, unwan, on the Checkout endpoint via woocommerce_store_api_register_endpoint_data(), with two fields:
Each holds a saved address ID or "new". This is the same Store API mechanism any other Blocks-aware extension uses to add data to the checkout request — Unwan isn’t reading or writing anything outside of WooCommerce’s supported extension surface.

Keeping order-specific choices from leaking into account defaults

This is the trickiest part of the integration, and worth understanding if you’re debugging address behavior: WooCommerce’s Store API updates the customer’s billing/shipping profile fields as a normal side effect of processing checkout, even when a shopper only meant to use an address for this order. Left alone, that would silently overwrite the account default — exactly what Checkout Overview promises won’t happen. Unwan works around this without fighting WooCommerce’s own checkout flow:
1

Capture, before the overwrite

On every signed-in checkout request (woocommerce_store_api_checkout_update_customer_from_request), Unwan takes a copy of both stored profile defaults, whatever the request contains. WooCommerce also rewrites the shipping default with the billing address for carts that need no shipping, and express payment buttons write it without Unwan’s picker involved, so both are always captured.
2

Let WooCommerce finish

WooCommerce is allowed to write the submitted address to its normal place — it has to, so the draft order can copy the correct address for this order before anything is restored.
3

Restore the account default afterward

Once the full Store API request has completed — including WooCommerce’s own final customer sync — Unwan writes back only the values that changed, via a rest_request_after_callbacks filter, with a shutdown-time fallback in case the primary hook doesn’t fire (payment failures, validation errors, etc.). If nothing changed, nothing is saved: saving the customer would make WooCommerce discard its session copy and price shipping and tax for the default address on the next request.
4

Save the new address afterward, if applicable

If the shopper explicitly chose “Enter a new address,” the finalized address is read back off the processed order (not the raw request) and added to the address book only once it’s known to be complete and valid.
The net effect: the order itself always has the correct, submitted address, and the account’s stored default is untouched unless New address defaults → Make the new address the matching default is explicitly enabled. In that mode the old default is restored first and the new address then takes its place, so the old one stays in the address book. For local pickup and other orders with no shipping address, WooCommerce fills the shipping address with the billing one. Unwan never saves that copy as a new shipping address.

Collapsing rows without hiding what’s needed

When a saved address is selected, Unwan collapses each standard address row individually, never the whole form, so fields other plugins place inside it stay visible. The list of collapsed rows lives on Unwan’s own picker element (data-unwan-collapse) and the stylesheet hides the matching rows with :has(). WooCommerce re-renders its own form wrapper (for example while an order is processing), so state kept there would be wiped and every field would reappear after a failed payment. A row stays visible when WooCommerce’s validation store reports an error for it — a required field the saved address lacks, or a value that fails the store’s rules — and once shown, it stays shown until the customer picks another address. Browsers without :has() support simply show every field.

Compatibility

Unwan declares compatibility with both custom_order_tables (HPOS) and cart_checkout_blocks via FeaturesUtil::declare_compatibility() before WooCommerce initializes its feature system, and registers its block scripts through the Checkout integration registry rather than assuming WooCommerce Blocks has already finished bootstrapping — it checks did_action( 'woocommerce_blocks_loaded' ) and registers immediately if Blocks already loaded, or hooks the action if not.
Last modified on October 5, 2026