Tras la última actualización de ¿Cómo añadir un campo NIF o CIF a WooCommerce 2.1?, código publicado inicialmente en ¿Cómo añadir un campo NIF o CIF a WooCommerce 2.0?, no habíamos tenido que realizar ningún tipo de modificación sobre el mismo hasta que se ha publicado WooCommerce 2.4 y hemos detectado, gracias al aviso de uno de nuestros lectores, un fallo en el orden de los campos que se muestran en el formulario de la página de finalización de la compra.

Tras algunas pruebas, ya hemos dado con la configuración correcta, así que procedemos a publicar el código PHP íntegro que necesitas para que todo vuelva a la normalidad. En esta ocasión le hemos añadido directamente la validación del campo NIF/CIF, que publicamos en Validando el campo NIF o CIF en WooCommerce y que permite la validación de cualquier tipo de número NIF, CIF o NIE. Recuerda que este código PHP debe ser añadido al archivo functions.php del tema hijo o padre que estés utilizando:

//Arreglamos la dirección predeterminada
function campos_de_direccion( $campos ) {
    $campos['nif'] = array( 
        'label' => __( '<abbr title="Código de Identificación Fiscal" lang="es">CIF</abbr>/<abbr title="Número de Identificación Fiscal" lang="es">NIF</abbr>', 'woocommerce' ),
        'placeholder' => _x( 'Introduzca el CIF/NIF', 'placeholder', 'woocommerce' ),
        'required' => false,
        'class' =>array( 'form-row-last' ),
        'clear' => true,
	);
    $campos['email'] =array( 
        'label' => __( 'Email Address', 'woocommerce' ),
        'required' => true,
        'class' =>array( 'form-row-last' ),
        'validate' =>array( 'email' ),
        'clear' => true,
	);
    $campos['phone'] =array( 
        'label' => __( 'Phone', 'woocommerce' ),
        'required' => true,
        'class' =>array( 'form-row-first' ),
	);

    $campos['company']['class'][0] = 'form-row-first';
    $campos['city']['class'][0] = 'form-row-first';
    $campos['state']['class'][0] = 'form-row-last update_totals_on_change';
    $campos['postcode']['class'][0] .= ' update_totals_on_change';

    //Reordenamos los campos
    $campos_nuevos['country'] = $campos['country'];
    $campos_nuevos['first_name'] = $campos['first_name'];
    $campos_nuevos['last_name'] = $campos['last_name'];
    $campos_nuevos['company'] = $campos['company'];
    $campos_nuevos['nif'] = $campos['nif'];
    $campos_nuevos['address_1'] = $campos['address_1'];
    $campos_nuevos['address_2'] = $campos['address_2'];
    $campos_nuevos['postcode'] = $campos['postcode'];
    $campos_nuevos['city'] = $campos['city'];
    $campos_nuevos['state'] = $campos['state'];
    if ( isset( $campos['email'] ) ) {
		$campos_nuevos['email'] = $campos['email'];
	}
    if ( isset( $campos['phone'] ) ) {
		$campos_nuevos['phone']['required'] = true;
		$campos_nuevos['phone'] = $campos['phone'];
    }
	
    return $campos_nuevos;
}
add_filter( 'woocommerce_default_address_fields' , 'campos_de_direccion' );

//Nueva función para hacer compatible el código con WooCommerce 2.1
function dame_campo_personalizado( $campo, $pedido ) {
    $valor = get_post_meta( $pedido, $campo, false );
	if ( isset( $valor[0] ) ){
		return $valor[0];
	}
	return NULL;
}

//Añadimos el NIF y el teléfono a la dirección de facturación y envío
function anade_campo_nif_direccion_facturacion( $campos, $pedido ) {
    $campos['nif'] = dame_campo_personalizado( '_billing_nif', $pedido->id );
    $campos['phone'] = dame_campo_personalizado( '_billing_phone', $pedido->id );
	
	return $campos;
}
add_filter( 'woocommerce_order_formatted_billing_address','anade_campo_nif_direccion_facturacion', 1, 2 );

function anade_campo_nif_direccion_envio( $campos, $pedido ) {
    $campos['nif'] = dame_campo_personalizado( '_shipping_nif', $pedido->id );
    $campos['phone'] = dame_campo_personalizado( '_shipping_phone', $pedido->id );
	
	return $campos;
}
add_filter( 'woocommerce_order_formatted_shipping_address','anade_campo_nif_direccion_envio', 1, 2 );

function formato_direccion_de_facturacion( $campos, $argumentos ) {
    $campos['{nif}'] = $argumentos['nif'];
    $campos['{nif_upper}'] =strtoupper( $argumentos['nif'] );
    $campos['{phone}'] = $argumentos['phone'];
    $campos['{phone_upper}'] =strtoupper( $argumentos['phone'] );
	
	return $campos;
}
add_filter( 'woocommerce_formatted_address_replacements','formato_direccion_de_facturacion', 1, 2 );

//Reordenamos los campos de la dirección predeterminada
function formato_direccion_localizacion( $campos ) {
    $campos['default'] = "{name}n{company}n{nif}n{address_1}n{address_2}n{city}n{state}n{postcode}n{country}n{phone}";
    $campos['ES'] = "{name}n{company}n{nif}n{address_1}n{address_2}n{postcode} {city}n{state}n{country}n{phone}";
	
	return $campos;
}
add_filter( 'woocommerce_localisation_address_formats','formato_direccion_localizacion' );

//Arreglamos el formulario de envío
function formulario_de_envio( $campos ) {
    $campos['shipping_email'] =array( 
        'label' => __( 'Email Address', 'woocommerce' ),
        'required' => false,
        'class' =>array( 'form-row-first' ),
        'validate' =>array( 'email' ),
	);
    $campos['shipping_phone'] =array( 
        'label' => __( 'Phone', 'woocommerce' ),
        'required' => true,
        'class' =>array( 'form-row-last' ),
        'clear' => true,
	);
    $campos['shipping_postcode'] =array( 
        'label' => __( 'Postcode / Zip', 'woocommerce' ),
        'placeholder' => __( 'Postcode / Zip', 'woocommerce' ),
        'required' => true,
        'class' =>array( 'form-row-wide', 'address-field' ),
        'clear' => true,
        'custom_attributes' =>array( 
            'autocomplete' => 'no'
        )
	);
	 
	return $campos;
}
add_filter( 'woocommerce_shipping_fields' , 'formulario_de_envio' );

//Arreglamos el formulario de cobro
function formulario_de_cobro( $campos ) {
	$campos['billing_postcode'] =array( 
        'label' => __( 'Postcode / Zip', 'woocommerce' ),
        'placeholder' => __( 'Postcode / Zip', 'woocommerce' ),
        'required' => true,
        'class' => array( 'form-row-wide', 'address-field' ),
        'clear' => true,
        'custom_attributes' => array( 
            'autocomplete' => 'no'
        )
	);
	
	return $campos;
}
add_filter( 'woocommerce_billing_fields' , 'formulario_de_cobro' );

//Añade el campo CIF/NIF a usuarios
function anade_campos_administracion_usuarios( $campos ) {
    $campos['billing']['fields']['billing_nif'] = array( 
            'label' => __( 'CIF/NIF', 'woocommerce' ),
            'description' => ''
	);

    $campos['shipping']['fields']['shipping_nif'] = array( 
            'label' => __( 'CIF/NIF', 'woocommerce' ),
            'description' => ''
	);
    $campos['shipping']['fields']['shipping_email'] = array( 
            'label' => __( 'Email', 'woocommerce' ),
            'description' => '',
       		'class' =>array( 'form-row-last' ),
	);
	$campos['shipping']['fields']['shipping_phone'] = array( 
            'label' => __( 'Telephone', 'woocommerce' ),
            'description' => '',
	        'class' =>array( 'form-row-first' ),
	);

    //Reordenamos los campos
    $campos_nuevos['billing']['title'] = $campos['billing']['title'];
    $campos_nuevos['billing']['fields']['billing_first_name'] = $campos['billing']['fields']['billing_first_name'];
    $campos_nuevos['billing']['fields']['billing_last_name'] = $campos['billing']['fields']['billing_last_name'];
    $campos_nuevos['billing']['fields']['billing_company'] = $campos['billing']['fields']['billing_company'];
    $campos_nuevos['billing']['fields']['billing_nif'] = $campos['billing']['fields']['billing_nif'];
    $campos_nuevos['billing']['fields']['billing_address_1'] = $campos['billing']['fields']['billing_address_1'];
    $campos_nuevos['billing']['fields']['billing_address_2'] = $campos['billing']['fields']['billing_address_2'];
    $campos_nuevos['billing']['fields']['billing_postcode'] = $campos['billing']['fields']['billing_postcode'];
    $campos_nuevos['billing']['fields']['billing_city'] = $campos['billing']['fields']['billing_city'];
    $campos_nuevos['billing']['fields']['billing_state'] = $campos['billing']['fields']['billing_state'];
    $campos_nuevos['billing']['fields']['billing_country'] = $campos['billing']['fields']['billing_country'];
    $campos_nuevos['billing']['fields']['billing_phone'] = $campos['billing']['fields']['billing_phone'];
    $campos_nuevos['billing']['fields']['billing_email'] = $campos['billing']['fields']['billing_email'];

    $campos_nuevos['shipping']['title'] = $campos['shipping']['title'];
    $campos_nuevos['shipping']['fields']['shipping_first_name'] = $campos['shipping']['fields']['shipping_first_name'];
    $campos_nuevos['shipping']['fields']['shipping_last_name'] = $campos['shipping']['fields']['shipping_last_name'];
    $campos_nuevos['shipping']['fields']['shipping_company'] = $campos['shipping']['fields']['shipping_company'];
    $campos_nuevos['shipping']['fields']['shipping_nif'] = $campos['shipping']['fields']['shipping_nif'];
    $campos_nuevos['shipping']['fields']['shipping_address_1'] = $campos['shipping']['fields']['shipping_address_1'];
    $campos_nuevos['shipping']['fields']['shipping_address_2'] = $campos['shipping']['fields']['shipping_address_2'];
    $campos_nuevos['shipping']['fields']['shipping_postcode'] = $campos['shipping']['fields']['shipping_postcode'];
    $campos_nuevos['shipping']['fields']['shipping_city'] = $campos['shipping']['fields']['shipping_city'];
    $campos_nuevos['shipping']['fields']['shipping_state'] = $campos['shipping']['fields']['shipping_state'];
    $campos_nuevos['shipping']['fields']['shipping_country'] = $campos['shipping']['fields']['shipping_country'];
    $campos_nuevos['shipping']['fields']['shipping_phone'] = $campos['shipping']['fields']['shipping_phone'];
    $campos_nuevos['shipping']['fields']['shipping_email'] = $campos['shipping']['fields']['shipping_email'];

    $campos_nuevos = apply_filters( 'wcbcf_customer_meta_fields', $campos_nuevos );
	
	return $campos_nuevos;
}
add_filter( 'woocommerce_customer_meta_fields', 'anade_campos_administracion_usuarios' );

//Añadimos el NIF a la dirección de facturación y envío
function anade_campo_nif_usuario_direccion_facturacion( $campos, $usuario ) {
    $campos['nif'] = get_user_meta( $usuario, 'billing_nif', true );
    $campos['phone'] = get_user_meta( $usuario, 'billing_phone', true );return $campos;
}
add_filter( 'woocommerce_user_column_billing_address','anade_campo_nif_usuario_direccion_facturacion', 1, 2 );

function anade_campo_nif_usuario_direccion_envio( $campos, $usuario ) {
    $campos['nif'] = get_user_meta( $usuario, 'shipping_nif', true );
    $campos['phone'] = get_user_meta( $usuario, 'shipping_phone', true );return $campos;
}
add_filter( 'woocommerce_user_column_shipping_address','anade_campo_nif_usuario_direccion_envio', 1, 2 );

//Añade el campo NIF a Editar mi dirección
function anade_campo_nif_editar_direccion( $campos, $usuario, $nombre ) {
    $campos['nif'] = get_user_meta( $usuario, $nombre . '_nif', true );
    $campos['phone'] = get_user_meta( $usuario, $nombre . '_phone', true );

    //Ordena los campos
    $campos_nuevos['first_name'] = $campos['first_name'];
    $campos_nuevos['last_name'] = $campos['last_name'];
    $campos_nuevos['company'] = $campos['company'];
    $campos_nuevos['nif'] = $campos['nif'];
    $campos_nuevos['address_1'] = $campos['address_1'];
    $campos_nuevos['address_2'] = $campos['address_2'];
    $campos_nuevos['postcode'] = $campos['postcode'];
    $campos_nuevos['city'] = $campos['city'];
    $campos_nuevos['state'] = $campos['state'];
    $campos_nuevos['country'] = $campos['country'];
    $campos_nuevos['phone'] = $campos['phone'];
	
	return $campos_nuevos;
}
add_filter( 'woocommerce_my_account_my_address_formatted_address', 'anade_campo_nif_editar_direccion', 10, 3 );

//Añade el campo NIF a Detalles del pedido
function anade_campo_nif_editar_direccion_pedido( $campos ) {
    $campos['nif'] = array( 
        'label' => __( 'CIF/NIF', 'woocommerce' ),
        'show'  => false
    );
    $campos['phone'] = array( 
        'label' => __( 'Telephone', 'woocommerce' ),
        'show'  => false
    );

    //Ordena los campos
    $campos_nuevos['first_name'] = $campos['first_name'];
    $campos_nuevos['last_name'] = $campos['last_name'];
    $campos_nuevos['company'] = $campos['company'];
    $campos_nuevos['nif'] = $campos['nif'];
    $campos_nuevos['address_1'] = $campos['address_1'];
    $campos_nuevos['address_2'] = $campos['address_2'];
    $campos_nuevos['postcode'] = $campos['postcode'];
    $campos_nuevos['city'] = $campos['city'];
    $campos_nuevos['state'] = $campos['state'];
    $campos_nuevos['country'] = $campos['country'];
    $campos_nuevos['phone'] = $campos['phone'];

    return $campos_nuevos;
}
add_filter( 'woocommerce_admin_billing_fields', 'anade_campo_nif_editar_direccion_pedido' );
add_filter( 'woocommerce_admin_shipping_fields', 'anade_campo_nif_editar_direccion_pedido' );

function carga_hoja_de_estilo_editar_direccion_pedido() {
    echo '</pre>
<style type="text/css"><!-- #order_data .order_data_column ._billing_company_field, #order_data .order_data_column ._shipping_company_field { float: left; margin: 9px 0 0; padding: 0; width: 48%; } #order_data .order_data_column ._billing_nif_field, #order_data .order_data_column ._shipping_nif_field { float: right; margin: 9px 0 0; padding: 0; width: 48%; } --></style>
<pre>';
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'carga_hoja_de_estilo_editar_direccion_pedido' );

//Validando el campo NIF/CIF
function validando_campo() {
	$falso = true;

    if ( isset( $_POST['billing_nif'] ) && strlen( $_POST['billing_nif'] ) == 9 ) {
		$nif = strtoupper( $_POST['billing_nif'] );

		for ( $i = 0; $i < 9; $i ++ ) {
			$num[$i] = substr( $nif, $i, 1 );
		}

		if ( !preg_match( '/((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)/', $nif ) ) { //No tiene formato válido
			$falso = true;
		}

		if ( preg_match( '/(^[0-9]{8}[A-Z]{1}$)/', $nif ) ) {
			if ( $num[8] == substr( 'TRWAGMYFPDXBNJZSQVHLCKE', substr( $nif, 0, 8 ) % 23, 1 ) ) { //NIF válido
				$falso = false;
			}
		}

		$suma = $num[2] + $num[4] + $num[6];
		for ( $i = 1; $i < 8; $i += 2 ) {
			$suma += substr( ( 2 * $num[$i] ), 0, 1 ) + substr( ( 2 * $num[$i] ), 1, 1 );
		}
		$n = 10 - substr( $suma, strlen( $suma ) - 1, 1 );

		if ( preg_match( '/^[KLM]{1}/', $nif ) ) { //NIF especial válido
			if ( $num[8] == chr( 64 + $n ) ) {
				$falso = false;
			}
		}

		if ( preg_match( '/^[ABCDEFGHJNPQRSUVW]{1}/', $nif ) && isset ( $num[8] ) ) {
			echo $num[8] ." == ".chr( 64 + $n )." - " . substr( $n, strlen( $n ) - 1, 1 );
			if ( $num[8] == chr( 64 + $n ) || $num[8] == substr( $n, strlen( $n ) - 1, 1 ) ) { //CIF válido
				$falso = false;
			}
		}

		if ( preg_match( '/^[T]{1}/', $nif ) ) {
			if ( $num[8] == preg_match( '/^[T]{1}[A-Z0-9]{8}$/', $nif ) ) { //NIE válido (T)
				$falso = false;
			}
		}

		if ( preg_match( '/^[XYZ]{1}/', $nif ) ) { //NIE válido (XYZ)
			if ( $num[8] == substr( 'TRWAGMYFPDXBNJZSQVHLCKE', substr( str_replace( array( 'X','Y','Z' ), array( '0','1','2' ), $nif ), 0, 8 ) % 23, 1 ) ) {
				$falso = false;
			}
		}
	}

	if ( $falso ) {
		if ( empty( $_POST['billing_nif'] ) ) {
			add_action( 'woocommerce_checkout_process', 'validando_campo' );

		} else {
			wc_add_notice( __( 'Por favor, introduzca un NIF/CIF válido.' ), 'error' );
		}
	}
}
add_action( 'woocommerce_checkout_process', 'validando_campo' );

Como siempre esperamos que este nuevo código os resulte útil y quedamos a la espera de vuestros comentarios, aportes y sugerencias.

Actualización: Hemos solucionado varios errores que hemos detectado en el código publicado originalmente.