Search code examples
phpwordpresswoocommercecheckoutcustom-fields

Get and display the inputed data from custom Checkout fields in WooCommerce


I already add checkbox to show/hide custom field in my WooCommerce Checkout page at functions.php and the code is working well but I can't get input data from my customer. Where/How can I get it? I've tried so many codes and losing so much my time.

Here is the code that displays my custom checkout fieds:

add_filter( 'woocommerce_checkout_fields' , 'rws_display_checkbox_and_new_checkout_field' ); 
function rws_display_checkbox_and_new_checkout_field( $fields ) {

    $fields['billing']['have_vat_number'] = array(
        'type'      => 'checkbox',
        'label'     => __('ต้องการใบกำกับภาษี', 'woocommerce'),
        'class'     => array('form-row-wide'),
        'clear'     => true
    );   
    $fields['billing']['vat_name'] = array(
        'label'     => __('ชื่อ – สกุล / บริษัท', 'woocommerce'),
        'placeholder'   => _x(' ', 'placeholder', 'woocommerce'),
        'class'     => array('form-row-wide'),
        'clear'     => true
    );
    $fields['billing']['vat_number'] = array(
        'label'     => __('หมายเลขผู้เสียภาษี', 'woocommerce'),
        'placeholder'   => _x(' ', 'placeholder', 'woocommerce'),
        'class'     => array('form-row-wide'),
        'clear'     => true
    );
    $fields['billing']['vat_address'] = array(
        'type'      => 'textarea',
        'label'     => __('ที่อยู่', 'woocommerce'),
        'placeholder'   => _x(' ', 'placeholder', 'woocommerce'),
        'class'     => array('form-row-wide'),
        'clear'     => true
    );
    return $fields;

}

This code show / hide some custom fields on a checkbox click:

add_action( 'woocommerce_after_checkout_form', 'rws_conditionally_hide_show_new_field', 9999 );
function rws_conditionally_hide_show_new_field() {
  wc_enqueue_js( "
      jQuery('input#have_vat_number').change(function(){
         if (! this.checked) {
            jQuery('#vat_name_field').fadeOut();
            jQuery('#vat_name_field input').val('');
            jQuery('#vat_number_field').fadeOut();
            jQuery('#vat_number_field input').val(''); 
            jQuery('#vat_address_field').fadeOut();
            jQuery('#vat_address_field input').val(''); 
         } else {
            jQuery('#vat_name_field').fadeIn();
            jQuery('#vat_number_field').fadeIn();
            jQuery('#vat_address_field').fadeIn();
         } 
      }).change();
  ");  
    if ( isset( $_POST['billing']['have_vat_number'] ) ) {
        $have_vat_number = $_POST['billing']['have_vat_number'];
    }

    if ( isset( $_POST['billing']['vat_name'] ) ) {
        $vat_name = $_POST['billing']['vat_name'];
    }

    if ( isset( $_POST['billing']['vat_number'] ) ) {
        $vat_number = $_POST['billing']['vat_number'];
    }

    if ( isset( $_POST['billing']['vat_address'] ) ) {
        $vat_address = $_POST['billing']['vat_address'];
    }
}

Then I've tried this code to save submitted input data when placing an order, but is still not working:

add_action('woocommerce_checkout_update_order_meta', 'rws_save_custom_checkout_field_data');

function rws_save_custom_checkout_field_data($order_id) {
    if ($_POST['billing']['have_vat_number']) {
        $have_vat_number = sanitize_text_field($_POST['billing']['have_vat_number']);
        update_post_meta($order_id, 'Have VAT Number', $have_vat_number);
    }

    if ($_POST['billing']['vat_name']) {
        $vat_name = sanitize_text_field($_POST['billing']['vat_name']);
        update_post_meta($order_id, 'VAT Name', $vat_name);
    }

    if ($_POST['billing']['vat_number']) {
        $vat_number = sanitize_text_field($_POST['billing']['vat_number']);
        update_post_meta($order_id, 'VAT Number', $vat_number);
    }

    if ($_POST['billing']['vat_address']) {
        $vat_address = sanitize_textarea_field($_POST['billing']['vat_address']);
        update_post_meta($order_id, 'VAT Address', $vat_address);
    }
}

Any help is appreciated.


Solution

  • There are some mistakes in your code, some missing things, and you are not using the correct hooks.

    In the following revisited code (and commented), I have:

    • added a custom function with your field settings (field keys, type and label) that will allow making the code more compact and efficient.
    • added the checkout field validation
    • compacted your jQuery code in an efficient way (and make it work also in My account Edit Billing address section).
    • changed the checkout field hook to allow it displaying also the fields in the customer My account Edit Billing Address section, allowing the customer to edit or remove his VAT data.
    • added a hooked function to save the data as user metadata, that allows to:
      • display the field values in checkout VAT fields when customer has already submitted an order with filled in VAT fields.
      • display the field values in My account Edit Billing address fields when customer has already submitted an order with filled in VAT fields.
    • added a hooked function to display VAT fields values in Admin Order pages

    Here is the complete code:

    // Taxpayer Field settings
    function taxpayer_fields_settings() {
        $domain = 'woocommerce';
        
        // Here we set all required data in the array to display checkout fields
        return array(
            'billing_has_vat_number' => array(
                'type'  =>   'checkbox',
                'label' => __('ต้องการใบกำกับภาษี', $domain), // Need a tax invoice
            ),
            'billing_vat_name' => array(
                'type'  =>   'text',
                'label' => __('ชื่อ – สกุล / บริษัท', $domain),  // Taxpayer Name & Company
            ),
            'billing_vat_number' => array(
                'type'  =>   'text',
                'label' => __('หมายเลขผู้เสียภาษี', $domain), // Taxpayer number
            ),
            'billing_vat_address' => array(
                'type'  =>   'textarea',
                'label' =>  __('ที่อยู่', $domain),  // Taxpayer address
            )
        );
    }
    
    // Display Taxpayer Fields in checkout and My account Edit Billing Address
    add_filter( 'woocommerce_billing_fields' , 'add_checkout_taxpayer_custom_fields' ); 
    function add_checkout_taxpayer_custom_fields( $billing_fields ) {
        // Loop through fields settings data array
        foreach ( taxpayer_fields_settings() as $field_key => $field_data ) {
            $billing_fields[$field_key] = array(
                'type'      => $field_data['type'],
                'label'     => $field_data['label'],
                'placeholder'   => _x(' ', 'placeholder', 'woocommerce'),
                'class'     => array('form-row-wide'),
                'clear'     => true
            ); 
        }
        
        return $billing_fields;
    }
    
    // jQuery: Show / Hide Taxpayer Fields in checkout and My account Edit Billing Address
    add_action( 'wp_head', 'checkout_taxpayer_custom_fields_js' );
    function checkout_taxpayer_custom_fields_js() {
       // Only on checkout page and My Account Edit Address
        if( ( is_checkout() && ! is_wc_endpoint_url() ) || is_wc_endpoint_url( 'edit-address' ) ) :
            
        wc_enqueue_js( "jQuery(function($){
            $('input#billing_has_vat_number').change(function(){
                if (! this.checked) {
                    $('#billing_vat_name_field,#billing_vat_number_field,#billing_vat_address_field').fadeOut();
                    $('#billing_vat_name_field input,#billing_vat_number_field input,#billing_vat_address_field textarea').val(''); 
                } else {
                    $('#billing_vat_name_field,#billing_vat_number_field,#billing_vat_address_field').fadeIn();
                } 
            }).change();
        });");
        
        endif;
    }
    
    //  Taxpayer checkout fields Validation
    add_action('woocommerce_checkout_process', 'checkout_taxpayer_custom_fields_validation');
    function checkout_taxpayer_custom_fields_validation() {
        $fields_data = taxpayer_fields_settings(); // Load checkout fields settings data array
        $has_vat_key = array_key_first( $fields_data ); // Get the first field key
        
        if ( isset($_POST[$has_vat_key]) && $_POST[$has_vat_key] ) {
            array_shift($fields_data);
            
            foreach( $fields_data as $field_key => $field_data ) {
                if ( isset($_POST[$field_key]) && ! $_POST[$field_key] ) {
                    wc_add_notice( sprintf( __( 'Please fill in "%s" field' ), $field_data['label'], 'woocommerce' ), 'error' );
                }
            }
        }
    }
    
    // Save Order Taxpayer checkout fields values
    add_action( 'woocommerce_checkout_create_order', 'save_order_meta_taxpayer_custom_fields' );
    function save_order_meta_taxpayer_custom_fields( $order ) {
        $fields_data = taxpayer_fields_settings(); // Load checkout fields settings data array
        $has_vat_key = array_key_first( $fields_data ); // Get the first field key
        
        if ( isset($_POST[$has_vat_key]) && $_POST[$has_vat_key] ) {
            $order->update_meta_data( '_' . $has_vat_key, 'yes' ); // update order meta
            
            array_shift($fields_data);
            
            foreach( $fields_data as $field_key => $field_data ) {
                if ( isset($_POST[$field_key]) && $_POST[$field_key] ) {
                    if( $field_data['type'] === 'text' ) {
                        $order->update_meta_data( '_' . $field_key, sanitize_text_field($_POST[$field_key]) ); // update order meta
                    } else {
                        $order->update_meta_data( '_' . $field_key, sanitize_textarea_field($_POST[$field_key]) ); // update order meta
                    }
                }
            }
        }
    }
    
    // Save Customer Taxpayer checkout fields values
    add_action( 'woocommerce_checkout_update_customer', 'save_customer_meta_taxpayer_custom_fields' );
    function save_customer_meta_taxpayer_custom_fields( $customer ) {
        $fields_data = taxpayer_fields_settings(); // Load checkout fields settings data array
        $has_vat_key = array_key_first( $fields_data ); // Get the first field key
        
        if ( isset($_POST[$has_vat_key]) && $_POST[$has_vat_key] ) {
            $customer->update_meta_data( $has_vat_key, 1 ); // update customer meta
            
            array_shift($fields_data);
            
            foreach( $fields_data as $field_key => $field_data ) {
                if ( isset($_POST[$field_key]) && $_POST[$field_key] ) {
                    if( $field_data['type'] === 'text' ) {
                        $customer->update_meta_data( $field_key, sanitize_text_field($_POST[$field_key]) ); // update customer meta
                    } else {
                        $customer->update_meta_data( $field_key, sanitize_textarea_field($_POST[$field_key]) ); // update customer meta
                    }
                }
            }
        }
    }
    
    // Display customer Taxpayer data in Admin Orders after Billing details
    add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_admin_order_taxpayer_custom_fields' );
    function display_admin_order_taxpayer_custom_fields( $order ){
        $fields_data = taxpayer_fields_settings(); // Load checkout fields settings data array
        $has_vat_key = array_key_first( $fields_data ); // Get the first field key
        
        $customer_has_vat = $order->get_meta( '_' . $has_vat_key ); // Get customer taxpayer if exist
        
        if ( $customer_has_vat ) {
            echo '<p><strong>' . __( 'ลูกค้าเป็นผู้เสียภาษี:', 'woocommerce' ) . '</strong>'; // Label: The customer is a taxpayer
    
            array_shift($fields_data);
            
            foreach( $fields_data as $field_key => $field_data ) {
                $field_value = $order->get_meta( '_' . $field_key ); // Get other field data values
                
                if( $field_value ) {
                    echo '<br><strong>' . $field_data['label'] . ':</strong> ' . $field_value;
                }
            }
            echo '</p>';
        }
    }
    

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

    In checkout page:

    enter image description here

    In My Account Edit Billing Address:

    enter image description here

    On Admin orders single page:

    enter image description here