I have looked for this all over the internet and couldn’t find any clean solution. I did find premium plugin but it’s a waste to pay for whole plugin when you need just one small chunk of it’s features. The code bellow will add conditional field to the flat rate shipping settings. And filter available shipping methods depending on the set condition.


Adding the field

/**
 * Add contition to flat rate
 */
function my_flat_rate_condition_field($form_fields) {

	$form_fields['condition'] = array(
		'title' => 'Condition',
		'type' => 'text',
		'description' => 'Cart total when this method will be available.',
		'default' => '0'
	);

	return $form_fields;
}
add_filter('woocommerce_shipping_instance_form_fields_flat_rate', 'my_flat_rate_condition_field');

With woocommerce_shipping_instance_form_fields_method_id filter, settings can be added to any shipping method, just replace method_id with shipping id you want to add options to.
$form_fields key should be unique so you won’t end up overwriting existing options, or if you want to change input type for some option then key needs to be the same. Said key will be used in options array.
Available parameters for a field are:

array(
     'title' => 'Title for your option shown on the settings page',
     'description' => 'Description for your option shown on the settings page',
     'type' => 'text|password|textarea|checkbox|select|multiselect',
     'default' => 'Default value for the option',
     'class' => 'Class for the input',
     'css' => 'CSS rules added line to the input',
     'label' => 'Label', // checkbox only
     'options' => array(
          'key' => 'value'
     ) // array of options for select/multiselects only
)

Taken from here WooCommerce documentation on settings api.

Filtering available shipping methods

/**
 * Filter available methods
 */
function my_shipping_methods_modify($rates, $package) {
	// Cart total
	$total = $package['contents_cost'];
	// Array to fill with flat rate methods
	$flat_rates = [];
	// Loop though available methods
    foreach($rates as $id => $rate) {
        if($rate->method_id == 'flat_rate') {
			// $id looks like flat_rate:4; 4 is just instance id and
			// can be any different number
            $instance_id = explode(':', $id);
			// Options are saved (in this case) in woocommerce_flat_rate_4_settings
            $options     = get_option('woocommerce_flat_rate_'.end($instance_id).'_settings');
			// In case if condition is not set or it's empty
            if(!isset($options['condition']) || empty($options['condition'])) {
                $options['condition'] = 0;
            }

            if($total >= (int)$options['condition']) {
				// Clear previous methods if condition is met
                $flat_rates = [];
            } elseif($options['condition'] != 0) {
				// Skip the loop if condition is not zero, so method
				// with condition won't be added to the array.
                continue;
            }
			
			// Add rate to the array
			$flat_rates[$id] = $rate;
			// Unset current rate from main array
			unset($rates[$id]);
        }
    }

	return array_merge($flat_rates, $rates);
}
add_filter('woocommerce_package_rates', 'my_shipping_methods_modify', 10, 2);

This code will filter though flat_rate methods and show only those that are needed. I commented out the function so there’s no need for explanation, but in short what this functions does is, inserts all flat_rate methods into separate array and resets said array if condition is met so it will always show only one flat rate method (if there’s a method with 0 for condition, or no condition).

If you want to show flat rate at the bottom of available shipping methods (currently it’s on the top), just reverse arrays in the returning array_merge.

I hope this helps you. Leave a comment if you have any question or suggestion.