Workflow Tip: Make Processing Orders Editable

The line items in WooCommerce orders are only editable when the order is in a “Pending” or “On Hold” status. In general this makes sense. If an order is processing, it means the payment has already been accepted and any line item changes would likely require a refund (using the refund functionality) or a new payment (likely a separate order).

However, some business may have products that are frequently swapped or changed while an order is in processing, and it doesn’t make sense to have to switch the status to update the order. In those cases, you can use the wc_order_is_editable filter.

function devpress_processing_orders_editable( $is_editable, $order ) {
    if ( $order->get_status() === 'processing' ) {
        $is_editable = true;

    return $is_editable;
add_filter( 'wc_order_is_editable', 'devpress_processing_orders_editable', 10, 2 );

How to Dequeue Scripts and Styles in WordPress for Improved Page Speed

Many WordPress plugins load scripts and styles on every page of a website even though they may just be needed on a few specific pages. For example, WooCommerce loads at least 3 scripts and 4 styles on every page, even if ecommerce functionality (like a cart or products) aren’t shown on those pages.

I recently went on a performance rampage at Universal Yums and removed ~300kb of enqueued assets that were not needed on our home page- which shows there can be quite a bit of fat to trim.

Continue reading

WooCommerce Performance: Indexing the post_modified_gmt column

WooCommerce 5.8 added support for `modified_before` and `modified_after` params when querying to the REST API for products, orders and coupons in the in the REST API endpoints. Here’s the PR that was merged.

This is great as lots of external services use the REST API to fetch data, and this allows them to just fetch data that has changed since the last sync.

However, if you have a really large posts table (~1 million records and up), this type of query may be slower than you’d like as `post_modified` and `post_modified_gmt` are not indexed columns in the database.

Continue reading

WooCommerce Performance: Using post_author to store order customer IDs

WooCommerce stores order records in the `posts` table as a `shop_order` post type. The majority of data associated with the order, such as the order_total or billing and shipping information is stored in the `postmeta` table.

This works fine in most cases, but once a WooCommerce shop scales past ~1 million orders, queries of postmeta can start to run long. If WordPress needs to get a specific customer’s orders (such as in the customer account dashboard), it requires a querying against `_customer_user` key in the postmeta table.

Continue reading

WP CLI Scripts and WooCommerce

If you manage a WooCommerce store, you’ll like need to bulk update or modify a large number of orders, subscriptions, products or customer records at some point. Writing a WP CLI script can be a quick and easy way to do this.

In this video I show how to export products into a CSV using WP CLI and the command wp eval-file, but the general concepts can be used to loop over any resource you may want to export, modify or delete.

Continue reading

Managing Fraud Orders in WooCommerce

One morning I woke up to find 20,000 new fraudulent orders on a WooCommerce site I manage. The vast majority of them were in failed status, but a few had successfully completed. We quickly determined this was a card testing attack, where a fraudster was using an automated system to iterate through a huge amount of stolen credit card numbers to check out on our site and determine which ones were still valid.

The biggest concern with this type of attack is that your credit card processor may stop processing payments from your site altogether due to fraud concerns, which means the business is dead until you can find a new payment processor.

As soon as we noticed the fraud, we alerted our payment processor and let them know we were taking steps to stop the attack and refund the fraudulent orders- which I think was helpful for keeping our account in good status.

Continue reading

How to Avoid Excess Meta with WooCommerce Subscriptions

Orders in WooCommerce create a lot data in the postmeta table. There’s the standard WooCommerce fields (like _order_key, _cart_hash, _billing_first_name, etc.), but payment gateway plugins, marketing integrations, and other WooCommerce plugins also generate their own metadata. It’s not unusual to see more than 60 rows of metadata for each order.

I recommend the Post Meta Inspector to easily view all the metadata on any order or post. You may be surprised how much there is!

If you run subscriptions on your site and generate a lot of renewals, WooCommerce Subscriptions may be creating a lot of unneeded metadata due to how subscriptions and renewal orders are generated. This can cause your database to grow really quickly.

Continue reading

Update the Modified Date in a WooCommerce Order

If you run a script to update order properties in WooCommerce, you may want to update the “post_modified” date along with the other updates. Many third-party integrations rely on the post_modified date to sync any order changes or updates.

Here’s how you can easily update the modified date (assuming you have the order object):

$order->set_date_modified( time() );

Here’s a full example which fetches the order, updates the date, and saves the order.

$order = wc_get_order( 123 );
$order->set_date_modified( time() );