How to add custom action button in WooCommerce admin order list

Let’s add a new custom quick action button in the WooCoommerce admin order list.

woocommerce admin order list actions buttons
How do we add these buttons?

By default, WooCommerce will only show these action buttons when an order status is “Pending”, “On-hold” or “Processing”.

It’s not very well documented in WooCommerce how to modify this; and the only thing I found was this StackOverflow thread.

Here is a step-by-step example.

Example: Add a “Shipped” order action button

For this example, let’s add an action button that will update the order status to a custom status called “Shipped”. It will only show when the current status is “Processing”.

Step 1: woocommerce_admin_order_actions filter hook

First, we set up our basic function using the filter hook woocommerce_admin_order_actions. It returns a list of available action buttons.

(For some reason, this hook was not searchable in the official WC reference docs. It can be found under the render_wc_actions_column function.)

The filter provides two parameters to our function:

  • $actions is an array of current action buttons;
  • $order is the order object of the current row

Here is our basic setup:

// add custom order action button
add_filter( 'woocommerce_admin_order_actions', 'custom_order_action_buttons', 10, 2 );
function custom_order_action_buttons ( $actions, $order ) {

    // add our custom action button
    //...

    return $actions;
}

Step 2: Add custom action button

Next, we need to add our new action to the provided $actions array.

We only want to add our custom action when the order status is “Processing”.

If you look at the reference code you can see how the “complete” and “processing” button data is added to the array. It’s basically creating an array of data (url, name, action) for each button, then adding it into the $actions array.

We are just going to copy from the reference and modify it for our ‘Shipped’ status. Replace $this->object with $order, and completed / processing with our custom status slug shipped.

// Add custom order action button 
add_filter( 'woocommerce_admin_order_actions', 'custom_order_action_buttons', 10, 2 );
function custom_order_action_buttons ( $actions, $order ) {

    // name of our custom order action
    $custom_order_action = 'shipped'; // use the slug of your custom order status

    // only show if order is "Processing"
    if ( $order->has_status( array( 'processing' ) ) ) { 

            // add our new array into $actions array
            $actions[$custom_order_action] = array( 
                'url'    => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status='.$custom_order_action.'&order_id=' . $order->get_id() ), 'woocommerce-mark-order-status' ), // ajax url 
                'name'   => __( 'Ship', 'woocommerce' ), // name that shows in tooltip
                'action' => $custom_order_action, // for custom CSS class
            );
        }

    return $actions;
}

The url uses the builtin WooCommerce ajax class method mark_order_status() to update the order status. You need to use the slug of your custom order status, or it won’t work.

Step 3: Add an icon with CSS

The final step is simply to add an icon using CSS. We are going to use the builtin WooCommerce icon font. (See a full list of available icons here)

Let’s use this truck icon (e01a) :

You could use an external admin CSS file, or you can do it quick and dirty through a function like this:

// Set custom action button icon with CSS -- add to WordPress admin <head>
add_action( 'admin_head', 'custom_order_action_buttons_css' );

function custom_order_action_buttons_css() {
		
	// action name
    $custom_order_action = "shipped"; 

	// echo custom CSS
    echo '
		<style>
			.wc-action-button-'.$custom_order_action.'::after { 
				font-family: woocommerce !important;  
				content: "\e01a" !important; 
				}
		</style>
		';
}

If you use an external CSS file, you would simply write the entire class name out like .wc-action-button-shipped

Full snippet

That’s it! Here is the full snippet (filter hook + custom icon CSS):

// Add custom order action button 
add_filter( 'woocommerce_admin_order_actions', 'custom_order_action_buttons', 10, 2 );
function custom_order_action_buttons ( $actions, $order ) {
	
	// slug of our custom order status
	$custom_order_action = 'shipped'; 

	// only show if order is "Processing"
	if ( $order->has_status( array( 'processing' ) ) ) { 
			
			// add our new array into $actions array
			$actions[$custom_order_action] = array( 
				'url'    => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status='.$custom_order_action.'&order_id=' . $order->get_id() ), 'woocommerce-mark-order-status' ), // button url link
				'name'   => __( 'Ship', 'woocommerce' ), // name that shows in tooltip
				'action' => $custom_order_action, // for custom CSS class
			);
		}

	return $actions; // dont forget to return $actions array!
}

// Set custom action button icon with CSS
add_action( 'admin_head', 'custom_order_action_buttons_css' );
function custom_order_action_buttons_css() {
		
	// name of action to use in CSS class
    $custom_order_action = "shipped"; 

	// echo custom CSS
    echo '
		<style>
			.wc-action-button-'.$custom_order_action.'::after { 
				font-family: woocommerce !important;  
				content: "\e01a" !important; 
				}
		</style>
		';
}

Final result:

Summary

Nice! We successfully added a custom action button to the WooCommerce admin order list.

You can add more buttons, and modify them to do whatever you want. Just change the 'url' value in your custom action array.

For example, you can make a button do a DuckDuckGo search of the customer’s first name by changing the url value like this:

'url' => ( 'https://duckduckgo.com/?q='.$order->billing_first_name.'' )

I’m sure you can come up with some better ideas.

🙃

Get Weekly WordPress tips

Was this helpful? Every week, I post a useful tip about WordPress development. Subscribe below to get updates by email. (It's free 🙂)

Leave a Comment