Sort orders by custom order meta – Woocommerce Orders admin page

Here I created a function to get all possible meta_values of a certain meta_key. Then I hooked restrict_manage_posts to add the new select field of meta_values to the filter form. Finally I hooked parse_query to add the new filter to the post query.

// Global to be used to stop filter from running on get_posts() in get_meta_values()
$GLOBALS['run_meta_filter_on_query'] = true;

// function to grab all possible meta values of the chosen meta key in this case '_payment_method'
function get_meta_values( $meta_key,  $post_type="post" ) {

    $GLOBALS['run_meta_filter_on_query'] = false;
    $posts = get_posts(
        array(
            'post_type' => $post_type,
            'meta_key' => $meta_key,
            'posts_per_page' => -1,
        )
    );
    $GLOBALS['run_meta_filter_on_query'] = true;

    $meta_values = array();
    foreach( $posts as $post ) {
        $meta_values[] = get_post_meta( $post->ID, $meta_key, true );
    }

    return $meta_values;

}

//Hook the filter options form
add_action('restrict_manage_posts','add_meta_value_to_posts');

function add_meta_value_to_posts(){

    // only add filter to shop_order
    global $post_type;
    if( $post_type == 'shop_order' ) {

        // function to grab all possible meta values of the chosen meta key in this case '_payment_method'
        $meta_values = get_meta_values('_payment_method', 'shop_order');

        // Generate select field from meta values
        echo '<select name="_payment_method" id="_payment_method">';

            $all_selected = sanitize_text_field($_GET['_payment_method']) == 'all' ? ' selected' : '';
            echo '<option value="all"'.$all_selected.'>All</option>';

            foreach ( $meta_values as $meta_value ) {
                $selected = sanitize_text_field($_GET['_payment_method']) == $meta_value ? ' selected' : '';
                echo '<option value="'.$meta_value.'"'.$selected.'>'.$meta_value.'</option>';
            }

        echo '</select>';

    }

}

// Hook parse_query to add new filter parameters
add_action('parse_query','filter_posts_per_meta_value');

function filter_posts_per_meta_value( $query ) {

    global $pagenow, $post_type;
    // Only add parmeeters if on shop_order and if all is not selected
    if( $pagenow == 'edit.php' && $post_type == 'shop_order' && !empty($_GET['_payment_method']) && $_GET['_payment_method'] != 'all' && $GLOBALS['run_meta_filter_on_query'] ) {

        $query->query_vars['meta_query'][] = array(
            'key' => '_payment_method',
            'value' => $_GET['_payment_method'],
            'compare' => '=',
        );

    }

}