Simple Theory
Simple Theory

Reputation: 78

Add a new custom checkout field before billing details in Woocommerce?

I can add a set of custom fields to my WooCommerce checkout screen but need to move it above the 'Billing Details'.

How can that be done?

According to this official WooCommerce documentation, here is an example code to add extra custom checkout fields:

/**
 * Add the field to the checkout
 */
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );

function my_custom_checkout_field( $checkout ) {

echo '<div id="my_custom_checkout_field"><h2>' . __('My Field') . '</h2>';

woocommerce_form_field( 'my_field_name', array(
    'type'          => 'text',
    'class'         => array('my-field-class form-row-wide'),
    'label'         => __('Fill in this field'),
    'placeholder'   => __('Enter something'),
    ), $checkout->get_value( 'my_field_name' ));

echo '</div>';

}

Upvotes: 2

Views: 9480

Answers (2)

LoicTheAztec
LoicTheAztec

Reputation: 253784

Updated: There is only one available hook before checkout billing fields that you can use to add custom fields in checkout form. Try this complete code:

add_action( 'woocommerce_checkout_before_customer_details', 'custom_checkout_fields_before_billing_details', 20 );
function custom_checkout_fields_before_billing_details(){
    $domain = 'woocommerce';
    $checkout = WC()->checkout;

    echo '<div id="my_custom_checkout_field">';

    echo '<h3>' . __('My New Fields Section') . '</h3>';

    woocommerce_form_field( '_my_field_name', array(
        'type'          => 'text',
        'label'         => __('My 1st new field', $domain ),
        'placeholder'   => __('Please fill in "my 1st new field"', $domain ),
        'class'         => array('my-field-class form-row-wide'),
        'required'      => true, // or false
    ), $checkout->get_value( '_my_field_name' ) );

    echo '</div>';
}

// Custom checkout fields validation
add_action( 'woocommerce_checkout_process', 'custom_checkout_field_process' );
function custom_checkout_field_process() {
    if ( isset($_POST['_my_field_name']) && empty($_POST['_my_field_name']) )
        wc_add_notice( __( 'Please fill in "My 1st new field".' ), 'error' );
}

// Save custom checkout fields the data to the order
add_action( 'woocommerce_checkout_create_order', 'custom_checkout_field_update_meta', 10, 2 );
function custom_checkout_field_update_meta( $order, $data ){
    if( isset($_POST['_my_field_name']) && ! empty($_POST['_my_field_name']) )
        $order->update_meta_data( '_my_field_name', sanitize_text_field( $_POST['_my_field_name'] ) );
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.

You will get a new field section with yours new custom field (where you can have many also):

enter image description here


Official reference docs: Customizing checkout fields using actions and filters

Upvotes: 10

Justin R.
Justin R.

Reputation: 488

WooCommerce uses hooks to display checkout page elements, such as the billing and shipping fields. You can use them to add your own custom content. You'll notice that the first line of code you posted contains woocommerce_after_order_notes which is one of those hooks. It defines the placement of the field.

If you wanted to add a message before the Billing Details, you could do it with this hook: woocommerce_before_checkout_billing_form

You can find a complete list of WooCommerce hooks at https://docs.woocommerce.com/wc-apidocs/hook-docs.html

Upvotes: 1

Related Questions