type:
snippet
category:
Misc cart and checkout
name:
Product Upselling on the cart/checkout
versions:
0.6.0, 0.7.0, 0.7.1, 0.7.2, 1.0
reference:
http://forum.foxycart.com/comments.php?DiscussionID=2361&page=1
tags:
Advance, Snippets, cart and checkout, upsell
date:
2011-06-02

Product Upselling on the cart/checkout

There are a lot of different ways to approach upselling on the cart or checkout, but the following provides a basic way to achieve this on both the cart and checkout with the same script. The idea is pretty simple: Have an add to cart link or form that redirects the customer straight back to where they were (cart or checkout) through the add to cart action. This script adds in some niceties to help anyone set this up.

The following steps apply exactly the same whether you're adding it to the cart or the checkout. Note that if you're wanting to add this functionality to both pages, you will need to add and customise this script on both templates

Step 1: Add your products

Add the following to your template wherever you'd like the upselling options to appear either above or below the default FoxyCart placeholders like ^^cart^^ and ^^checkout^^.

<div id="upsell" style="display:none;">
 
</div>

It is within the above div that you add in your add to cart links or forms as you normally would, and anything else that is displayed as part of your upselling promotion. So for example, this could be an excerpt of your cart template:

...
<body>
  <div id="upsell" style="display:none;">
    <h3>We think the following might interest you too...</h3>
    <div class="upsell" id="box">
      <h4>This is a really cool shirt</h4>
      <a href="https://YOURSTORE.foxycart.com/cart?name=Cool%20Box&price=10&color=red">Add a red Cool Box</a>
    </div>
    <form class="upsell" id="shirt" action="https://YOURSTORE.foxycart.com/cart" method="post" accept-charset="utf-8">
      <input type="hidden" name="name" value="Cool Shirt" />
      <input type="hidden" name="price" value="10" />
      <label class="label_left">Size</label>
      <select name="size">
        <option value="small">Small</option>
        <option value="medium">Medium</option>
        <option value="large">Large</option>
      </select>
      <input type="submit" name="Add a Cool Example" value="Add a Cool Shirt" class="submit" />
     </form>
  </div>
  ^^cart^^
</body>
...

There are a couple rules to this layout though.

  1. The container div needs to have an id of “upsell” and we'd suggest giving it a style of “display:none”.
  2. Each individual product needs to have a class of “upsell” and an id that is unique for that product across the whole template either directly on the link or form or on a parent element. For an example of this, in the above code, the form for the “Cool Shirt” has the class and id applied directly to it, where as the link for the “Cool Box” is within a div that has the settings. If you have the class and id applied to a parent element around the link or form, you can also include other elements inside the parent element like images and text which will be hidden or shown along with the link or form.

Step 2: Add the javascript

Add the following javascript right before the closing </head> tag in the template:

<script type="text/javascript">  
  storedomain = "YOURSTORE.foxycart.com"; 
 
  jQuery(document).ready(function() {
    initUpSell();
 
    /* BEGIN CUSTOM UPSELL LOGIC */
 
 
 
    /* END CUSTOM UPSELL LOGIC */
 
  });
 
  function initUpSell() {
    jQuery("#upsell,.upsell").hide();
    total_upsell = (fc_json.custom_fields.upsell) ? parseInt(fc_json.custom_fields.upsell) : 0;
    var params = "&h:upsell="+(total_upsell + 1);
    var inputs = '<input type="hidden" name="h:upsell" value="'+(total_upsell + 1)+'" />';
    var href = window.location.href;
    if (href.match("/checkout")) {
      params += "&cart=checkout";
      inputs += '<input type="hidden" name="cart" value="checkout" />';
    } 
    if (fc_json.session_id) {
      params += "&fcsid="+fc_json.session_id;
      inputs += '<input type="hidden" name="fcsid" value="'+fc_json.session_id+'" />';
    }
    jQuery('a.upsell, .upsell a[href*="' + storedomain + '"]').each(function() {
      jQuery(this).attr('href', jQuery(this).attr('href') + params);
    });
    jQuery('form.upsell, .upsell form[action*="' + storedomain + '"]').each(function() {
      jQuery(this).prepend(inputs);
    })
  }
 
  function showUpSell(uid) {
    jQuery("#"+uid).show();
    showHideUpSell();
  }
 
  function hideUpSell(uid) {
    jQuery("#"+uid).hide();
    showHideUpSell();
  }
 
  function showAllUpSell() {
    jQuery(".upsell").show();
    showHideUpSell();
  }
 
  function hideAllUpSell() {
    jQuery(".upsell").hide();
    showHideUpSell();
  }
 
  function showHideUpSell() {
    var show = false;
    jQuery(".upsell").each(function() {
      if (jQuery(this).css('display') != 'none') { show = true; }
    });
    (show) ? jQuery("#upsell").show() : jQuery("#upsell").hide();
  }
</script> 

Once you've got it pasted, update the 'storedomain' variable at the top of the script to match your FoxyCart domain.

Step 3: Customise the upsell products

Now the fun part, based on whatever criteria you want, add in the different upsell options your customers can see. Add your custom code between the /* BEGIN CUSTOM UPSELL LOGIC */ and /* END CUSTOM UPSELL LOGIC */ lines in the javascript block. There are four functions available to you.

showUpSell()
Description: Displays an upsell option.
Parameters: upsellID
Example: showUpSell('shirt');
hideUpSell()
Description: Hides an upsell option.
Parameters: upsellID
Example: hideUpSell('shirt');
showAllUpSell()
Description: Shows all upsell options.
Parameters: none
Example: showAllUpSell();
hideAllUpSell()
Description: Hides all upsell options.
Parameters: none
Example: hideAllUpSell();

There is also a variable set called total_upsell which contains how many upsells the customer has add so far to their cart. This is useful in situations where you don't want to show any upsells after a customer has added one, or show different products after the customer has added an upsell already.

Example

  1. 6 upsell products in a store selling tickets to a concert: 3 different variations of glow sticks in one div, 3 merchandise in another div
  2. The merchandise only displays if there isn't any merchandise products in the cart and only if they haven't added any upsells yet
  3. The glowsticks displays if they have added an upsell or if they already have merchandise in their cart.
var hasMerch = false;
for (p in fc_json.products) {
  if (fc_json.products[p].category == "Merchandise") {
    hasMerch = true;
  }
}
if (!hasMerch && total_upsell == 0) {
  showUpSell("merch");
} else if (hasMerch || total_upsell > 0) {
  showUpSell("glowsticks");
}

Tips & Tricks

  • By having the same code on both your cart and checkout, and by utilising the total_upsell variable, you can present a series of upsells throughout the checkout flow, but never double-up on your products displayed.
  • When styling your upselling products, use the id of #upsell to restrict to just the upsell container.
  • The parent upsell div is hidden whenever there is no upsell's currently visible, and shown when there is. In this way, you can add headings, text and images to that div outside of your actual products, and it should only be displayed when an upsell product is available to add to the cart.
  • When adding the upsell to the cart, take into consideration that when a handful of products have been added to the cart, any upsell's you have at the bottom of the cart might be hidden outside of the modal viewport, requiring the user scroll down to see them.

What does this script do?

  1. Finds all the elements with the class of upsell that are a form or link (either the element or contained inside the element) and adds a session variable to increase the total_upsell, the fcsid and if its the checkout the cart=checkout parameter to redirect the customer back to the checkout
  2. Sets the current total_upsells to its variable
  3. Whenever a function is called to show or hide an upsell, it checks to see if there are some visible and if there are, shows the parent div with an id of upsell. If there isn't it hides it.

Site Tools