WooCommerce 11.0 Extension Developer Compatibility Checklist

WooCommerce 11.0 is scheduled for release on July 28, 2026. As of July 25, 11.0.0-beta.2 is the current public pre-release, with the first release candidate scheduled for July 27. Despite the major-looking version number, WooCommerce does not use the usual semantic-versioning distinction between major and minor releases. An extension should not need a complete rewrite merely because the version changed from 10.x to 11.0. (GitHub)

That does not make this a release you can safely ignore.

WooCommerce 11.0 removes the experimental block-based Product Editor, changes the queried object returned on the Shop page, restores inventory when orders enter the failed status, makes product shipping classes private, introduces stricter Store API request limits, and enables product object caching for new installations. Each change is manageable, but extensions that depend on the affected behavior can fail in subtle ways. (The WooCommerce Developer Blog)

Use the following checklist before adding “Tested up to WooCommerce 11.0” to your extension.

Release status — July 25, 2026: WooCommerce 11.0.0-beta.2 is available for testing. RC1 is scheduled for July 27, followed by the stable release on July 28. The beta package declares WordPress 6.9 and PHP 7.4 as its minimum requirements and is tested through WordPress 7.0. (GitHub)


1. Build a reproducible compatibility matrix

Do not begin by changing code. Begin by creating environments that can reproduce the problems your customers are likely to encounter.

At a minimum, test your extension against:

AreaRecommended coverage
WooCommerceLatest 10.9.x release and WooCommerce 11.0
WordPressWordPress 6.9 and 7.0
PHPYour extension’s declared minimum and a modern supported version
Order storageHPOS enabled, with compatibility mode disabled
Cart and checkoutCart and Checkout blocks, plus shortcodes when supported
Product cachingProduct object caching disabled and enabled
ThemesAt least one classic theme and one block theme
ProductsSimple, variable, virtual, downloadable, and backordered products
Order creationCheckout, REST API, admin-created orders, and subscription or renewal flows where relevant
NetworkingSingle site and multisite when your extension claims multisite support

The WooCommerce 11.0 beta currently requires WordPress 6.9 or newer and PHP 7.4 or newer. You do not necessarily have to raise your extension’s own minimum versions to those values, but you must test the combinations you advertise.

A useful rule is to keep your last supported WooCommerce 10.9 environment alongside the 11.0 environment. That makes it easier to determine whether a failure is a regression introduced by your changes or a genuine compatibility difference.

Pass this step when: every failed test can be reproduced from a documented combination of WordPress, WooCommerce, PHP, storage mode, and checkout type.


2. Remove dependencies on the experimental Product Editor

The highest-priority codebase audit concerns the block-based Product Editor beta.

WooCommerce 11.0 removes the experimental Product Editor from core. The classic product editor remains available, and existing product data is not migrated or deleted. What disappears are the editor feature flag, routes, menu entries, JavaScript packages, tests, blocks, slots, fills, and extension points built specifically for that beta experience. (The WooCommerce Developer Blog)

Search your extension for:

@woocommerce/product-editor
@woocommerce/create-product-editor-block
product-block-editor-v1
__experimental
Product Editor blocks
Product Editor slots and fills
Editor-specific routes
Editor-specific data stores

WooCommerce 11.0 beta 2 added compatibility shims for some removed Product Editor registries and PHP block-template APIs. These shims may prevent an immediate fatal error in certain extensions, but they should not be treated as a supported long-term integration layer.

If your extension added product fields through the experimental editor, move that functionality to one of the currently supported surfaces:

  • Classic product data panels and hooks
  • Product meta registered through standard WordPress APIs
  • A dedicated extension settings screen
  • A supported WooCommerce block integration
  • A separate React interface backed by your own REST API

Do not automatically delete product metadata merely because its editor interface was removed. The stored data may still be required by orders, integrations, imports, exports, or older extension versions.

Pass this step when: the extension can activate, edit products, save product data, and render its front-end functionality without loading any removed Product Editor package or extension point.


3. Fix assumptions about the Shop page queried object

WooCommerce 11.0 changes what WordPress returns from get_queried_object() on the main Shop page.

Previously, extensions could receive the WP_Post_Type object for the product post type. In WooCommerce 11.0, the queried object is the WP_Post representing the configured Shop page. The same change affects get_queried_object_id(), $query->queried_object, and $query->queried_object_id. Conditional functions such as is_shop(), is_archive(), and is_post_type_archive( 'product' ) continue to work as before. (The WooCommerce Developer Blog)

Code that assumes the queried object is always a post type object may now access properties that do not exist or use the wrong ID.

Use explicit type checks:

<?php

if ( is_shop() ) {
    $shop_page = get_queried_object();

    if ( $shop_page instanceof WP_Post ) {
        $shop_page_id    = $shop_page->ID;
        $shop_page_title = get_the_title( $shop_page );
    }
}

When you actually need information about the product post type, request it directly:

<?php

$product_post_type = get_post_type_object( 'product' );

if ( $product_post_type instanceof WP_Post_Type ) {
    $archive_label = $product_post_type->labels->name;
}

Search for uses of:

get_queried_object()
get_queried_object_id()
$query->queried_object
$query->queried_object_id

Pay particular attention to breadcrumb extensions, SEO integrations, archive layouts, product filters, title replacements, schema generators, and Shop-page template conditions.

Pass this step when: your Shop-page logic distinguishes between the configured Shop page and the product post type instead of inferring both from the queried object.


4. Test every failed-order inventory path

WooCommerce 11.0 attaches wc_maybe_increase_stock_levels() to the woocommerce_order_status_failed action.

When an order previously reduced inventory and later enters the failed status, WooCommerce will now restore that inventory. An order that never reduced stock, such as a pending order that failed before payment processing, should not receive an additional stock adjustment. This change does not alter WooCommerce’s separate checkout stock-reservation mechanism. (The WooCommerce Developer Blog)

This is important for extensions that:

  • Introduce custom payment gateways
  • Retry asynchronous payments
  • Change order statuses through webhooks
  • Reserve or reduce inventory themselves
  • Repurpose failed as a non-payment workflow status
  • Maintain inventory in an external ERP or warehouse
  • Create child, renewal, deposit, or split-payment orders

Test at least these transitions:

  1. pendingfailed, when inventory was never reduced
  2. on-holdfailed, after inventory was reduced
  3. processingfailed
  4. failedprocessing, following a successful payment retry
  5. Repeated failed-payment webhooks for the same order
  6. Manual transitions performed from the order administration screen
  7. Failed orders containing variations, backorders, or managed and unmanaged products

For every test, inspect:

  • Product and variation stock quantities
  • The order’s stock-reduced state
  • Order notes
  • External inventory synchronization calls
  • Duplicate gateway webhooks
  • Retry behavior

Extensions that intentionally own failed-order inventory behavior can remove WooCommerce’s callback:

<?php

// Run after WooCommerce has registered its default callback.
remove_action(
    'woocommerce_order_status_failed',
    'wc_maybe_increase_stock_levels'
);

Do not use this as a blanket compatibility fix. Removing the action without replacing its behavior can leave legitimately failed orders with inventory permanently deducted.

Pass this step when: an order can fail, retry, and fail again without either losing inventory permanently or restoring the same inventory twice.


5. Stop treating shipping classes as a public taxonomy

WooCommerce 11.0 registers the product_shipping_class taxonomy with public set to false.

Shipping-class terms, product assignments, and shipping calculations continue to work. What changes is their public visibility: WordPress will no longer treat shipping classes as a publicly queryable front-end taxonomy by default. (The WooCommerce Developer Blog)

Audit extensions that use shipping classes for purposes beyond shipping calculations, particularly code that:

  • Creates public shipping-class archive URLs
  • Adds shipping classes to XML sitemaps
  • Includes them in public taxonomy selectors
  • Uses get_taxonomies( [ 'public' => true ] )
  • Exposes them through GraphQL or search integrations
  • Generates SEO metadata for shipping-class archives
  • Uses shipping classes as customer-facing product categories
  • Assumes is_taxonomy_viewable() returns true

If public shipping classes are an intentional part of your product, WooCommerce provides a filter for restoring that behavior:

<?php

add_filter(
    'register_product_shipping_class_taxonomy_args',
    static function ( array $args ): array {
        $args['public']             = true;
        $args['publicly_queryable'] = true;

        return $args;
    }
);

For most extensions, a dedicated product taxonomy is a better solution for customer-facing grouping. Shipping classes should describe fulfillment and pricing behavior, not act as a substitute for brands, collections, materials, or product types.

Pass this step when: the extension either works with private shipping classes or restores public visibility deliberately and documents why it is required.


6. Test with product object caching enabled

WooCommerce 11.0 enables product object caching by default for newly created stores. Existing stores retain their current setting, which means an extension may appear compatible on an upgraded development site while failing on a fresh installation. (The WooCommerce Developer Blog)

The cache is request-scoped rather than persistent across requests. Repeated calls to wc_get_product() can reuse the cached product data, while returning cloned product instances so callers do not accidentally share the same mutable object. (The WooCommerce Developer Blog)

Extensions using normal WooCommerce and WordPress data APIs should generally work correctly. The biggest risk is code that writes directly to the database and then reads the same product again during the current request.

Audit for:

$wpdb->query()
$wpdb->update()
$wpdb->insert()

Pay special attention to direct writes involving:

_price
_regular_price
_sale_price
_stock
_stock_status
product attributes
variation data
WooCommerce product lookup tables

Prefer supported APIs:

<?php

$product = wc_get_product( $product_id );

if ( $product instanceof WC_Product ) {
    $product->set_regular_price( '29.00' );
    $product->set_price( '29.00' );
    $product->save();
}

For ordinary metadata, use WordPress functions such as update_post_meta(), add_post_meta(), and delete_post_meta() rather than raw SQL. For computed pricing that should not be stored, use the relevant WooCommerce getter filters instead of mutating product rows during a request.

Test these scenarios with caching both enabled and disabled:

  • Dynamic and role-based pricing
  • Currency conversion
  • Product bundles and composite products
  • Bulk imports and synchronization
  • Variation creation and updates
  • Product duplication
  • Stock synchronization
  • Read-after-write operations within one request
  • REST API batch operations
  • Long-running administration requests

After testing, extensions may explicitly declare compatibility with the feature:

<?php

use Automattic\WooCommerce\Utilities\FeaturesUtil;

add_action(
    'before_woocommerce_init',
    static function (): void {
        if ( ! class_exists( FeaturesUtil::class ) ) {
            return;
        }

        FeaturesUtil::declare_compatibility(
            'product_instance_caching',
            __FILE__,
            true
        );
    }
);

Declare compatibility only after testing the extension’s write paths. The declaration should describe verified behavior, not suppress a warning.

Pass this step when: enabling caching does not produce stale prices, stock quantities, variation data, or product metadata during the same request.


7. Keep Store API count requests within the new limit

WooCommerce 11.0 limits the number of entries accepted by the Store API’s /products/collection-data count parameters.

The affected parameters are:

calculate_attribute_counts
calculate_taxonomy_counts

Each parameter now accepts a maximum of 25 requested entries by default. Requests exceeding the limit return an HTTP 400 response. The limit applies to the number of requested attributes or taxonomies, not to the number of terms contained in the response. Duplicate count calculations are also deduplicated. (GitHub)

This primarily affects:

  • Advanced product-filter extensions
  • Faceted search interfaces
  • Headless WooCommerce storefronts
  • Large navigation systems
  • Product discovery applications
  • Storefronts that request every filter count in one API call

Do not immediately raise the limit. First determine whether the interface actually needs all counts at the same time.

Better approaches include:

  • Requesting counts only for visible filters
  • Splitting filters into smaller requests
  • Loading secondary filters on demand
  • Caching stable filter configuration
  • Avoiding duplicate taxonomy requests

WooCommerce exposes the woocommerce_store_api_collection_data_counts_max_items filter for exceptional use cases, but raising the limit increases the amount of work allowed in a single request. Treat it as an architectural decision rather than a quick patch.

Pass this step when: no Store API request sends more than 25 attribute or taxonomy count entries, unless the limit was intentionally changed and performance-tested.


8. Pass stock-reservation durations explicitly

In WooCommerce 11.0, calls to ReserveStock::reserve_stock_for_order() that omit the reservation duration use a default duration of 60 minutes. (The WooCommerce Developer Blog)

Most extensions should not call lower-level stock-reservation methods directly. Those that do should stop depending on an implicit default.

Review reservations created by:

  • Custom checkout flows
  • Buy-now functionality
  • Payment links
  • Deposits and installment extensions
  • Headless storefronts
  • External order-creation services
  • Quote-to-order workflows

Pass the intended duration explicitly so that your extension’s behavior remains understandable when WooCommerce defaults change again.

Also test the interaction between:

  • Reserved stock
  • Reduced stock
  • Failed-order restoration
  • Cancelled orders
  • Abandoned checkouts
  • Delayed payment webhooks

Pass this step when: every custom stock reservation has a deliberate lifetime, expiration behavior, and cleanup path.


9. Review custom phone validation and formatting

WooCommerce 11.0 introduces dedicated phone-number extension points:

woocommerce_validate_phone
woocommerce_format_phone_number
WC_Validation::is_phone_format()

These APIs give extensions a supported way to customize phone validation and formatting instead of replacing broader checkout validation or maintaining disconnected regular expressions. (The WooCommerce Developer Blog)

This is not necessarily a breaking change, but it is a good opportunity to simplify extensions that:

  • Add country-specific phone validation
  • Normalize phone numbers before sending SMS messages
  • Integrate with delivery providers
  • Require E.164-style values
  • Copy phone fields into external CRMs
  • Validate billing and shipping numbers differently

Be careful not to make checkout validation stricter without considering existing customer data, imported orders, administration-created orders, and countries with variable-length phone numbers.

Pass this step when: the same phone value is handled consistently across checkout, My Account, order administration, REST requests, and external integrations.


10. Audit blocks, JavaScript packages, and build tooling

The Product Editor is not the only front-end development area affected by WooCommerce 11.0.

The release also includes changes such as:

  • Removal of the Product Image block’s Resolution attribute in favor of responsive-image behavior
  • Removal of @woocommerce/integrate-plugin
  • Replacement of the WooCommerce ESLint plugin’s dependency-group rule with import/order
  • Deprecation of Automattic\WooCommerce\Blocks\QueryFilters
  • Renaming of the Products beta block to indicate its deprecated status
  • Compatibility shims for selected removed Product Editor APIs (The WooCommerce Developer Blog)

Rebuild your production assets against the dependency versions used by WooCommerce 11.0. Do not limit the test to a previously compiled ZIP file.

Check for:

  • Missing JavaScript package exports
  • Webpack externals that are no longer registered
  • Deprecated block imports
  • ESLint configuration failures
  • Block attributes that no longer exist
  • Front-end scripts depending on experimental globals
  • Styles targeting removed Product Editor selectors
  • PHP code importing classes marked @internal

WooCommerce does not guarantee backward compatibility for internal APIs merely because the classes are technically accessible. Extensions should avoid importing code under internal namespaces or relying on methods explicitly documented as internal. (The WooCommerce Developer Blog)

Pass this step when: a clean dependency install, lint, build, and production bundle completes without removed imports, unresolved externals, or reliance on internal WooCommerce APIs.


11. Re-test checkout registration and background processing

WooCommerce 11.0 adds a warning when additional checkout fields are registered before the woocommerce_init action. Register custom fields at the supported point in the lifecycle rather than at file load time. The release also updates Action Scheduler to 4.0.0 and adds the variation ID as an additional argument to the woocommerce_add_to_cart_quantity filter.

A safe checkout-field registration pattern is:

<?php

add_action(
    'woocommerce_init',
    static function (): void {
        // Register additional checkout fields here.
    }
);

Re-test extensions that:

  • Register additional checkout fields
  • Queue asynchronous imports or exports
  • Schedule subscription or renewal actions
  • Run delayed inventory synchronization
  • Process webhooks in background jobs
  • Use custom Action Scheduler stores or loggers
  • Modify add-to-cart quantities for variations
  • Bundle their own copy of Action Scheduler

Check the scheduled-actions administration screen for:

  • Failed actions
  • Duplicate actions
  • Actions stuck in progress
  • Unexpectedly rescheduled jobs
  • Callback argument-count errors
  • Unserializable payloads
  • Jobs using renamed or removed classes

Pass this step when: checkout registration produces no lifecycle warnings and all scheduled jobs complete once with the expected arguments.


12. Reconfirm HPOS and Cart/Checkout block compatibility

HPOS and the Cart and Checkout blocks are not new in WooCommerce 11.0, but declaring compatibility with a new WooCommerce release should include another complete test of both.

For HPOS, avoid direct assumptions about order storage. Use:

wc_get_order()
wc_get_orders()
WC_Order_Query
$order->get_meta()
$order->update_meta_data()
$order->save()

Do not read or write orders directly through wp_posts and wp_postmeta.

For Cart and Checkout blocks, test:

  • Custom fees
  • Shipping calculations
  • Payment methods
  • Additional checkout fields
  • Validation errors
  • Order metadata
  • Thank-you page behavior
  • Store API error responses
  • Express-payment methods
  • Logged-in and guest checkout
  • Classic shortcode checkout when still supported

Woo Marketplace requirements currently expect listed extensions to support HPOS and the Cart and Checkout blocks where applicable, and to pass applicable QIT checks. (The WooCommerce Developer Blog)

WooCommerce’s newer Settings interface remains experimental and opt-in. Extension developers can test it, but WooCommerce 11.0 does not require every extension to migrate its settings screen to React. Avoid depending on experimental settings APIs as your only production interface. (The WooCommerce Developer Blog)

Pass this step when: order and checkout functionality behaves consistently across HPOS, block checkout, and every legacy mode your extension still claims to support.


A fast static audit

Before manual testing, run a codebase search for the most likely compatibility hotspots.

Using ripgrep:

rg -n \
'@woocommerce/product-editor|@woocommerce/create-product-editor-block|@woocommerce/integrate-plugin|product-block-editor-v1|Automattic\\WooCommerce\\Blocks\\QueryFilters|get_queried_object(_id)?|product_shipping_class|woocommerce_order_status_failed|reserve_stock_for_order|\$wpdb->(query|update|insert)|woocommerce_additional_checkout_fields' \
src includes assets package.json composer.json

Run a separate, manually reviewed search for experimental APIs:

rg -n \
'__experimental|experimental|Slot|Fill|@internal' \
src includes assets package.json composer.json

These searches will produce false positives. Their purpose is to create an audit queue, not to prove that every match is a defect.

Also search your tests. A unit test that mocks the previous Shop-page queried object or previous failed-order stock behavior can hide a production incompatibility by enforcing an outdated assumption.


Automate the release gate with QIT

WooCommerce’s Quality Insights Toolkit can run activation and validation tests using configurable WordPress, WooCommerce, and PHP versions.

For example:

qit run:activation your-extension \
  --woocommerce_version=11.0.0-beta.2 \
  --wordpress_version=7.0 \
  --php_version=8.3

Replace your-extension with your extension slug. When the release candidate or stable build becomes available, rerun the same test using the newer WooCommerce version.

The QIT activation test exercises activation, administration pages, basic product and order creation, cart and checkout behavior, and deactivation while monitoring PHP errors, warnings, and notices. QIT validation tests also inspect plugin headers and selected compatibility declarations. (Quality Insights Toolkit)

Automated checks should be followed by focused integration tests for your extension’s own domain. A shipping extension needs rate, package, zone, and shipping-class coverage. A payment gateway needs webhook, retry, refund, capture, and failure coverage. A pricing extension needs cart, order, tax, coupon, caching, and variation coverage.


Update plugin headers only after testing

A typical WooCommerce plugin header can include:

<?php
/**
 * Plugin Name: Example Extension
 * Requires at least: 6.9
 * Requires PHP: 7.4
 * WC requires at least: 10.9
 * WC tested up to: 11.0
 */

These values are examples, not values every extension should copy.

Your Requires at least, Requires PHP, and WC requires at least values must describe your extension’s actual minimum requirements. Do not raise WC requires at least to 11.0 unless the extension genuinely depends on an API introduced in WooCommerce 11.0.

Set WC tested up to: 11.0 only after the test matrix has passed. WooCommerce recognizes these headers as part of extension compatibility metadata. (The WooCommerce Developer Blog)

Similarly, feature declarations should reflect verified behavior:

<?php

use Automattic\WooCommerce\Utilities\FeaturesUtil;

add_action(
    'before_woocommerce_init',
    static function (): void {
        if ( ! class_exists( FeaturesUtil::class ) ) {
            return;
        }

        FeaturesUtil::declare_compatibility(
            'custom_order_tables',
            __FILE__,
            true
        );

        FeaturesUtil::declare_compatibility(
            'cart_checkout_blocks',
            __FILE__,
            true
        );

        FeaturesUtil::declare_compatibility(
            'product_instance_caching',
            __FILE__,
            true
        );
    }
);

Do not declare a feature compatible merely to remove an administration warning. Compatibility declarations are promises to store owners and should be backed by repeatable tests. (The WooCommerce Developer Blog)


The final WooCommerce 11.0 release gate

Before publishing your update, confirm all of the following:

  • The extension installs, activates, upgrades, deactivates, and uninstalls without PHP errors or warnings.
  • No production code depends on the removed Product Editor beta.
  • Shop-page code safely handles a WP_Post queried object.
  • Failed-order transitions neither double-restore nor permanently lose inventory.
  • Shipping classes are not unintentionally exposed as public taxonomies.
  • Product object caching does not produce stale reads after writes.
  • Store API count requests remain within the 25-item default limit.
  • Custom stock reservations use deliberate durations.
  • Checkout fields are registered at the correct point in the WooCommerce lifecycle.
  • Background jobs complete correctly with the bundled Action Scheduler version.
  • HPOS works without direct order-table assumptions.
  • Cart and Checkout blocks work for every supported payment, shipping, fee, and field integration.
  • Classic checkout still works when your extension claims to support it.
  • REST API, webhooks, emails, refunds, and administration-created orders have been tested.
  • A clean JavaScript dependency installation, lint, and production build succeeds.
  • QIT activation and validation tests pass.
  • WC tested up to and feature declarations were updated only after testing.
  • The changelog identifies WooCommerce 11.0 compatibility changes.
  • The release has a documented rollback path.

Final thoughts

WooCommerce 11.0 is not a release that should force most extension developers into a large rewrite. Its compatibility risks are concentrated in a relatively small number of assumptions:

  • That the experimental Product Editor would remain available
  • That the Shop queried object would always represent the product post type
  • That entering the failed status would leave previously reduced inventory untouched
  • That shipping classes were publicly viewable taxonomies
  • That direct database writes would always be visible to later product reads
  • That a Store API request could calculate an unlimited number of filter counts

Those assumptions may have remained invisible for years because they worked in existing test environments.

The most reliable compatibility process is therefore not to scan the changelog for obvious fatal errors. It is to create a fresh WooCommerce 11.0 installation, enable modern storage and caching features, run complete order and inventory lifecycles, and validate every integration boundary your extension owns.

A compatibility declaration should be the final result of that process—not the first step.

Official references

Leave a Comment