HeruRaHa
HeruRaHa

Reputation: 63

Woocommerce custom fields for shipping calculator

I'm building a custom shipping method for Woocommerce, and the one thing I'm totally hung up on is how to pass custom values to the calculate_shipping() function, either when it's being used on the Cart page or Checkout page.

I need to pass a handful of user-defined variables that will impact the quote -- ie "Is Residential Address", "Is Trade Show", etc etc.

calculate_shipping receives the $package array which contains a 'destination' array, but this only includes the standard add1, add2, city, state, zip, country info. I've added custom fields to the checkout page under both billing and shipping but I still can't figure out how to make these values accessible to the calculate_shipping function.

I've added a custom field like so:

add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );

// Our hooked in function - $fields is passed via the filter!
function custom_override_checkout_fields( $fields ) {
  $fields['shipping']['is_residential'] = array(
    'label'     => __('Residential Address?', 'woocommerce'),
 'type'      => 'checkbox',
 'required'  => false,
 'class'     => array('form-row-wide'),
 'clear'     => true
  );

  return $fields;
}

And I see this field show up on the Shipping section of the checkout form. However, I'm not seeing how I can access it anywhere. Even doing a print_r($_POST) on the checkout page doesn't show this field as being part of the post data, even after I know the form has been updated and re-posted.

But most importantly, I need to add the contents of the submitted field into the $package object which Woocommerce passes to a shipping method's calculate_shipping() function.

I'm just really not sure where to even start with this.

Upvotes: 5

Views: 10236

Answers (1)

Gabriel Reguly
Gabriel Reguly

Reputation: 350

You can't expect to add checkout fields and have them available at the cart page.

The correct way is to use cart packages.

Check function get_shipping_packages() from class-wc-cart.php

public function get_shipping_packages() {
        // Packages array for storing 'carts'
        $packages = array();

        $packages[0]['contents']                 = $this->get_cart();       // Items in the package
        $packages[0]['contents_cost']            = 0;                       // Cost of items in the package, set below
        $packages[0]['applied_coupons']          = $this->applied_coupons;
        $packages[0]['destination']['country']   = WC()->customer->get_shipping_country();
        $packages[0]['destination']['state']     = WC()->customer->get_shipping_state();
        $packages[0]['destination']['postcode']  = WC()->customer->get_shipping_postcode();
        $packages[0]['destination']['city']      = WC()->customer->get_shipping_city();
        $packages[0]['destination']['address']   = WC()->customer->get_shipping_address();
        $packages[0]['destination']['address_2'] = WC()->customer->get_shipping_address_2();

        foreach ( $this->get_cart() as $item )
            if ( $item['data']->needs_shipping() )
                if ( isset( $item['line_total'] ) )
                    $packages[0]['contents_cost'] += $item['line_total'];

        return apply_filters( 'woocommerce_cart_shipping_packages', $packages );
    }

You gotta hook into woocommerce_cart_shipping_packages filter and add your fields there.

Most likely you will need to add them (your fields) at the shipping calculator and checkout pages.

Hope this helps.

Upvotes: 3

Related Questions