Custom or Sequential Order Numbers in WooCommerce

The first thing we need to understand when we talk about WooCommerce order numbers is that order numbers and order IDs are not the same but by default WooCommerce uses order IDs as order numbers 🙃

Order numbers in WooCommerce admin:

Order numbers in WooCommerce admin

Order IDs in the database:

Order IDs in WooCommerce database

So the ID is just a column in the database which we probably shouldn’t touch, but we can do whatever we want with order numbers using woocommerce_order_number filter hook. And yes, if see any plugin out there which allows to change WooCommerce order numbers in one or another way, most likely the plugin is just using the mentioned hook.

Custom Order Numbers

In this part of the tutorial we’re going to take a look at different examples of custom order number patters you can use in your WooCommerce store.

Example 1. Include custom prefixes into order numbers

If you want to add a prefix or a suffix to your WooCommerce order numbers, you can easily do it with this small piece of code:

add_filter( 'woocommerce_order_number', 'rudr_order_number_prefix' );

function rudr_order_number_prefix( $order_id ) {

	return 'rudr-' . $order_id;

}

The result:

Custom order number prefix in WooCommerce

Example 2. Include order dates into order numbers

Now when we know how to change WooCommerce order numbers with the woocommerce_order_number filter hook, let’s try something more interesting, for example we can add a date in a format {number}-{Year}. It is also not that difficult to do since we have an order object available as a second paremeter in the hook function. Let’s try it out.

add_filter( 'woocommerce_order_number', 'rudr_add_date_to_order_number', 25, 2 );

function rudr_add_date_to_order_number( $order_id, $order ) {
	// we need to get a WC_DateTime object from here
	$order_date = $order->get_date_created();
	// format the date object with a date() method and add it to order numbers
	return $order_id . '-' . $order_date->date( 'Y' );

}

And the result in WooCommerce admin:

how to add order dates in order numbers in WooCommerce

Example 3. Include sub-site IDs for orders within a WordPress Multisite

First of all it is quite easy to add a current store ID to order numbers when you’re using your WooCommerce store as a part of a WordPress multisite network.

add_filter( 'woocommerce_order_number', function( $order_id ) {
	return $order_id . '-' . get_current_blog_id();
} );

So kind of boring, right? But it becomes more interesting when you’re syncing orders from different WooCommerce stores of all your multisite network to a single “main” store!

add_filter( 'woocommerce_order_number', function( $order_id, $order ) {
	// we get a source order ID and store ID from the order meta
	$source_order_id = $order->get_meta( '_mos_source_site_id' );
	$source_store_id = $order->get_meta( '_mos_source_order_id' );
	
	return $source_order_id . '-' . $source_store_id;

}, 25, 2 );

Here, as you can see, a source order ID and a store ID where this order was initially created are stored in the order meta. In this example I am also using meta keys my order sync plugin is using, so in case you have my plugin installed, you can use this code snippet without changes.

Result is going to be like this:

Add sub-store IDs to WooCommerce multisite order numbers

But of course it is not really necessary to code anything because you can also configure it easily in plugin settings:

how to configure custom order number format for synced orders

Sequential Order Numbers

In case you’re already read the first part of the tutorial, you might have already guessed that sequential order numbers are no more no less but just another custom field value.

You may ask – “Wait, but HPOS orders have their own database tables, aren’t their numbers sequential anyway?”. Haha, it could be in a dream world, but you forgot about backward compatibility, my friend, so even HPOS orders are using wp_posts database table, they put some kind of placeholders there and are going to use placholder IDs as order IDs.

So the whole idea of sequential order numbers comes into two parts. In the first part we need to create a custom field when we create an order, something like this:

// generate a sequential order number
$wpdb->query( 
	$wpdb->prepare(
		"
		INSERT INTO {$wpdb->prefix}wc_orders_meta (order_id, meta_key, meta_value)
		SELECT %d, '_order_number', IF( MAX( CAST( meta_value as UNSIGNED ) ) IS NULL, 1, MAX( CAST( meta_value as UNSIGNED ) ) + 1 )
			FROM {$wpdb->prefix}wc_orders_meta
			WHERE meta_key='_order_number'
		", 
		$order_id 
	)
);

In this code example we get a “maximum + 1” value of the _order_number custom field and save it as a value for a new order.

The second part – we are using a custom field value as an order number:

add_filter( 'woocommerce_order_number', function( $order_id, $order ) {
	
	$order_number_sequential = $order->get_meta( '_order_number' );
	
	return $order_number_sequential ? $order_number_sequential : $order_id;

}, 25, 2 );

As simple as that! If you have any questions, please leave them in the comments.

Misha Rudrastyh

Misha Rudrastyh

Hey guys and welcome to my website. For more than 10 years I've been doing my best to share with you some superb WordPress guides and tips for free.

Need some developer help? Contact me

Follow me on X