WooCommerce 8.7 Released: Product Collection Block Enhancements, Receipt Rendering Engine and More

WooCommerce 8.7 has been released!

This post will highlight what’s included in this version of WooCommerce.

See our update guide.
Download directly from WordPress.org.

Please note:

Latest Release:

👉 WooCommerce 8.7.0


  • ✅ Backwards compatible
  • Commits: 300+
  • Contributors: 74

Release Schedule:

  • Final Release — March 19, 2024

Known Issue with Gutenberg 17.9.0

The latest Gutenberg release 17.9.0 includes a bug that causes the New Product Editor to crash when the user attempts to edit the product description in the Full Editor mode (see issue). The New Product Editor is behind a feature flag, meaning the New Product Editor is unavailable by default. The issue would have affected you if you had the New Product Editor enabled through Settings >> Advanced >> Features >> New Product Editor.

To allow further use of the New Product Editor, we disabled the Full Editor of the product description in the 8.7 release if Gutenberg 17.9 is installed. The New Product Editor is working as expected otherwise.

As soon as the Gutenberg 18.0 is released, the product description Full Editor will be re-enabled automatically while using the WooCommerce 8.7 release.

If you’ve been using the New Product Editor and have already used the Full Editor mode of the product description field prior, you will be blocked from editing the product description beyond the text starting from the WooCommerce 8.7 release.

If you’d like/need to edit the product description in the Full Editor mode, please downgrade or deactivate Gutenberg.

A fix has been submitted to Gutenberg and approved for the next Gutenberg 18.0 release on March 27th.

Product Collection Block Enhancements

Scroll to Top & Loading Animation: Following your feedback, we’ve introduced a “Scroll to Top” feature for a smoother browsing experience within the Product Collection block.

We also added a new loading animation signals when products are being refreshed, integrating seamlessly with your theme’s primary color.

Receipt Rendering Engine

Built on top of the transient files engine that was introduced in WooCommerce 8.6, the new receipts printing engine allows generating public temporary URLs for the HTML representation of a receipt for an order. These URLs are unauthenticated, so they can be sent to any printing service in order to get a paper copy of the receipt.

The information included in the receipt, as well as its formatting, is the same as the receipts that are already provided by the WooCommerce mobile applications. This includes the credit card icon and last four digits when the order is paid using WooCommerce Payments.

The engine can be accessed via two new REST API endpoints:

  • POST /wp-json/wc/v3/orders/<order id>/receipt will generate a new receipt and return its public URL, or will just return the public URL of a receipt that had been generated previously. An optional expiration_date=yyyy-mm-dd argument or an expiration_days=n argument can be added to the query string to specify when the receipt will expire (the default is one day later than the current date). Also force_new=true can be optionally specified to force the generation of a new receipt, discarding a previously generated one.
  • GET /wp-json/wc/v3/orders/<order id>/receipt is similar to the POST counterpart, but this time if no receipt had been generated previously then a “Not found” error will be returned.

A note on security. Although the generated URLs are public, they don’t contain order ids, but unrelated random hashes instead; therefore it’s not possible to reconstruct the receipt URL by trying to guess the order id. The REST API endpoints on the other hand receive an order id, but these are regular authenticated endpoints that require the “read order” capability.

These REST API endpoints will be used by the WooCommerce mobile apps to offer receipt printing functionality when the server is on WooCommerce 8.7 or newer.

Checkout Additional Fields API

WooCommerce 8.7.0 ships with an experimental version of the Additional Fields API feature that we have been working on for Checkout Block. This feature is developer only and is currently prefixed with an experimental prefix. It gives you the ability to introduce native additional fields in the Checkout block that will be rendered, collected, and shown all over WooCommerce, from the My Account page, Order Admin, to Emails, and Order Confirmation screens. We invite you to experiment with it, test it, and to make sure it fits your use case.

Here are the docs and tutorial about how to use additional checkout fields.

Moroccan Regions Support

We’ve added comprehensive support for Moroccan regions, enabling more accurate shipping, tax calculations, and customer segmentation. This update ensures a localized shopping experience for your Moroccan customers.

The following are screenshots where this update can be observed:

Changes in Order Coupons Line Item Storage

Back in October, we created a GitHub discussion regarding an issue with the storage of metadata concerning coupons applied to orders. The short version is that once a coupon is applied to an order, a coupon_data metadata item is stored for the corresponding discount order line item (needed to apply the coupon again when doing recalculations on the order when the coupon no longer exists) in the wp_woocommerce_order_itemmeta table; but that metadata item is an entire copy of the coupon object itself, which is overkill and is causing issues in sites with heavy coupon usage (the database size is growing up to unacceptable levels).

We’re glad to announce that a fix for this has been implemented and is a part of WooCommerce 8.7 release.

Changes to metadata storage

From now on, when a coupon is applied to an order, the corresponding line item won’t get a coupon_data metadata item. Instead, it will get a coupon_info item whose value is a string representing a JSON array with the following information:

  • Coupon id.
  • Coupon code.
  • Discount type. The default value fixed_cart will be stored as null.
  • Nominal amount of the coupon, it’s a number that represents either a fixed amount or a percent, depending on the coupon type.
  • Whether the coupon grants free shipping or not. This value is stored only if it has a value of true.

For example, a coupon with id 1234 and code 20off granting a 20% discount and free shipping will get a metadata entry with this value:


while for a coupon with the same id and code, 10bucks, granting a fixed discount of 10$/€/… and no free shipping the value will be:


Migrating metadata on existing orders

Coupon metadata for existing orders won’t get automatically migrated to the new format (and meta key name). If additional coupons are added to the order, these will get coupon_info metadata entries, but existing coupon_data for other coupons previously applied to the order won’t be touched.

If the database space taken up by existing coupon_data entries is an issue in your site, you can use the new metadata migration tool available in the WooCommerce tools page (WooCommerce – Status – Tools):

Click the Start converting button and a background process that converts existing coupon_data entries to simplified coupon_info entries will be initiated. Once the process has started, the button text turns into Stop converting and, you guessed it, pressing it will stop the process (you can restart it at any time). 1000 metadata entries are converted in each iteration.

Changes in REST API

The order details REST API endpoint (/wp-json/wc/v3/orders/<order id>) also gets changes, more precisely in the objects returned inside the array keyed as coupon_lines:

  • Since the raw existing metadata for coupon line items is returned inside the meta_data key, this means that you’ll get coupon_info entries (instead of coupon_data entries) for new orders and for old orders that have got their metadata entries migrated. One of the two (but not both) will always exist for any given coupon line item.
  • Three new keys are added to the coupon line item object (outside of meta_data): discount_type (string), nominal_amount (float) and grants_free_shipping (boolean). In this way, you get basic coupon information without having to parse the metadata, be it the old coupon_data or the new coupon_info.

Here’s an example of the information returned for an order having one coupon applied and a coupon_data metadata entry in the corresponding coupon line item:

	"coupon_lines": [
            "id": 100,
            "code": "20off",
            "discount": "80.65",
            "discount_tax": "19.36",
            "meta_data": [
                    "id": 200,
                    "key": "coupon_data",
                    "value": {
                        "id": 300,
                        "code": "20off",
                        "amount": "20",
                        "status": "publish",
                        "discount_type": "percent",
                        "date_created": {
                            "date": "2021-03-29 10:54:30.000000",
                            "timezone_type": 1,
                            "timezone": "+00:00"
                        //...and a lot more!

And this is the same example, but with the line item having being created with (or having been migrated to) a coupon_info entry:

"coupon_lines": [
            "id": 100,
            "code": "20off",
            "discount": "80.65",
            "discount_tax": "19.36",
            "discount_type": "percent",
            "nominal_amount": 20,
            "free_shipping": true
            "meta_data": [
                    "id": 200,
                    "key": "coupon_info",
                    "value": "[300,\"20off\",\"percent\",20,true]",
                    "display_key": "coupon_info",
                    "display_value": "[300,\"20off\",\"percent\",20,true]"

Please notice the difference between the nominal_amount field (this tells the discount amount as defined in the coupon itself, and can be either a fixed monetary value or a percent) and the discount field (this is the actual value discounted from the order, and is always a fixed monetary value).

Also, note (this can be confusing) that three id values are in play here: the id of the order line corresponding to the coupon usage (100 in the example), the id of the metadata entry created for the order line (200), and the id of the coupon itself (300).

Finally, keep in mind that as in the case of coupon_data entries, the referenced coupon could no longer exist (a site administrator might have deleted it after it was applied to orders).

How can I tell if this affects me?

This change affects you if you have custom code that makes direct use of the old coupon_data metadata entries, either by directly retrieving it from the database (wp_woocommerce_order_itemmeta table) or from the order details REST API endpoint. Your code should be changed so that it’s prepared for coupon line items that have a coupon_info entry instead of a coupon_data entry (one of the two will always be available for any given coupon line item).

Database Changes

This release adds a new update to the database to prevent the listing of the default transient files directory, default_transient_files_dir. This change was introduced in #43502.

WooCommerce REST API Changes

Other Updates

For a complete list of the changes included in this release, please see the changelog in the readme for this release.

WordPress 6.5 Compatibility

WooCommerce 8.7 release has been tested against WordPress 6.5 RC2. Various changes have been made to ensure compatibility with the upcoming WordPress release.

Much 💜 to all the contributors

Lastly, heartfelt appreciation goes out to all members of our community who have contributed through issue reports, bug fixes, translations, testing, providing support to other users, or even by spreading the word.

WooCommerce Core




12 responses to “WooCommerce 8.7 Released: Product Collection Block Enhancements, Receipt Rendering Engine and More”

  1. Thank you very much for publishing a well outwritten release post. What a change compared to the previous release posts!

    The post is very functional (gray background text, intro block, screenshots) and it also looks beatuifull!
    Great work, WooCommerce!

    1. Julia Amosova Avatar
      Julia Amosova

      Hi Dave! Thank you for your vote of confidence and the positive feedback. We will be looking at further changes including rethinking the changelog format. It is great to know that what we’ve introduced so far is helpful!

  2. The option to select the default variant is buggy. I mean no matter how i create and enter the variable inside the product editor screen, it show alphanumeric order (like first number, then letter from A to Z). Please provide an option to set the default variable value for each attribute, just like in the older woocommerce post editor (Not BETA Version).

    This is the most important functionality we want (Have control over default attribute value).

    In my situation, i have an following values.

    Attribute: Size
    Values: LH, SH, H, 6, 5

    This is showing in same order as above when you open product editor, but as soon as you click on edit value inside post editor the order change to (5, 6, H, LH, SH) and i have checked the option, select the default, which select the first value (In this case it becomes 5) as default value.

    But i want to have LH as default value. I have created the variable one after one starting from LH, then SH, then H, then 6 and last 5. So term ID will be increasing order.

    Is there any temporary way i can do this, like via a snippet.

    1. Matt Sherman Avatar
      Matt Sherman

      Thanks for reporting this, Rahul!

      A workaround you can do for now is to go to “Products” > “Attributes” and click “Configure terms” for your Size attribute.

      Then, drag the terms to the order you want.

      This ordering will now show on the store front when you view the product… the LH value will now be the default value in the Size dropdown.

      I will create an issue to improve this in the new product editor and will share a link to it here later today.

      1. Matt Sherman Avatar
        Matt Sherman

        I’ve created an issue that can be used to track this:


        If you have any addition details or concerns that you want to make sure we consider, please comment on the issue!

  3. […] WooCommerce 8.7 är släppt, med diverse förändringar. Det finns ett känt problem med Gutenberg 17.9 vilket man är medveten […]

  4. Nice post! 🙌
    Would it be possible for you to include a link to posts like this in future versions of the changelogs? At update-time is when people really need this information so it would make sense to link to important information like this just before all the changelog entries.
    Thanks for considering this!

    1. brentmackinnon Avatar

      Thanks Ben! I’m glad you found it helpful. We’ll always make sure a post like this is available before an update is released. When in doubt, check out https://developer.woocommerce.com/changelog/ for the latest updates. In the mean time, I’ll see what we can do about the changelog template, thanks for the idea!

  5. Thanks Brent for considering adding a link to the changelog template! The URL is great when you know about it but I don’t think everybody does. I just learned about it now and I always try to keep updated on things like this but every plugin has it’s way of doing things. It’s not totally uncommon to include a link like that.

  6. […] Full release notes on developer.woo.com. […]

  7. I love everything about WooCommerce’s technology, the platform and all the new features the talented team is working on!

    PLEASE… somehow… fit a new UI into the roadmap that beats Shopify!

    The non-techie clients I work with care about this more than all these awesome features.

    1. Jacklyn Biggin Avatar
      Jacklyn Biggin

      Hey John! I’d love to learn more about your thoughts on WooCommerce’s UI. Gonna send you an email 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *