type:
snippet
category:
shipping
name:
Flat rate shipping calculated by product shipping attributes via add to cart
versions:
0.6.0, 0.7.0, 0.7.1, 0.7.2, 1.0, 1.1
tags:
snippet, shipping, addtocart, checkout
date:
2012-02-22

Flat rate shipping calculated by product shipping attributes via add to cart

Versions 0.7.1 and older: Note that applying javascript shipping modifications using either live or flat rates where you are setting custom values has been found to not work as expected for subscription based products where you need the shipping to apply to each subscription renewal. A fix is in place for versions 0.7.2 and newer.

Using version 2.0? There is a new snippet available for our latest version, available from here.

If you're using handling fees note that you can't overwrite handling fees using javascript on the checkout to provide free shipping. While it will appear that the shipping is $0 on the checkout, the handling fees will be added back in server-side, and the customer will see a shipping fee that matches the handling fee cost you have set in the administration.

When using a CMS to manage products, it can sometimes be logical to define a shipping value per product within the CMS system. This would then allow store manages to update product shipping pricing alongside of the actual products.

Step 1: Update Categories

Update all categories to 'Shipped using a flat rate fee' with a value of 0 in the 'Product Delivery Option' section.

This step comes in after you've setup your CMS or management system as required if you have one. Essentially for this script you can go as basic as a numeric field called shipping for the product. A requirement for this approach is also that each product must have a code set as well. This is used to make a unique session attribute for the product.

In your add to cart form, add a session attribute for the product shipping that looks like this:

<input type="hidden" name="h:PRODUCTCODE_shipping" value="SHIPPINGVALUE" />

Or in your add to cart link like this:

...&name=Product&price=20&h:PRODUCTCODE_shipping=SHIPPINGVALUE

Step 3: Add javascript to your cart template (optional)

As the shipping value is included with your products information, you can actually calculate shipping charges inside the cart rather than just on the checkout. Insert the following javascript right before the closing </head> tag of your cart template to add shipping charges to the cart table:

<script type="text/javascript">
//<![CDATA[
  function currency_format(amount) {
    var i = parseFloat(amount);
    if(isNaN(i)) { i = 0.00; }
    var minus = "";
    if(i < 0) { minus = "-"; }
    i = Math.abs(i);
    i = parseInt((i + .005) * 100);
    i = i / 100;
    s = new String(i);
    if(s.indexOf(".") < 0) { s += ".00"; }
    if(s.indexOf(".") == (s.length - 2)) { s += "0"; }
    s = minus + s;
    return s;
  }
 
  jQuery(document).ready(function() {
    jQuery("tr#fc_cart_foot_total").before("<tr id='fc_cart_foot_shipping'><td colspan='3' class='fc_col1'>Shipping:</td><td class='fc_col2'></td></tr>");
    var canShip = true;
    var shipping = 0;
    for (var p in fc_json.products) {
      if (fc_json.custom_fields[fc_json.products[p].code+"_shipping"]) {
        shipping += (fc_json.custom_fields[fc_json.products[p].code+"_shipping"] * fc_json.products[p].quantity)
      } else {
        // No shipping attribute set for this product
        //canShip = false;
      }
    }
 
    if (canShip) {
      // Perform tasks here when shipping is possible
      jQuery("tr#fc_cart_foot_shipping .fc_col2").html("$" + currency_format(shipping));
      jQuery("tr#fc_cart_foot_total .fc_col2").html("$" + currency_format(shipping + fc_json.total_price));
    } else {
      // Perform tasks here when shipping isn't possible
      jQuery("tr#fc_cart_foot_shipping .fc_col2").html("TBA");
    }  
  });
//]]>
</script>

The script above loops through the products and calculates all of the shipping charges included for the added products. If any of the products doesn't have shipping charges specified, or if any other specific requirements are/aren't met, you can set a canShip variable to false and perform additional tasks like setting the total shipping value to “TBA” or whatever other logic you want to do. Otherwise it adds to total shipping for each product multiplied by its quantity to the total shipping table row, and also adds it to the cart total cost as well.

Step 4: Add javascript to your checkout template

<script type="text/javascript">
//<![CDATA[
  jQuery(document).ready(function() {
    var canShip = true;
    var shipping = 0;
    for (var p in fc_json.products) {
      if (fc_json.custom_fields[fc_json.products[p].code+"_shipping"]) {
        shipping += (fc_json.custom_fields[fc_json.products[p].code+"_shipping"] * fc_json.products[p].quantity)
      } else {
        // No shipping attribute set for this product
        //canShip = false;
      }
    }
    if (canShip) {
      // Perform tasks here when shipping is possible
      FC.checkout.config.orderFlatRateShipping = shipping;
      FC.checkout.updateShipping(-1);
    } else {
      // Perform tasks here when shipping isn't possible
 
    }
  });
//]]>
</script>

Step 5: Customise

This approach is fairly simplified, but it wouldn't take much to make this script much more powerful and robust. For example, you could specify other parameters in the product shipping attribute which triggers other functionality. Such as:

"We'll contact you for shipping"

If the shipping variable is set to “contact” rather than a number, set the canShip variable to false, and on the checkout hide live payment options and show the purchase order option, using this 'hiding the purchase order payment method' snippet to change it to match this purpose.

Shipping tiers or grouping

You could quite easily add tiers to the shipping attribute similar to how the coupon tiers are specified, and based on the quantity ordered per product, get the relevant tier in the javascript and charge accordingly. For example, the tiers could look like “1:10|5:12|10:15” which would say 1-4 products would be $10, 5-9 $12, 10+ would be $15.

You could also expand your management system to have group prices based on a FoxyCart category and in your add to cart form creation check to see if there is a flat rate for the products category or not, and use that instead if required.

Site Tools