The Foxy forums are on the move!

We're in the process of moving our forums over to a new system, and so these forums are now read-only.
If you have a question about your store in the meantime, please don't hesitate to reach out to us via email.

Multiple Flat Rate Shipping

mathyoomathyoo Member
in Bugs & Feature Requests edited May 2010
I've been digging through the forums and wiki and have found some discussion about multiple flat rates and other custom shipping options, but I haven't seen anything that I'm looking for. I need to have 4 standard flat rates of shipping:

Local Delivery (free)
Standard Delivery (8.00)
Express Delivery (14.00)
International Delivery (17.00)

But nothing I've seen helps with just setting up several flat rate options. Everything I've seen seems to be conditional on number of items, weight, country, etc., but nothing about just creating a pull-down menu with flat rate options. Anyone know of a resource for that?
«1
Comments
  • fc_adamfc_adam FoxyCart Team
    edited May 2011
    [Edit to add] An updated version of this script is available here: http://wiki.foxycart.com/v/0.7.0/shipping/customizations#multiple_custom_flat_rate_shipping_options. I'd suggest using the updated script over the one detailed in this thread.

    - - - - - - - - - - - - - - - - - - - - - -

    Hey mathyoo,

    This one got me a little too excited and I spent a good whack of time working on this solution, which in essence is completely piggybacking on the structure and functionality that live rates has. So based on the information you provided above:

    1) Set the shipping methods for all your product categories to be shipped with a flat rate, with a value of $0

    2) Paste the following in the head of your checkout template:
    <script type="text/javascript" charset="utf-8">
    	  //<![CDATA[
        $(document).ready(function() {
          $("input[name=shipping_service]").click(function(){
            shipping_service_description = jQuery(this).siblings(".fc_shipping_carrier").html();
    				shipping_service_description += ((shipping_service_description == "") ? '' : ' '); 
    				shipping_service_description += jQuery(this).siblings(".fc_shipping_service").html(); 
            $("#shipping_details").val(shipping_service_description);
            // Launch FoxyCart functionality
            FC.checkout.updatePrice(-1);
          });
        })
    	  //]]>
    	</script>
    

    3) ...and paste this just below the
    ^^checkout^^
    
    tags in the checkout template:
    ^^custom_begin^^
        <h2>Shipping Options</h2>
        <div class="fc_row fc_shipping_methods_container" id="fc_shipping_methods_container">
        	<div class="fc_radio_group_container fc_row fc_shipping_methods" id="fc_shipping_methods">
    				<input type="hidden" value="0" id="shipping_service_id" name="shipping_service_id">
    				<input type="text" style="display:none;" value="" id="shipping_service_description" name="shipping_service_description">
    				<input type="text" value="" id="shipping_details" name="Shipping_Details" style="display:none;" />
        		<div class="fc_shipping_methods_inner" id="fc_shipping_methods_inner">
        		  <label for="shipping_service_local" class="fc_radio">
        		    <input type="radio" class="fc_radio fc_required" value="local|0.00" id="shipping_service_local" name="shipping_service" />
        		    <span class="fc_shipping_carrier">PostBox</span>
        		    <span class="fc_shipping_service">Local Delivery</span>
        		    <span class="fc_shipping_cost">Free</span> 
        	    </label>
        	    <label for="shipping_service_standard" class="fc_radio">
        		    <input type="radio" class="fc_radio fc_required" value="standard|8.00" id="shipping_service_standard" name="shipping_service" />
        		    <span class="fc_shipping_carrier">PostBox</span>
        		    <span class="fc_shipping_service">Standard Delivery</span>
        		    <span class="fc_shipping_cost">$8.00</span> 
        	    </label>
        	    <label for="shipping_service_express" class="fc_radio">
        		    <input type="radio" class="fc_radio fc_required" value="express|14.00" id="shipping_service_express" name="shipping_service" />
        		    <span class="fc_shipping_carrier">PostBox</span>
        		    <span class="fc_shipping_service">Express Delivery</span>
        		    <span class="fc_shipping_cost">$14.00</span> 
        	    </label>
        		  <label for="shipping_service_international" class="fc_radio">
        		    <input type="radio" class="fc_radio fc_required" value="international|17.00" id="shipping_service_international" name="shipping_service" />
        		    <span class="fc_shipping_carrier">PostBox</span> 
        		    <span class="fc_shipping_service">International Delivery</span> 
        		    <span class="fc_shipping_cost">$17.00</span> 
        	    </label>
        	  </div>
        		<label style="display: none;" class="fc_error" for="fc_shipping_methods">Please select a shipping method.</label>
        	</div>
        </div>
        ^^custom_end^^
    

    Quick code explanation: The structure for the shipping options is taken completely from the structure of live rates, so all the css ids/classes and the inputs that are needed are all their, so the default functionality works like it does for live rates (ie: automatically adds the shipping rates when you click an option, throws an error if none are selected and someone tries to checkout...). The first bit of javascript that you put in the head is to add the selected shipping choice to a text box that is passed through to the receipt and email so that you can easily see which shipping option they chose.

    Important to note: I only really tested this in Firefox, and was jumping between this and a couple other things, so you'll need to test, test test!
  • Awesome! Thanks so much-it looks perfect so far! I'll test it in multiple browsers to be sure, but so far it looks terrific.
  • lukeluke FoxyCart Team
    Awesome work Adam!

    Worth noting, this is not technically supported stuff so please upgrade with caution and if you haven't already, vote for super ship on our requests page. Also, the shipping information may not show up correctly in receipts and in the admin history when using custom tweaks like this.
  • This is a very helpful post -- thank you. The technique here is applicable to situations that go beyond just shipping options.

    However, I can't seem to make this work. I've set up the simplest possible implementation: I'm using the default sample code for a simple product, and I'm using the default templates except for the modifications mentioned for the checkout template. When I progress to the checkout page, it's blank (nothing... no html tags whatsoever). Same behavior in FF and Safari.

    Any ideas? Thanks.
  • fc_adamfc_adam FoxyCart Team
    Can you post your template from the admin into a pastie?
  • Whoops. Got it working. I had nuked the rest of the template while inserting the custom bits. My bad.
  • Ok, this works in Firefox, but when go through the process of adding the sample product to my cart and clicking over to the checkout page in Safari, I end up on the OLD version of the template with full blown CSS/HTML customizations. Even if I log into the FoxyCart admin and chose to use the FoxyCart standard template and save it, Safari still is somehow using an old version of the template that should have been destroyed. I've cleared Safari's cache. What's going on? Any ideas?

    Safari 4.0.5 on Mac OS 10.4.11
  • lukeluke FoxyCart Team
    Can you provide a link so we can take a look?
  • Hi this is a great, I really only have one question. Could someone show me how to have it calculate based on quantities? I am doing a flat rate for domestic (US) shipping and a flat rate for international shipping. I want to provide a 50% discount for every item on top of the 1st that is ordered, so for instance flat rate of $4 for first domestic item and $2 per item after that.

    Can anyone help me?

    Thanks so much!
  • fc_adamfc_adam FoxyCart Team
    Hey wattssw, do you have anything setup on your checkout currently? It's easier to work off of what you've got setup if you do.
  • wattsswwattssw Member
    edited December 2010
    Hi, thanks for the reply. I followed the instructions above with just small changes to step 3:

    1) Set the shipping methods for all your product categories to be shipped with a flat rate, with a value of $0

    2) Paste the following in the head of your checkout template:
    <script type="text/javascript" charset="utf-8">
    //<![CDATA[
    $(document).ready(function() {
    $("input[name=shipping_service]").click(function(){
    shipping_service_description = jQuery(this).siblings(".fc_shipping_carrier").html();
    shipping_service_description += ((shipping_service_description == "") ? '' : ' ');
    shipping_service_description += jQuery(this).siblings(".fc_shipping_service").html();
    $("#shipping_details").val(shipping_service_description);
    // Launch FoxyCart functionality
    FC.checkout.updatePrice(-1);
    });
    })
    //]]>
    </script>

    3) ...and paste this just below the ^^checkout^^ tags in the checkout template:

    ^^custom_begin^^
    <h2>Shipping Options</h2>
    <div class="fc_row fc_shipping_methods_container" id="fc_shipping_methods_container">
    <div class="fc_radio_group_container fc_row fc_shipping_methods" id="fc_shipping_methods">

    <input type="hidden" value="0" id="shipping_service_id" name="shipping_service_id">
    <input type="text" style="display:none;" value="" id="shipping_service_description" name="shipping_service_description">

    <input type="text" value="" id="shipping_details" name="Shipping_Details" style="display:none;" />

    <div class="fc_shipping_methods_inner" id="fc_shipping_methods_inner">
    <label for="shipping_service_local" class="fc_radio">
    <input type="radio" class="fc_radio fc_required" value="local|4.99" id="shipping_service_local" name="shipping_service" />
    <span class="fc_shipping_carrier">Standard</span>
    <span class="fc_shipping_service">U.S. Domestic</span>
    <span class="fc_shipping_cost">$4.99</span>
    </label>

    <label for="shipping_service_international" class="fc_radio">
    <input type="radio" class="fc_radio fc_required" value="international|14.99" id="shipping_service_international" name="shipping_service" />
    <span class="fc_shipping_carrier">Standard</span>
    <span class="fc_shipping_service">International (Outside U.S.)</span>
    <span class="fc_shipping_cost">$14.99</span>
    </label>

    </div>
    <label style="display: none;" class="fc_error" for="fc_shipping_methods">Please select a shipping method.</label>
    </div>
    </div>
    ^^custom_end^^
  • fc_adamfc_adam FoxyCart Team
    Thanks @wattssw. I'll try to run over this in the next couple days. If you don't hear from me in a couple days, feel free to bump this thread.
  • wattsswwattssw Member
    edited December 2010
    Hello, any chance to consider this?

    Again, what I want to do is: A flat rate for 1 item domestic and a flat rate for 1 item international. Then, on multiple items, it will be the flat rate for the first item and 50% of the flat rate for each additional item.

    Thanks in advance.
  • fc_adamfc_adam FoxyCart Team
    @wattssw, sorry about that, and thanks for bumping the thread. Replace the second step code with this, and you should be good to go - you'll just need to adjust the 4 variables within this code, which allows you to specify what the cost is for the first product, and each subsequent product for both local and international.

    http://pastie.org/private/ivqyckektzztminiex9daw
  • Hello, thanks for the response. I followed the instructions but it isn't working correctly, still only yielding the flat rate for a single item no matter how many are being ordered. I believe I need to alter the code in Step 3 as well. I have made the changes, which you can see via the website at http://healthiswealth.net/index.php?/store

    My revised Step 2 Code:

    <script type="text/javascript" charset="utf-8">
    //<![CDATA[
    $(document).ready(function() {
    $("input[name=shipping_service]").click(function(){
    shipping_service_description = jQuery(this).siblings(".fc_shipping_carrier").html();
    shipping_service_description += ((shipping_service_description == "") ? '' : ' ');
    shipping_service_description += jQuery(this).siblings(".fc_shipping_service").html();
    $("#shipping_details").val(shipping_service_description);
    // Launch FoxyCart functionality
    FC.checkout.updatePrice(-1);
    });

    var localFirst = 4.99;
    var localRest = 2.99;
    var intlFirst = 15.99;
    var intlRest = 7.99;

    if (fc_json.product_count >= 1) {
    var localShipping = localFirst + (localRest * (fc_json.product_count - 1));
    var intlShipping = intlFirst + (intlRest * (fc_json.product_count - 1));
    jQuery("#shipping_service_local").val("local|" + localShipping).siblings(".fc_shipping_cost").html("$" + FC.formatter.currency(localShipping));
    jQuery("#shipping_service_international").val("international|" + intlShipping).siblings(".fc_shipping_cost").html("$" + FC.formatter.currency(intlShipping));
    }
    })
    //]]>
    </script>


    And my Step 3 code which I believe needs an alteration (the value of the radios?):

    ^^custom_begin^^
    <h2>Shipping Options</h2>
    (Note: Shipping prices for 1st item. Shipping on additional items varies.)
    <div class="fc_row fc_shipping_methods_container" id="fc_shipping_methods_container">
    <div class="fc_radio_group_container fc_row fc_shipping_methods" id="fc_shipping_methods">

    <input type="hidden" value="0" id="shipping_service_id" name="shipping_service_id">
    <input type="text" style="display:none;" value="" id="shipping_service_description" name="shipping_service_description">

    <input type="text" value="" id="shipping_details" name="Shipping_Details" style="display:none;" />

    <div class="fc_shipping_methods_inner" id="fc_shipping_methods_inner">
    <label for="shipping_service_local" class="fc_radio">
    <input type="radio" class="fc_radio fc_required" value="local|4.99" id="shipping_service_local" name="shipping_service" />
    <span class="fc_shipping_carrier">Standard </span>
    <span class="fc_shipping_service">U.S. Domestic</span>
    <span class="fc_shipping_cost">$4.99</span>
    </label>

    <label for="shipping_service_international" class="fc_radio">
    <input type="radio" class="fc_radio fc_required" value="international|15.99" id="shipping_service_international" name="shipping_service" />
    <span class="fc_shipping_carrier">Standard </span>
    <span class="fc_shipping_service">International (Outside U.S.)</span>
    <span class="fc_shipping_cost">$15.99</span>
    </label>

    </div>
    <label style="display: none;" class="fc_error" for="fc_shipping_methods">Please select a shipping method.</label>
    </div>
    </div>
    ^^custom_end^^


    Again, I really appreciate your help.
  • fc_adamfc_adam FoxyCart Team
    edited December 2010
    Hey,

    The code should be fine as you posted, but its just a placement issue. If you move the code from step 2 to be right before the
    </head>
    
    rather than right after the
    <head>
    
    and that should get it working.

    [edit to add] I should also explains how this works. Basically, when the page loads, the script will look at how many products are in the cart, and adjust those flat rate shipping values according to how many products there are. So if there is 3 products, it will add the first product price with 2 times the subsequent price and update the price automatically. So you're customers won't see anything different, they'll just see the correct shipping price.
  • Hey thanks so much, this works perfectly! I really appreciate your help and I hope my question can assist someone in the future.

    Best regards,
    Stephen
  • Is this post still the recommended way to handle multiple flat-rate shipping options? Or does 7.1 have something new that obsoletes this?
  • fc_adamfc_adam FoxyCart Team
    At this point, yeah - this is still the way to go.
  • randomboyuk1randomboyuk1 Member
    edited May 2011
    Hi Adam.

    Hope that you're well.

    Question A.
    I've successfully integrated the multiple shipping options onto a site - but there are a few different categories of product. Some that get posted (where we needed the different shipping options) and others that are workshops (that don't need any shipping options. Although the workshop category is set up to not need shipping - the script is still called when checking out a workshop. Can you recommend a way that I could resolve this?

    Question B.
    Is it possible (and if so how) to force a shipping option depending on the total value of the items in the basket?

    Many thanks for your help.

    All the best
    James
  • mathyoomathyoo Member
    I have this successfully integrated, but my client wants to add a coupon code for free shipping. I've tried the javascript hack in the wiki, but it doesn't work if you have multiple flat rate shipping. Any ideas?
  • fc_adamfc_adam FoxyCart Team
    @James & @mathyoo,

    Could you both post your questions as new threads? While they relate to multiple flat rates, its different enough to this thread to warrant its own thread.
  • I'm working on the flat rate shipping described here: http://wiki.foxycart.com/v/0.7.0/shipping/customizations#multiple_custom_flat_rate_shipping_options

    I'm using the flat rate shown in example 1 and the international/domestic part shown in example 2.

    Here is my code:

    var postage = 0;
    var country_code = (jQuery("#use_different_addresses").is(":checked") ? $("#shipping_country").val() : $("#customer_country").val());
    if (country_code == "US") {
    addShippingOption(1, 3.96, 'USPS', 'Economy');
    addShippingOption(2, 8.57, 'USPS', 'Priority Mail');
    addShippingOption(3, 17.91, 'UPS', '2 Day');
    addShippingOption(4, 36.93, 'UPS', '1 Day');
      } else {
    addShippingOption(5, 19.50, 'USPS', 'International Priority');
    addShippingOption(6, 25.91, 'UPS', 'Worldwide Express Saver');

    }


    The domestic shipping options are working, but the problem is that it isn't changing over to the international shipping options when I put in another country. Any ideas what I'm doing wrong here?
  • fc_adamfc_adam FoxyCart Team
    @JRasmussen,

    So the reason it's not updating on change is that the function isn't actually being called whenever the country field updates. Try something like this:

    * Pull your code above out into its own function, like:
    function myShippingRules() {
    removeCustomShippingContainer(); // This call will make sure that when it updates, it starts fresh.
    
    // Your code in here
    }
    

    Where your custom code is now, replace it with this:
    myShippingRules();
    FC.checkout.overload("updatePriceDisplay", "myShippingRules", null);
    
    .

    As an overview, the last part of the first script block of the javascript will look like this:
    /* BEGIN CUSTOM SHIPPING LOGIC */
    myShippingRules();
    FC.checkout.overload("updatePriceDisplay", "myShippingRules", null); 
        /* END CUSTOM SHIPPING LOGIC */
      });
    
    function myShippingRules() {
    ...
    }
    
  • fc_adam,

    The reply to @JRasmussen is timely. I've found the same problem.
    Namely, Example 2 presumably can never work where a customer changes the country.
    I implemented your solution but this result in addShippingOption running with each click of the Radio button to confirm the shipping option.
    And due to the Append
    jQuery("#fc_shipping_methods_inner").append(newShippingOption);

    Resulted in 2 radio button shipping options. Then another click resulted in 4 buttons and so on.
    Changing the country from my default UK to US resulted in the 4 UK shipping options and 2 new International buttons.

    So I had a go by replacing append with replaceWith
    jQuery("#fc_shipping_methods_inner").replaceWith(newShippingOption);

    Works better but instead of the Radio button duplicating it is reformed with each click and thus remains in the unchecked state.
    Otherwise the functionality is good.

    But with an uncheckable Shipping option button Confirm your Order sends a warning - "Please select a shipping method".

    Can you think of a better alternative for replaceWith? I assume a check to see if the #fc_shipping_methods_inner has any contents and remove them instead (I'm replacing the wrong thing as things stand).
    Probably replace (if it exists) <label for="shipping_service_X but how best to achieve this?

    Stuart
  • fc_adamfc_adam FoxyCart Team
    edited August 2011
    @Stuart,

    Oh man, good catch. I hadn't considered that! Give this a try instead:

    Using the code as it stands on the wiki for the multiple flat rates, not the steps I detailed above for @JRasmussen, paste this in the custom code section: http://pastie.org/2317006

    @JRasmussen, I'd suggest updating your code to this as well, to get aroudn the issue that @Parthian found above.

    [edit to add] I also updated the wiki instructions to update that last example with this code too.
  • ParthianParthian Member
    edited August 2011
    fc_adam,

    Spotted a little flaw. Changing the country resulted in the postage to the previous country, always one step behind.

    So I moved the country_code = new_country_code from the bottom to the top.
    This as I'm doing several tests of country_code. I test for GB then a set of European Countries ELSE Rest of the World. To give three postal rates.

    if (country_code != new_country_code) { // The shipping country has changed!
    country_code = new_country_code;

    Thus running the country tests on the new country.
    I looked for the code changes in the wiki. Don't appear to be there.
    http://wiki.foxycart.com/v/0.7.1/shipping/customizations#multiple_custom_flat_rate_shipping_options

    Completing the Form
    The logic of when a Postal change occurs is slightly unpredictable. E.g. Default at UK, Changing to US requires the City AND State, then the code fires to change the postage. Quite clever, helps with accuracy. Without an epic of coding up each State/District in the world. Seems fine.
    For other countries it appears that just the Country needs to change, perhaps as long as there is something in the State/Province field (can be any text).
    Sound about right?

    It got me thinking, what if a person (particularly when shipping as a gift to another country) doesn't know the state/district. Also, it looks like the postcode is required to 'Confirm Order' so people who don't know the postcode or don't have one in their country may run into problems. Is this likely?

    A fake State and/or postcode is probably worse than a blank one. I found entering a space 'fools' the error handling. Which is handy. Maybe this could be added to the error messages for these fields? Or perhaps Paypal or other Payment Gateways will get upset?


    Stuart
  • Thought I'd add my code to detect European Countries.

    Can't claim that it is 100% and some postal rates may vary but from the UK there appears to be one rate for all of these countries.
    I Think!

    } // Madera and Azores? - Canary Islands? from http://en.wikipedia.org/wiki/European_Union_Value_Added_Tax
    else if ( country_code in { AT:1, BE:1, BG:1, CY:1, CZ:1, DK:1, EE:1, FI:1, FR:1, DE:1, GR:1, HU:1,
    IE:1, IT:1, LV:1, LT:1, LU:1, MT:1, NL:1, PL:1, PT:1, RO:1, SK:1, SI:1, ES:1, SE:1, GI:1 } ) {

    May be useful to someone.
  • fc_adamfc_adam FoxyCart Team
    @Parthian,

    Good catch with new new_country_code vs country_code! I've update the script on the wiki. I've also removed that one you linked to, as the code now lives in our snazzy snippet library here: http://wiki.foxycart.com/snippets/shipping/multiple_flat_rates (Well actually I didn't remove it, just changed it to link to the snippet library instead)

    In terms of the checkout, the town, state and postcode fields are all required fields. Can you think of an example where someone doesn't have a postcode?
  • Adam

    I searched for - countries without postcodes (maybe postal codes).
    Found a list but quite old.
    There are about a dozen countries which don't have them. Usually, African or small islands.
    Ireland apparently only code postcodes in 2008.

    Something to consider.

    Regarding Snippet Library.
    When researching FC stuff I'm forever finding old articles which look nearly identical to newer.
    How about a style change to the background colour of the 0.60 - 0.70, 0.7.1 and snippets wikis. Perhaps getting redder the older they get... Warning, this code is old.
    I think that some of the wiki doesn't exist in 0.7.1 such that there is no choice but to go to older versions. Not sure about that.
    Either way, I get confused.
Sign In or Register to comment.