phpwordpresswoocommerceorderssku

WooCommerce custom order number prepending product sku


I am building a WooCommerce web-store with different and I want to get different series of order numbers or invoice numbers based on this thread.

I need a similar solution. The codes I've tried:

1st try

add_filter( 'woocommerce_order_number', 'change_woocommerce_order_number' );

function change_woocommerce_order_number( $order_id ) {
    $order = new WC_Order( $order_id );
    foreach ( $order->get_items() as $item_key => $item )
    $product = $order->get_product_from_item( $item );
    $sku = $product->get_sku();
    $new_order_id = $sku . $order_id;
    return $new_order_id;
}

2nd try:

function change_woocommerce_order_number($order_id) {
    $order = new WC_Order($order_id);
    $items = $order->get_items();
    $first_item = $items[0];
    $product_id = $first_item->get_product_id();
    $product = new WC_Product($product_id);
    $sku = $product->get_sku();

    return $sku.$order_id;
}
add_filter('woocommerce_order_number', 'change_woocommerce_order_number');

Now, whenever I use those code snippets, the checkout page stops working and gives the error "there has been a critical error on this website". I'm a complete novice in regard to custom coding.

Edit:

i found the below code to work as i want and also make the order number increase in a sequence by adding a custom field that acts as a counter but i would have to add this code for each product separately

add_filter( 'woocommerce_order_number', 'custom_wc_order_number_increment_with_meta', 10, 2 );
function custom_wc_order_number_increment_with_meta( $order_id, $order ) {
    $item    = current( $order->get_items() ); // Get the first order item
    $product = $item->get_product(); // Get the WC_Product Object
    $product_id = $product->get_id(); // Get the product ID
    $sku     = $product->get_sku(); // Get the SKU from the product
    
    // Specify the product ID you want to target
    $target_product_id = 1234; // Replace with the actual product ID

    if ( $product_id == $target_product_id && $sku ) {
        // Retrieve the current order number from post meta (custom field)
        $current_order_number = get_post_meta( $product_id, '_custom_order_number', true );
        
        // If no order number is found in the meta, start from 1
        if ( empty( $current_order_number ) ) {
            $current_order_number = 1;
        }

        // Customize the order number by prepending SKU and using the incremented number
        $custom_order_number = $sku . '-' . str_pad($current_order_number, 4, '0', STR_PAD_LEFT); // Example: SKU-0001

        // Increment the number for the next order
        $new_order_number = $current_order_number + 1;

        // Update the incremented number in the product's post meta
        update_post_meta( $product_id, '_custom_order_number', $new_order_number );

        return $custom_order_number;
    }

    return $order_id; // Return default order ID if it's not the target product
}

Solution

  • There are some mistakes in your code attempts and as an order can have multiple products, you need to get the SKU from the first order item (product), to prepend it to the order number.

    Try the following instead:

    add_filter( 'woocommerce_order_number', 'custom_wc_order_number', 10, 2 );
    function custom_wc_order_number( $order_id, $order ) {
        $item    = current( $order->get_items() ); // Get the first order item
        $product = $item->get_product(); // Get the WC_Product Object
        $sku     = $product->get_sku(); // Get the SKU from the product
    
        if ( $sku ) {
            return $sku . $order_id; // Prepend the sku to the order number
        }
        return $order_id;
    }
    

    It should work.