2026年11月12日

2026年11月12日

WooCommerce Order Management: Statuses, Bulk Changes, Email Resend, CSV Export

This article is a localized edition of the Japanese original. Read the Japanese original

In WooCommerce you list and edit orders under WooCommerce → Orders. Once orders start piling up, the least effort is to use the built-in bulk actions and email resend features first, and fill the remaining gaps with WP-CLI or code.

The steps and code in this article were tested in November 2026 on WooCommerce 11.2.2 (WordPress 7.1, PHP 8.3).

What the order statuses mean

The WooCommerce documentation (Order Statuses) lists these eight default statuses.

Status Meaning
Pending payment The order was received, but no payment has been made yet
Processing Payment received and stock reduced; the order is waiting to be shipped
On hold Awaiting payment confirmation; used by bank transfer (BACS) and similar methods
Completed Shipped or otherwise fulfilled; nothing left to do
Cancelled Cancelled by an admin or the customer; stock is returned if inventory management is on
Refunded The full amount was refunded
Failed The payment failed or was declined
Draft A temporary record created by the block-based checkout before the order is placed

Draft orders are temporary records created before checkout is completed, and WooCommerce deletes inactive ones automatically every day. You don't need to handle them.

The usual flow is Processing → (ship) → Completed. Changing an order to Completed sends the customer the completed-order email (if it is enabled under WooCommerce → Settings → Emails).

Change orders in bulk from the order list

If you only need to change the status of several orders, no code is required.

  1. Open WooCommerce → Orders.
  2. Filter by status with the tabs at the top (such as Processing) and tick the orders you want to change.
  3. Choose an action such as "Change status to completed" from the bulk actions menu and click "Apply".

The built-in bulk actions change orders to processing, on-hold, completed or cancelled, and move them to the trash.

Resend order emails

When a customer says they never got an email, you can send it again from the order edit screen.

  1. Click the order number in the order list to open the edit screen.
  2. In the order actions box on the right, open "Choose an action..." and select the email to send (see the table below).
  3. Click "Update".
Option Email sent
Send order details to customer Sends the order details to the customer
Resend new order notification Sends the admin new-order email again

If the email still doesn't arrive after resending, the cause is usually the server's mail delivery rather than WooCommerce, so check your SMTP settings.

List and update orders with WP-CLI

If you can use WP-CLI over SSH, the wp wc shop_order command handles orders. The command name is shop_order; there is no wp wc order command.

The WooCommerce CLI uses the REST API internally, so pass a user with the right permissions (an administrator's username or ID) in --user. Without it you get the error Sorry, you cannot list resources.

# Show processing orders as a table
wp wc shop_order list --status=processing --fields=id,status,total --user=admin

# Count processing orders
wp wc shop_order list --status=processing --format=count --user=admin

# Mark order 123 as completed
wp wc shop_order update 123 --status=completed --user=admin

To complete all processing orders at once, get the list of IDs and update them one by one. A completed-order email is sent for each order, so check the count before you run it.

for id in $(wp wc shop_order list --status=processing --format=ids --user=admin); do
  wp wc shop_order update "$id" --status=completed --user=admin
done

Run wp help wc shop_order list to see the other available options.

Add a custom “Awaiting shipment” status

If you want a step such as "Awaiting shipment" between Processing and Completed, add the status with code. The code below registers the status, adds it to the status list, and adds it to the bulk actions on the order list.

Save it as wp-content/mu-plugins/wc-awaiting-shipment.php and it loads without being activated as a plugin (create the mu-plugins folder if it doesn't exist). If you put it in your theme's functions.php, the status disappears when you switch themes, so this location is recommended.

<?php
/**
 * Plugin Name: Awaiting shipment status
 */

// 1. Register the status (needed when orders are stored in the legacy posts table)
add_filter( 'woocommerce_register_shop_order_post_statuses', function ( $statuses ) {
	$statuses['wc-awaiting-shipment'] = array(
		'label'                     => 'Awaiting shipment',
		'public'                    => false,
		'exclude_from_search'       => false,
		'show_in_admin_all_list'    => true,
		'show_in_admin_status_list' => true,
		/* translators: %s: number of orders */
		'label_count'               => _n_noop( 'Awaiting shipment <span class="count">(%s)</span>', 'Awaiting shipment <span class="count">(%s)</span>' ),
	);
	return $statuses;
} );

// 2. Add it to the order status list (right after Processing)
add_filter( 'wc_order_statuses', function ( $statuses ) {
	$new = array();
	foreach ( $statuses as $key => $label ) {
		$new[ $key ] = $label;
		if ( 'wc-processing' === $key ) {
			$new['wc-awaiting-shipment'] = 'Awaiting shipment';
		}
	}
	return $new;
} );

// 3. Add "Change status to awaiting shipment" to the order list bulk actions (HPOS and legacy screens)
foreach ( array( 'bulk_actions-woocommerce_page_wc-orders', 'bulk_actions-edit-shop_order' ) as $hook ) {
	add_filter( $hook, function ( $actions ) {
		$actions['mark_awaiting-shipment'] = 'Change status to awaiting shipment';
		return $actions;
	} );
}

Key points:

  • Start the status key with wc- and keep the whole key within 20 characters (the post status column holds 20 characters).
  • If the bulk action key is mark_ plus the status name (without wc-), WooCommerce's built-in handler changes the status for you. No handler code is needed.
  • WP-CLI can list and update these orders with --status=awaiting-shipment as well.

Run code when the status changes

When the status changes, the action woocommerce_order_status_{status} fires (without the wc- prefix). It receives the order ID and the order object. The example below leaves an internal note on orders that move to Awaiting shipment. Put notifications to a warehouse system and similar tasks inside this callback.

<?php
add_action( 'woocommerce_order_status_awaiting-shipment', function ( $order_id, $order ) {
	$order->add_order_note( 'Now awaiting shipment. Check the shipping instructions.' );
}, 10, 2 );

If you send data to an external API, check the return value of wp_remote_post() with is_wp_error() and write a note on the order when it fails, so you notice anything that was missed.

Export orders to CSV

Export from the admin

Go to Analytics → Orders, set the date range and status, and click "Download" at the top right of the table to get a CSV. For large exports, the file may be emailed to you once it is ready.

Export with WP-CLI

If you want to choose the columns yourself, create the following PHP file and run it with wp eval-file. Because it uses wc_get_orders(), it works regardless of how orders are stored (HPOS or the legacy posts table).

<?php
// Usage: wp eval-file export-orders.php > orders.csv
// Output completed orders created on or after January 1, 2026 as CSV
$orders = wc_get_orders(
	array(
		'status'       => array( 'completed' ),
		'date_created' => '>=2026-01-01',
		'limit'        => -1,
		'orderby'      => 'date',
		'order'        => 'ASC',
	)
);

$out = fopen( 'php://output', 'w' );
fputcsv( $out, array( 'order_id', 'date', 'name', 'email', 'total' ) );
foreach ( $orders as $order ) {
	fputcsv(
		$out,
		array(
			$order->get_id(),
			$order->get_date_created() ? $order->get_date_created()->date( 'Y-m-d H:i' ) : '',
			$order->get_billing_last_name() . ' ' . $order->get_billing_first_name(),
			$order->get_billing_email(),
			$order->get_total(),
		)
	);
}
fclose( $out );
wp eval-file export-orders.php > orders.csv

Set the date range in date_created as '>=2026-01-01' or '2026-01-01...2026-03-31'. With fputcsv(), the columns stay aligned even when a name contains a comma. If the text looks garbled in Excel, import the file with the data import feature and choose UTF-8 as the encoding.

With tens of thousands of orders, 'limit' => -1 can run out of memory. Split the run with 'limit' => 500 and 'page' => 1, 2, 3….

Things to watch

  • Where order data is stored. For new stores on WooCommerce 8.2 and later, High-Performance Order Storage (HPOS) is enabled by default and orders are saved in dedicated tables such as wp_wc_orders. Check which one you use under WooCommerce → Settings → Advanced → Features, in "Order data storage". Raw SQL against the database can break depending on the storage mode, so use wc_get_orders() and the WC_Order methods instead.
  • Changing a status back by hand. This can affect stock and sales reports. For example, setting an order to Cancelled returns its stock. Check the order notes for the history before you change it back.
  • Removing a custom status. If you remove the code while orders still have that status, they disappear from the order list. Move them to another status first, then remove the code.

Related articles

Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)

お気軽にご相談ください

お見積りへ お問い合わせへ
▲