Retrieving custom field value from Checkout page

On the WooCommerce Checkout page, I have added an extra field the customer must enter to checkout.

I want to access this field’s value in the woocommerce_cart_calculate_fees action hook.

Read More

I have tried several ways by using woocommerce->customer data and order data but cannot get the value. Any assistance is greatly appreciated.

/* WooCommerce Add Extra Fees */
add_action( 'woocommerce_cart_calculate_fees','endo_handling_fee' );
function endo_handling_fee() {
 global $woocommerce, $post;

 if ( is_admin() && ! defined( 'DOING_AJAX' ) )
      return;

 // Get the order ID
 $order = new WC_Order($post->ID);
 // to escape # from order id 
 $order_id = trim(str_replace('#', '', $order->get_order_number()));

 // Here is where I want to get the field value
 $orderFee = get_post_meta( $order_id, 'decedents_name_field', true );

}

Related posts

2 comments

  1. I ran into the same problem. I had a delivery fee that needed to be applied if fewer than a certain number of products were in the cart AND the user wanted a delivery (my custom field). What I ended up doing to solve this was sending the data to the server via AJAX like so:

    jQuery("select#delivery_pickup_field").change(function(e) {
        var data = {
            action: 'woocommerce_delivery_fee',
            security: wc_checkout_params.apply_delivery_nonce,
            delivery_option: this.value 
        };
    
        jQuery.ajax({
            type: 'POST',
            url: wc_checkout_params.ajax_url,
            data: data,
            success: function (code) {
                if (code === '0') {
                    jQuery('body').trigger('update_checkout');
                }
                console.log(code);
            },
            dataType: 'html'
        });
        return false;
    });
    

    Then take that data and put it in a SESSION variable

    // Give server access to status of delivery select
    add_action('wp_ajax_woocommerce_delivery_fee', 'ajax_add_delivery_fee', 10);
    add_action('wp_ajax_nopriv_woocommerce_delivery_fee', 'ajax_add_delivery_fee', 10);
    function ajax_add_delivery_fee() {
        if(isset($_POST['delivery_option'])) {
            session_start();
            $_SESSION['delivery_option'] = $_POST['delivery_option'];
            return 1;
        }
        return 0;
    }
    

    From there, your server now has access to whatever value your custom field has.

    // Adding delivery fee if fewer than 6 items is in cart
    add_action( 'woocommerce_cart_calculate_fees', 'minimum_delivery_fee' );
    function minimum_delivery_fee($instance) {
        global $woocommerce;
        @session_start();
        $order_meta = $_SESSION['delivery_option'];
    
        if(($woocommerce->cart->cart_contents_count < 6) && ($order_meta == 'delivery')) {
            $woocommerce->cart->add_fee( __('Delivery Fee', 'woocommerce'), 15 );
        }
    }
    

    As helgatheviking pointed out, the order hasn’t been submitted yet and doesn’t exist. The only way I can see you getting the data you need is by sending it to the server via AJAX.

    If this is confusing, check out the source I used for more information.

  2. Found solution that don’t require AJAX:
    The field values are stored in:
    WC()->checkout()->get_value(‘post_data’)

    In my case I had to add a fee of 2% of on payments (2nd payment and up);

    I added a custom field to billing fileds, note use of class update_totals_on_change to trigger cart recalculation to add the fee.

    function number_of_payments_select($fields ){
        //print_b($checkout);
    
    
        $cartTotal=WC()->cart->get_cart_contents_total();
        //echo $cartTotal;
        $paymentsArray=array();
            for ($i=1; $i<=12 ;$i++){
                $paymentsArray[strval($i)]= $i.' Payments(amount to pay: '.($cartTotal/$i+$cartTotal/$i*($i-1)*1.02).'currency)';
            }
    
    
    
        $fields ['billing_number_of_payments']= array(
            'type'          => 'select',
            'class'         => array('number_of_payments form-row-wide update_totals_on_change'),
            'label'         => 'Number of payments',
            'required'    => true,
            'options'     => $paymentsArray);
    
            return $fields;
    
    }
    add_action( 'woocommerce_billing_fields', 'number_of_payments_select', 10, 1 );
    

    Then I get the number of payments selected by parsing (WC()->checkout()->get_value(‘post_data’)

        function add_payments_fee(){
        if (is_admin() && !defined('DOING_AJAX')) {
            return;
        }
    
    
        parse_str (WC()->checkout()->get_value('post_data'),$post_data);
        $number_of_payments=$post_data['billing_number_of_payments'];
        if ($number_of_payments>1) {
            $cartTotal=WC()->cart->get_cart_contents_total();
            $payment_fee=$cartTotal/$number_of_payments*($number_of_payments-1)*0.02;
            WC()->cart->add_fee('fee', $payment_fee);
        }
    }
    add_action('woocommerce_cart_calculate_fees','add_payments_fee');
    

Comments are closed.