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:
- This release includes a database change.
- This release includes a known issue with Gutenberg 17.9.0.
Latest Release:
About:
- ✅ Backwards compatible
- Commits: 300+
- Contributors: 74
Release Schedule:
- Final Release — March 19, 2024
What’s new in 8.7.0?
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 optionalexpiration_date=yyyy-mm-dd
argument or anexpiration_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). Alsoforce_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 thePOST
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 asnull
. - 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:
[1234,"20off","percent",20,true]
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:
[1234,"10bucks",null,10]
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 getcoupon_info
entries (instead ofcoupon_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) andgrants_free_shipping
(boolean). In this way, you get basic coupon information without having to parse the metadata, be it the oldcoupon_data
or the newcoupon_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
- Add the Receipts Rendering Engine
- APIv1 > Orders Controller > Avoid deprecated means of accessing coupon data
- Fix the REST API controllers registration
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.
Leave a Reply