WooCommerce custom billing fields on email address

I finally got it to work using this code:

I’m using a php class to make an organized workflow so don’t mind the public on functions…

First I register my filters like this:

public function registerFilters()
{
    add_filter( 'woocommerce_default_address_fields', array($this, 'woo_new_default_address_fields'), 10, 2);
    add_filter('woocommerce_order_formatted_billing_address', array($this, 'woo_custom_order_formatted_billing_address'), 10, 2);
    add_filter('woocommerce_formatted_address_replacements', array($this, 'myFunction'), 10, 2);
    add_filter('woocommerce_localisation_address_formats', array($this, 'mySecondFunction'), 10, 2);

    return $this;
}

With this function I can add/register the custom fields to make them by default, this way it will show on the plugin section with the letters on purple (shown in the screenshot at the top of the page):

public function woo_new_default_address_fields($fields)
{
    $fields['colonia'] = array(

        'label' => __( 'Colonia', 'woocommerce' ),
        'class' => array( 'form-row-wide' ),

    );
    $fields['num_int'] = array(

        'label' => __( 'Num. Interior', 'woocommerce' ),
        'class' => array( 'form-row-wide' ),

    );
    $fields['num_ext'] = array(

        'label' => __( 'Num. Exterior', 'woocommerce' ),
        'class' => array( 'form-row-wide' ),

    );
    $fields['municipio'] = array(

        'label' => __( 'Municipio', 'woocommerce' ),
        'class' => array( 'form-row-wide' ),

    );
    $fields['reference'] = array(

        'label' => __( 'Referencias', 'woocommerce' ),
        'class' => array( 'form-row-wide' ),

    );

    $order = array(
        "first_name",
        "last_name",
        "colonia",
        "num_int",
        "num_ext",
        "municipio",
        "reference",
        "company",
        "country",
        "address_1",
        "address_2",
        "city",
        "state",
        "postcode"
    );

    foreach($order as $field) {

        $ordered_fields[$field] = $fields[$field];

    }

    $fields = $ordered_fields;

    return $fields;
}

Then I add them to the formatted billing address for the emails:

public function woo_custom_order_formatted_billing_address( $address , $WC_Order )
{

    $address = array(
        'first_name'    => 'Nombre: ' . $WC_Order->billing_first_name . ' ' . $address['last_name'],
        'address_1'     => 'Dirección: ' . $WC_Order->billing_address_1,
        'colonia'     => 'Colonia: ' . $WC_Order->billing_colonia,
        'num_ext'       => 'Num. Exterior: ' . $WC_Order->billing_num_ext,
        'num_int'       => 'Num. Interior: ' . $WC_Order->billing_num_int,
        'reference'     => 'Referencias: ' . $WC_Order->billing_reference,
        'city'          => 'Ciudad: ' . $WC_Order->billing_city,
        'state'         => 'Estado: ' . $WC_Order->billing_state,
        'municipio'     => 'Municipio: ' . $WC_Order->billing_municipio,
        'postcode'      => 'Código Postal: ' . $WC_Order->billing_postcode,


    );

    return $address;

}

Here I replace/add my custom fields into the address for them to be used on the formatted billing address:

public function myFunction( $address, $args )
{
    $address['{colonia}'] = $args['colonia'];
    $address['{num_int}'] = $args['num_int'];
    $address['{num_ext}'] = $args['num_ext'];
    $address['{municipio}'] = $args['municipio'];
    $address['{reference}'] = $args['reference'];
    return $address;
}

And then I replace/add them on how it will be shown:

public function mySecondFunction($formats)
{
    foreach($formats as $key => $value) :
        $formats[$key] .= "\n\n{colonia}";
        $formats[$key] .= "\n\n{num_int}";
        $formats[$key] .= "\n\n{num_ext}";
        $formats[$key] .= "\n\n{municipio}";
        $formats[$key] .= "\n\n{reference}";
    endforeach;

    return $formats;
}

I hope you can all understand me, I’m not an expert 🙂