Delivery only option

I was wondering if there were any examples out there of setting up the shipping as delivery only. This would involve limiting orders to certain zip codes, adding a minimum order dollar amount, and adding a delivery fee.

Any info / ideas would be much appreciated!
Comments
  • fc_adamfc_adam FoxyCart Team
    @blicht454,

    We don't have any specific examples that cover all of those aspects - but what you're wanting to do is possible.

    A large portion of it would be contained within this snippet: https://wiki.foxycart.com/v/2.0/snippets/flat_rate_shipping_modification

    You would us that snippet to set up custom shipping rates based on the customers address details.

    You could also make use of this snippet: https://wiki.foxycart.com/v/2.0/snippets/prevent_shipping_to_po_boxes - and alter it to instead check the order total and the postal code to show an alert when an incorrect postal code is entered or the minimum order amount hasn't yet been reached.

    That should help get you started - but if you're not familiar with javascript yourself or not working with a developer - we can give you some more guidance on getting that set up.
  • I am familiar with some Javascript but this seems a little advanced for me. Maybe a couple questions to get me started:

    1. In order to prevent orders that are less than $X from being processed, how would I modify the snippet you included for PO boxes? Or, even better, is there a way to make this happen on the Cart page before checkout? Maybe graying out the checkout box with a message that says something like, "You're order has not reached the minimum of $X for delivery."

    2. How can I use the same snippet for allowing only certain zip codes? The snippet that you sent is searching for the term "po box" but, in our case, there are so many zip codes that we won't accept and only a few that we will. How can we search from a small database of acceptable zip codes and allow only those?

    3. As for the flat rate shipping modification, I don't think we'll need this if we have the first two items working properly. We can just set a simple flat rate shipping fee called "delivery fee" and it will be the same for every order. My only question here is if there is any way to show this shipping fee in the cart page and the checkout page? Right now, shipping fees are only displayed on the checkout page.

    Thanks! I know this is asking a lot!
  • fc_jedfc_jed FoxyCart Team
    edited August 2015
    @blicht454

    I'll answer your questions one-by-one so that I could explain them in more detail.

    1. In order to prevent orders that are less than $X from being processed, how would I modify the snippet you included for PO boxes? Or, even better, is there a way to make this happen on the Cart page before checkout? Maybe graying out the checkout box with a message that says something like, "You're order has not reached the minimum of $X for delivery."

    Anything related to amounts are better suited for the flat rate shipping modification. However, for what you're describing, a custom javascript on your own page might be a better fit. This is a sample of how you could implement it:
    <script>
    var FC = FC || {};
    FC.onLoad = function () {
    var x = /* WHATEVER AMOUNT YOU WISH FOR $X */
    if (FC.json.total_item_price < x) {
    /* Code to gray out checkout box and display "Your order has not reached the minimum of $X for delivery." */
    }
    };
    </script>
    To be honest, I don't even think FC functions are necessary. Just gray out the checkbox using jQuery by using the conditional provided in the sample code.

    2. How can I use the same snippet for allowing only certain zip codes? The snippet that you sent is searching for the term "po box" but, in our case, there are so many zip codes that we won't accept and only a few that we will. How can we search from a small database of acceptable zip codes and allow only those?

    Try out this modification:
    <script type="text/javascript">

    var validatePO = function() {
    var addressString = $("#shipping_address1").val() + $("#shipping_address2").val();
    addressString = addressString.replace(/\./g,"");
    addressString = addressString.replace(/ /g,"");
    addressString = addressString.toLowerCase();
    if(addressString.indexOf('pobox') != -1) {
    alert("We can not ship to a PO Box shipping address. Please choose a different shipping address location.");
    return false;
    }
    else {
    return true;
    }
    }

    var validateZip = function() {
    var zip = $("#shipping_postal_code").val();
    // assuming that you have a zipcodes object that gets the data from your list of zip codes
    for(zipcode in zipcodes) {
    if(zip == zipcode) {
    alert("We can not ship to this zip code. Please choose a different shipping address location.");
    return false;
    }
    }
    return true;
    }

    var validateAddress = function() {
    return (validatePO() && validateZip()) ? true : false;
    }

    FC.client.on('customer-address-change', validateAddress);
    FC.client.on('checkout-submit', validateAddress);

    </script>
    This assumes that you have an array of zipcodes that gets from your database (perhaps using Ajax, or whatever method you prefer).

    3. As for the flat rate shipping modification, I don't think we'll need this if we have the first two items working properly. We can just set a simple flat rate shipping fee called "delivery fee" and it will be the same for every order. My only question here is if there is any way to show this shipping fee in the cart page and the checkout page? Right now, shipping fees are only displayed on the checkout page.

    You can show shipping fees by entering the zip code and clicking the Go! button, to calculate shipping.
  • fc_jedfc_jed FoxyCart Team
    @blicht454

    I've consulted with @fc_adam, and he suggested this for your first item instead:
    {% if context == 'cart' %}
    <script>
    $(document).on("click", ".fc-action--checkout--button, .fc-fixed-button-right .fc-btn-action", function(e) {
    var x = 5;
    if (FC.json.total_item_price < x) {
    alert("Your order has not reached the minimum of $"+ x +" for delivery.");
    e.preventDefault();
    }
    });
    </script>
    {% endif %}
    You would need to place that as a custom footer. That can be done going to your store admin's template configuration, checking Add custom header and footer code to your templates and pasting your code in the custom footer text area.
  • blicht454blicht454 Member
    edited September 2015
    @fc_jed

    So, it looks like that all works. Of course, it leads to more questions!

    It turns out that zip codes are not the best way to limit a delivery area. I'm hoping to simplify it further: what if I just required that ALL deliveries are to addresses with the city set as BOULDER, CO? I've tried to modify the javascript to make that work but with no success... Maybe something super simple like if(city == Boulder, CO) { alert(.....)?

    Also, a few other modifications come to mind:

    1. Maybe because I'm using flat rate shipping I'm getting the option to "Calculate taxes" by entering a zip code in the cart. However, once I enter a zip code and choose a city, it populates the city / state / zip under the "Shipping to..." line. Is there a way to change this to calculate delivery fee? (the delivery fee will actually be the same for all orders so it's really the flat rate shipping fee, just with a new label). And can we use this input to send the same error message if anyone is trying to get delivery to a city that is not BOULDER, CO?

    2. Is it possible to change the "Shipping to..." to "Delivery to..." in the shopping cart?

    3. Can the "Shipping & Handling" (flat fee) be changed to "Delivery Fee"? This shows up on the cart, checkout, and receipt templates.

    Thank you again for all your help!
  • fc_jedfc_jed FoxyCart Team
    @blicht454

    Sure, that can be done. So, instead of using the validateZip() function, replace that whole block with this:
    <script type="text/javascript">

    var validatePO = function() {
    var addressString = $("#shipping_address1").val() + $("#shipping_address2").val();
    addressString = addressString.replace(/\./g,"");
    addressString = addressString.replace(/ /g,"");
    addressString = addressString.toLowerCase();
    if(addressString.indexOf('pobox') != -1) {
    alert("We can not ship to a PO Box shipping address. Please choose a different shipping address location.");
    return false;
    }
    else {
    return true;
    }
    }

    var validateCityState = function() {
    var citystate = FC.json.shipping_address.city_option_selected;
    if(citystate != "BOULDER, CO") {
    alert("We can not ship to this city. Please choose a different shipping address location.");
    return false;
    }
    return true;
    }

    var validateAddress = function() {
    return (validatePO() && validateCityState()) ? true : false;
    }

    FC.client.on('customer-address-change', validateAddress);
    FC.client.on('checkout-submit', validateAddress);

    </script>
    Basically, I replace the validateZip() function with validateCityState(), also with every call.

    As for your questions, I'll answer them again one-by-one, so that I could further explain:

    1. Maybe because I'm using flat rate shipping I'm getting the option to "Calculate taxes" by entering a zip code in the cart. However, once I enter a zip code and choose a city, it populates the city / state / zip under the "Shipping to..." line. Is there a way to change this to calculate delivery fee? (the delivery fee will actually be the same for all orders so it's really the flat rate shipping fee, just with a new label). And can we use this input to send the same error message if anyone is trying to get delivery to a city that is not BOULDER, CO?

    You would have to use the Flat Rate Shipping Modification snippet, which, to be honest, would've made the shipping restriction a lot easier. All of the functions that were coded earlier would be part of the shipping logic instead of separate functions.

    To do that, you would have to revert back to the base Prevent PO snippet, and place the Flat Rate Shipping Modification snippet beneath that code. With validateAddress and validateCityState removed, insert this as the custom shipping logic:
    if(address.city == "Boulder" && address.state == "CO") {
    //WHATEVER CUSTOM FLAT RATE SCRIPT YOU WANT i.e. FC.customFlatRates.add(1, shippingCost, '', 'Standard Shipping');
    }
    Refer to the Flat Rate Shipping Modification link for more information on how to code the custom flat rates.

    2. Is it possible to change the "Shipping to..." to "Delivery to..." in the shopping cart?

    Go to your store admin's language settings, click on the Edit Details button beneath cart and look for "shipping to:". You can change the value to "Delivery to..." or whatever you prefer.

    3. Can the "Shipping & Handling" (flat fee) be changed to "Delivery Fee"? This shows up on the cart, checkout, and receipt templates.

    Same as above, look for "shipping and handling:" and change the value to whatever you prefer.
  • blicht454blicht454 Member
    edited September 2015
    @fc_jed

    Wow, thanks! All of this is working great. Just one last thing, if possible:

    The city verification works on the checkout page but is there a way to have it give the same message on the cart page when a user adds their zipcode, city, and state to calculate shipping?

    In other words, if someone enters a zipcode, city, and state in the Calculate Shipping box on the cart page where the city and state are NOT Boulder, CO, can we send an alert that says "We only deliver to Boulder..." AND prevent them from moving to the checkout page?
  • fc_jedfc_jed FoxyCart Team
    @blicht454

    Can you whisper me your store domain? I don't know why I haven't asked before. Are you currently working with a developer? If not, we could recommend a list of developers who have worked with FoxyCart extensively.

    Did you end up using the Flat Rate Modification Snippet? If so, you could just re-paste the previous snippet beneath the other existing snippets but modify it to only check for the city and state since you already have the prevent shipping to PO in place.
    <script type="text/javascript">

    var validateCityState = function() {
    var citystate = FC.json.shipping_address.city_option_selected;
    if(citystate != "BOULDER, CO") {
    alert("We only deliver to Boulder...");
    return false;
    }
    return true;
    }

    FC.client.on('customer-address-change', validateCityState);

    </script>
  • blicht454blicht454 Member
    edited September 2015

    @fc_jed

    I'm not sure if the whisper worked so let me know if you didn't get the url. But here's the rest of the message:

    I have that snippet in the Flat Rate Modification Snippet. And it works fine on the checkout page. But it's not working on the Cart page. When I add a zip code in the "Calculate Shipping" field (which I've changed to "Do we deliver to you?", I can enter any zip code / city / state and there's no alert telling me that we only deliver to Boulder, CO. It also allows me to proceed to checkout no matter what I've entered there. I'd like the same message to come up if someone enters a zip code that doesn't correspond to Boulder, CO.

    Let me know if you have any ideas.

    Thanks!
  • fc_jedfc_jed FoxyCart Team
    @blicht454

    Sorry for the delayed response, I was out the whole weekend. I did receive the whisper, thanks for that information. Okay, so that we have a baseline, the first step I want you to do is remove all the custom code that we've discussed in this thread, in your store admin's configuration and in your native js. This should be done to ensure that there wouldn't be any duplicate code, as I've seen that you have a few duplicate code in the link you provided.

    Replace the code in your custom footer with this: http://pastie.org/private/wsvt0w9uqs6dbcbghepsrg

    Replace your custom javascript click handler with this:
    <script>
    $(document).on("click", ".fc-action--checkout--button, .fc-fixed-button-right .fc-btn-action", function(e) {
    var is_invalid = false;
    var x = 100;
    if(FC.json.total_item_price < x) {
    alert("Your order has not reached the minimum of $"+ x +" for delivery.");
    is_invalid = true;
    }
    if(FC.json.shipping_address.city != "Boulder" && FC.json.shipping_address.region != "CO") {
    alert("We only deliver to Boulder. Please choose a different delivery address location.");
    is_invalid = true;
    }
    if(is_invalid) {
    e.preventDefault();
    }
    });

    </script>
    Let us know if we missed any of your requirements.
  • @fc_jed

    Thanks for the response. For the most part, that's working really well. There's still one big issue though:

    The address verify on both the cart page and checkout page only works once. Meaning that if I enter a city other than Boulder, CO, I get the error message "We only deliver to Boulder...". But when I close that error message and enter a new zip code / city, it can be anything and I'm not given the message again, even if it's not Boulder, CO. The same is true on the checkout page. I'm given the alert once but I can still finish the checkout even if the address doesn't match Boulder, CO.

    I'm wondering how we can make sure that the user can't proceed unless the city matches Boulder, CO. Do you have any ideas?

    Also, please make sure I've placed the custom code properly in the footer. I'm hoping that the mistake isn't coming from that!

    Thank you again!
  • fc_jedfc_jed FoxyCart Team
    @blicht454

    Thank you for that detailed replication steps. Unfortunately, I've re-tested that script for all your conditions and it works as expected on my end. Could you provide links and concrete values, including test accounts so that I could investigate on your store?

    Also, you have an error that is preventing the sidecart from appearing. You might want to address that:
    Uncaught ReferenceError: fcc is not defined
    Specifically, for this line:
    fcc.events.cart.process = new FC.client.event();
    The return false; for the is_invalid condition ensures that the checkout should not go through. Perhaps you can log to the console what its value is so that we'll know why it's failing.

    PS Good thinking for the Customize whitelist/blacklist filtering of countries and regions restriction, that adds a level of security for restricting non-Colorado zip codes.
  • fc_jedfc_jed FoxyCart Team
    @blicht454

    It actually defaults to the Full-page cart if the FC loader.js doesn't load correctly, which is more of a connection-javascript issue.

    Are you sure that you included this code in your site's javascript?
    <script>
    $(document).on("click", ".fc-action--checkout--button, .fc-fixed-button-right .fc-btn-action", function(e) {
    var is_invalid = false;
    var x = 100;
    if(FC.json.total_item_price < x) {
    alert("Your order has not reached the minimum of $"+ x +" for delivery.");
    is_invalid = true;
    }
    if(FC.json.shipping_address.city != "Boulder" && FC.json.shipping_address.region != "CO") {
    alert("We only deliver to Boulder. Please choose a different delivery address location.");
    is_invalid = true;
    }
    if(is_invalid) {
    e.preventDefault();
    }
    });

    </script>
    The old javascript of FoxyCart should be removed from your site, as there's no need for it. There's an uncaught type exception when clicking Add to Cart, so you might want to address that as well. Getting rid of javascript errors would definitely narrow down our search for a resolution.
  • @fc_jed

    Yeah, that snippet is in the footer, in the "Custom shipping logic" of the flat rate modification. Should it go somewhere else?

    And I've tried to eliminate any javascript errors but the only one I notice looks like it's relative to the sidecart. I'm seeing "undefined is not a function" and unless I'm mistaken, it looks like it's coming from the javascript to pull up the sidecart.

    I'm not sure exactly what is going on but there are a lot of pieces not working now:

    1. The sidecart works only sometimes, maybe 50% of the time. I can't tell why this is happening.

    2. The zip code validation doesn't work on the cart or checkout page. I can input anything and it lets me move forward.

    3. I just caught this: if I edit the contents of my cart on the checkout page, I can go lower than the set minimum and it still allows me to complete the checkout. (I don't get the error message "amount in cart is less than..."

    I'm a little lost here. Do you know why this is so glitchy?
  • fc_jedfc_jed FoxyCart Team
    @blicht454

    It seems that you placed the click handler code inside the custom logic. Do not place that there, instead place it it your own site's javascript. I apologize if there was confusion there. "Custom shipping logic" which is inside the flat rate shipping modification snippet should be placed in the custom footer, while the click handler should be placed in your own site.

    When I said to copy the code snippet in the earlier pastie, I meant to copy it as is and not make any further customization. Please follow the instruction here and see if that resolves your issue: https://forum.foxycart.com/discussion/comment/53906/#Comment_53906
  • @fc_jed

    Sorry for the confusion there. I had definitely misunderstood that.

    Unfortunately, that only solved the issue for the minimum order. The address / city validation isn't working at all. I can enter any address (as long as it's in Colorado, because that's taken care of in the whitelist / blacklist) and the order is still allowed to move forward and process.
  • fc_adamfc_adam FoxyCart Team
    @blicht454,

    Actually - we've just spotted the issue there. We had a small issue in the javascript that was causing it to incorrectly let Colorado cities through other than Boulder like you were seeing.

    You'll need to update both of the scripts.

    Firstly - on your own website replace the script with this: http://pastie.org/private/ugg3rt1hbl5mrstmgsuq

    Next, in your store's configuration section, update the footer code in its entirety to this: http://pastie.org/private/xpzxhdh2h2ibbfb2xl5qeg

    Once doing that, you should see it correctly catching those orders. I've also adjusted the script to combine the three different alerts into a single alert - so the user won't get bombarded with multiple alerts if they fail multiple conditions.
  • @fc_adam

    It looks like that did the trick! And nice idea to combine the alerts into a single alert.

    Just FYI, I needed to change the city in both snippets to all uppercase (BOULDER) in order for the city to match the format in the cart / checkout page. It was sending the alert "We only deliver to Boulder..." otherwise.

    Unless you know of a way to make this not case sensitive?

    Thanks for all the help!
  • fc_adamfc_adam FoxyCart Team
    @blicht454,

    Yes there is - look for this line in both the code you pasted on your own site and in the custom configuration:

    if ((FC.json.shipping_address.city != "" && FC.json.shipping_address.city != "Boulder") || (FC.json.shipping_address.region != "" && FC.json.shipping_address.region != "CO")) {

    And change it to this:

    if ((FC.json.shipping_address.city != "" && FC.json.shipping_address.city.toLowerCase() != "boulder") || (FC.json.shipping_address.region != "" && FC.json.shipping_address.region.toLowerCase() != "co")) {

    That code will convert both the city and region to always be lowercase - so you will catch whatever case they're in.
Sign In or Register to comment.