I have added a custom field using the below code:

add_action( 'woocommerce_before_order_notes', 'bbloomer_add_custom_checkout_field' );
function bbloomer_add_custom_checkout_field( $checkout ) { 
   $current_user = wp_get_current_user();
   $saved_gst_no = $current_user->gst_no;
   
   woocommerce_form_field( 'gst_no', array(        
       'type'        => 'text',        
       'class'       => array( 'form-row-wide' ),        
       'label'       => 'GST Number',        
       'placeholder' => 'GST Number',        
       'required'    => true
       //'default'   => $saved_gst_no,        
   ), $checkout->get_value( 'gst_no' ) ); 
}

On entering any value in GST Number field (custom checkout field), then going to payment screen by clicking "Place order" button and returning to checkout page without completing the transaction, all default woocommerce fields like billing phone, email etc are auto filled from the session.

However, the custom field added via above code is always blank. How to get the previously entered value auto-filled in the custom field for guest users, similar to the way default woocommerce fields are auto-filled?

2

There are 2 best solutions below

0
On BEST ANSWER

Updated (replaced wrong WC_Session method set() with get() on the first function)

This will work for guest users too. Replace your code with:

// Display checkout custom field
add_action( 'woocommerce_before_order_notes', 'add_custom_checkout_field' );
function add_custom_checkout_field( $checkout ) { 
    $key_field = 'gst_no';
       
    woocommerce_form_field( $key_field, array(        
        'type'        => 'text',        
        'class'       => array( 'form-row-wide' ),        
        'label'       => __('GST Number'),        
        'placeholder' => __('GST Number'),        
        'required'    => true
        //'default'   => $saved_gst_no,        
    ), $checkout->get_value($key_field) ? $checkout->get_value($key_field) : WC()->session->get($key_field) ); 
}

// Save checkout custom field value in a WC_Session variable 
add_action( 'woocommerce_checkout_create_order', 'action_checkout_create_order', 10, 2 );
function action_checkout_create_order( $order, $data  ) {
    $key_field = 'gst_no';
    
    if( isset($_POST[$key_field]) ) {
        WC()->session->set($key_field, sanitize_text_field($_POST[$key_field]));
    }
}

// Save checkout custom field value as user meta data
add_action( 'woocommerce_checkout_update_customer', 'action_checkout_update_customer', 10, 2 );
function action_checkout_update_customer( $customer, $data  ) {
    $key_field = $key_field;
    
    if( isset($_POST['gst_no']) ) {
        $customer->update_meta_data($key_field, sanitize_text_field($_POST[$key_field]));
    }
}

Note: Uses a WC_Session variable to store the submitted value for guests, allowing to display it on checkout when returning without completing the transaction.

0
On

In my experience, WooCommerce was saving the form data in session variables via AJAX when fields were updated via the update_order_review path. In order to hook into this and stored my custom vars, I used the following:

add_action('woocommerce_checkout_update_order_review', 'custom_woocommerce_checkout_update_order_review');
function custom_woocommerce_checkout_update_order_review($post_data){

    // Convert $post_data string to array and clean it
    $post_arr = array();
    parse_str($post_data, $post_arr);
    wc_clean($post_arr);

    if(isset($post_arr['gst_no'])) {
        WC()->session->set('gst_no', $post_arr['gst_no']);
    }
}

Also a deeper way to add the custom checkout fields so that it's available in the $data passed to woocommerce_checkout_update_order_meta:

add_filter('woocommerce_checkout_fields', 'custom_checkout_fields');
function custom_checkout_fields($fields){
    $fields['gst_no'] = array(
        'type'        => 'text',
        'default'     => WC()->session->get('gst_no')
    );
    return $fields;
}