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.
- Open WooCommerce → Orders.
- Filter by status with the tabs at the top (such as Processing) and tick the orders you want to change.
- 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.
- Click the order number in the order list to open the edit screen.
- In the order actions box on the right, open "Choose an action..." and select the email to send (see the table below).
- 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 (withoutwc-), 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-shipmentas 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 usewc_get_orders()and theWC_Ordermethods 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
- How to set up WooCommerce HPOS (High-Performance Order Storage)
- What to do when a WooCommerce order status won't change
- What to do when WooCommerce emails aren't delivered
Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)