Submit a request

How to add a discount to the cart by clicking a link

Follow

Comments

16 comments

  • Avatar
    John Lenertz

    It looks like adcodes can be linked to discount codes but not campaign coupon codes. I want to make campaign codes linkable so I can tell the customer: Get 10% OFF YOUR ORDER with coupon XYZ and make that coupon code clickable or allow the customer to assign manually.

  • Avatar
    Kathy Sechrist

    I want an adcode to double as a coupon code. This worked in the old admin fine, but not in the new one. If it's not a strict rule, I could probably do this (adcode or coupon code), but if I am trying to limit the discount to a product, category, manufacturer, etc. I can only do adcode or a coupon code, but not both. (If I create separate rules for each, customer could possibly double their discount by clicking the link then typing the coupon code).

    Also, because adcodes don't double as coupon codes, and there is no way to enter an adcode in the order entry screen, my CSR can no longer type in adcodes when taking phone orders.

  • Avatar
    Jeremy Roberts

    I agree with John and Kathy. A discount applied from an adcode link must not permit any other discount or coupons to stack. Adcodes for discounts are essentially useless in the real world if a coupon can be stacked on top of it. Why not make the adcode "discount" a "coupon"? We are basically hijacking the adcode and using it for something it wasn't really designed to do, right? What we need is an incoming link that can assign a coupon. Everyone agree? Please vote early and often: http://vote.americommerce.com/forums/25843-feature-ideas/suggestions/7175762-adcode-needs-option-to-apply-discount-as-coupon-n

  • Avatar
    Bryan D.

    This is a workaround that I just developed tonight. It uses the incoming link to assign a coupon code using some JQuery. See below:

    I'm going to post some script here, I hope it works! My jquery knowledge isn't the best, so someone may have a better method than I have found to do this. However, this is working for the time being:

    In your Theme Editor, add this to your cart:
    <script>
    function getUrlParameter(sParam)
    {
    var sPageURL = window.location.search.substring(1);
    var sURLVariables = sPageURL.split('&');
    for (var i = 0; i < sURLVariables.length; i++)
    {
    var sParameterName = sURLVariables[i].split('=');
    if (sParameterName[0] == sParam)
    {
    return sParameterName[1];
    }
    }
    }

    var homeadcode = getUrlParameter('a');
    var cartdc = getUrlParameter('dc');
    
    if ( homeadcode == 'vcpop' && cartdc == 'vchallenge' ) {
      $(function(){
    
        $("#ctl26_txtCouponCode").val("vokechallenge");
        $('#ctl26_btnAddCoupon').click();
    
      });     
    }
    

    </script>

    What does this do? This checks for URL parameters that you pass to your cart and then assigns them to a variable. So in my case, it checks for the URL paramter 'a=' and also 'dc='. I use these for redundancy, and because using 'a=' allows me to track the adcode as well!

    After storing those in a variable, it uses the 'IF' statement to check what those variables are equal to. I have them passed along as 'a=vcpop' and 'dc=vchallenge' in my URL, and then stored as the variables homeadcode and cartdc.

    Next from your theme editor, you need to get the DIV ID's for both the Coupon Code Box as well as the 'Add Code' button, which you can see above as "#ctl26_txtCouponCode" and "#ctl26_btnAddCoupon", respectively. The last part of the Jquery auto-populates the coupon code and then submits it for you.

    For reference, here is a snippet of my custom URL to make this work:
    blah .com/store/addtocart.aspx?itemid=69&qty=1&a=vcpop&dc=vchallenge

    The disadvantages are that you need a special link with these values in it, and also it causes the page to refresh. However, those are both relatively minor considerations in comparison to the multiple discount codes the adcode can provide!

  • Avatar
    Jeremy Roberts

    Bryan D., this is pretty awesome.
    We are working with a new affiliate program manager, and he wants us to lose the coupon code box entirely. All discounts would be fired by an adcode in an incoming link, ?a=discountcode
    BUT.
    We also want to offer all new customers a $5 coupon code via email -- and we occasionally want to offer a "coupon" code -- so this solution could be what we need.
    I tested and your script worked exactly as represented - but only for one coupon code.

    Beyond my skillset, but... what would be awesome is the same functionality, without having to preset an adcode/dc in the script.

    IF the link is:
    blah .com/store/addtocart.aspx?itemid=69&qty=1&a=anyAdCode&dc=couponname

    would it be possible to set a variable, dc=couponname
    insert couponnamevariable into $("#ctl26_txtCouponCode").val("couponnamevariable");

    The page reload is not a deal buster, but it would be cooler without.

    ANYONE reading this know how to do this?

  • Avatar
    Bryan D.

    Hi Jeremy, you can set a variable to do whatever you want no problem.

    Modify the script to this:

    var homeadcode = getUrlParameter('a');
    var cartdc = getUrlParameter('dc');

    if ( homeadcode == 'vcpop' && cartdc == 'vchallenge' ) {
    $(function(){

    $("#ctl26_txtCouponCode").val("whatever1");
    $('#ctl26_btnAddCoupon').click();
    

    });

    }

    if ( homeadcode == 'vcpop' && cartdc == 'vchallenge2' ) {
    $(function(){

    $("#ctl26_txtCouponCode").val("blahblah2");
    $('#ctl26_btnAddCoupon').click();
    

    });

    }

    if ( homeadcode == 'vcpop' && cartdc == 'random3' ) {
    $(function(){

    $("#ctl26_txtCouponCode").val("coupon3");
    $('#ctl26_btnAddCoupon').click();
    

    });

    }

    Maybe you missed the first part of my script? The first part of the script does exactly what you are looking for. It pulls the URL parameters, see how it asks for the cartdc variable?

    var homeadcode = getUrlParameter('a');
    var cartdc = getUrlParameter('dc');

    function getUrlParameter(sParam)
    {
    var sPageURL = window.location.search.substring(1);
    var sURLVariables = sPageURL.split('&');
    for (var i = 0; i < sURLVariables.length; i++)
    {
    var sParameterName = sURLVariables[i].split('=');
    if (sParameterName[0] == sParam)
    {
    return sParameterName[1];
    }
    }
    }

    Basically, test.com/?a=whatever&dc=whatever2 uses the URL Parameter function to populate the variables "homeadcode" and "cartdc". These are then automatically checked for their content into the second script.

    I think it already does whatever you are asking for? Just place "dc" with whatever coupon code you want and ensure that you are using the URL Parameters function as well.

    As far as sending it without the page refresh, I don't think that works. I've tried to understand the POST logic a little bit from AC to see if I could hack it with AJAX but no success so far.

  • Avatar
    Jeremy Roberts

    Hi Bryan D.,

    Thank you - this is a FANTASTIC contribution to the AC community.
    It looks like I have to add all possible inbound coupon codes to the script, right? So if I have 6 possible adcode/coupon codes, all 6 must be in the script.

    WHAT I was hoping to do - apply a new coupon code without having to edit the script... I tried to find a way to grab the couponcode (as a variable) and then replace the target coupon code val -- but this didn't work.

    $("#ctl26_txtCouponCode").val('cartdc');
    [probably because the val is trying to set the exact code, not the variable]

    Basically, is it possible for the coupon code that is in the link, to become the val of the code that is replaced by $("#ctl26_txtCouponCode").val('link_dc=couponcode');
    ?

    THAT would be sweet. And then simplify the if to simply
    if ( homeadcode == 'testing123' ) {

    so that if any link looked like:

    blah .com/store/shopCart.aspx?a=testing123&dc=newcouponcode

    then coupon code newcouponcode would be set, without needing to edit the script.

    This will permit my customer service team to make coupon codes for customers, and send them links, without going near the template or script. THAT would be super cool if possible, but beyond my jquery skill right now.

    But for now, I will limit the inbound coupon code links.
    THANK YOU for coming up with this!

  • Avatar
    Jeremy Roberts

    Bryan D., this is working great on the cart page -- EXCEPT...
    The link to the dc=code MUST be on the shopping cart page

    I tried moving the script to the footer, so that it is on all pages, and that did not work.
    If we are going to offer an inbound link to an empty shopping cart, that doesn't work either.

    WHAT IF we want to offer an inbound coupon code (similar to an adcode) so that the coupon is loaded from the first page load? Is this possible with this script?

  • Avatar
    Bryan D.

    Hi Jeremy, pretty tired last night and wasn't thinking straight! I believe that putting in the coupon code from the link directly would work. The reason I didn't initially was a security reason, I didn't want the coupon code directly in the URL. If someone wanted it, they could find it by reading the sourecode on the page but that was a lesser concern. Since you can't type in coupon codes for your team, it shouldn't matter. For us it was a different situation.

    It certainly shouldn't be a problem just storing the coupon code into a variable and then populating the rest of the script. Then you wouldn't need every one listed in the if/then statements:

    <script>
    function getUrlParameter(sParam) {
    var sPageURL = window.location.search.substring(1);
    var sURLVariables = sPageURL.split('&');
    for (var i = 0; i < sURLVariables.length; i++) {
    var sParameterName = sURLVariables[i].split('=');
    if (sParameterName[0] == sParam) {
    return sParameterName[1];}}}

    var cartdc = getUrlParameter('dc');

    $(function(){
    $("#ctl26_txtCouponCode").val(cartdc);
    $('#ctl26_btnAddCoupon').click(); });

    </script>

    I condensed the script. I think that the syntax should work, but you will need to test for errors. You should be able to call the variable in the .val(variable) function and then using the "getUrlParameter('dc')" it will populate the cartdc variable and should call it in the function. Try it out!

    I thought a little bit about your second question this morning. I believe the easiest way to do this would be to set a simple session cookie with the js-cookie Jquery plugin (https://github.com/js-cookie/js-cookie) :

    Call the js-cookie file in your header, then script into your header-

    function getUrlParameter(sParam) {
    var sPageURL = window.location.search.substring(1);
    var sURLVariables = sPageURL.split('&');
    for (var i = 0; i < sURLVariables.length; i++) {
    var sParameterName = sURLVariables[i].split('=');
    if (sParameterName[0] == sParam) {
    return sParameterName[1];}}}

    var cartdc = getUrlParameter('dc');

    $(function(){Cookies.set('coupon', cartdc); });

    ////Then in the page for your cart (don't put it in the header, put a script into your themes cart page) -

    $(document).ready(function(){
    

    var couponcode = Cookies.get('coupon'); //I think this should work

    $(function(){
    $("#ctl26_txtCouponCode").val(couponcode);
    $('#ctl26_btnAddCoupon').click(); });

    });

    ///This should, if I'm thinking correctly, strip the name of the coupon code you want from the URL that you use to get to the site using the UrlParameters function and add it to the cartdc variable. Then you use the cartdc variable to set a coupon code cookie for the session. On the cart page, you read the coupon code cookie into a new variable and pass it into the function that applies it to the cart.

    I have done NO testing on this, so you will have to do it but I think it should work with some playing around. This could probably be condensed quite a bit but it was the quickest/easiest way for me to write it out.

  • Avatar
    Jeremy Roberts

    Hi Bryan,
    Wow. Awesome contributions here. Thank you.
    I quickly tested the
    .val(variable) function (to use the coupon code from the link without forcing it into the script)

    $(function(){
    $("#ctl26txtCouponCode").val(cartdc);
    $('#ctl26btnAddCoupon').click();
    });

    and that did not work. but the original idea worked, if code inserted into script...

    if ( homeadcode == 'adcodetest5' && cartdc == 'couponcode5' ) {
    $(function(){

        $("#ctl26_txtCouponCode").val('couponcode5');
        $('#ctl26_btnAddCoupon').click();
    
      });     
    }
    

    Hmm... gonna try to debug later. Thanks.

  • Avatar
    Jeremy Roberts

    Kinda frustrated :-(
    Setting the cookie - works using /js-cookie, but the cookie does not preserve beyond first page -- default is supposed to stay active for entire session -- but it's not... doing it like this:

    <!-- set cookie for coupon code -->
    <script>
    function getUrlParameter(sParam) {
    var sPageURL = window.location.search.substring(1);
    var sURLVariables = sPageURL.split('&');
    for (var i = 0; i < sURLVariables.length; i++) {
    var sParameterName = sURLVariables[i].split('=');
    if (sParameterName[0] == sParam) {
    return sParameterName[1];}}}

    var cartdc = getUrlParameter('dc');

    $(function(){Cookies.set('coupon',cartdc); });
    </script>

    And this does not preserve past the first page load.
    I tried adding an expires parameter, { expires: 2 } no change.

    I spent hours on this. :-(
    I verified that the session is not changing.
    Gonna look for a different/better way to set a cookie.

  • Avatar
    Jeremy Roberts

    I tried a different cookie script:
    https://github.com/stefangabos/Zebra_Cookie/
    no difference... the cookie_value does not preserve when going to a different page.
    Could there be something in the
    function getUrlParameter(sParam) {
    ?

    PS -- to show the coupon code field (this link is for our customer service or to give to a customer for special circumstances) use this:

    <!--[ac] show coupon code input IF url contains ?showcouponcode - /store/shopCart.aspx?showcouponcode -->
    <script>
    $(function () {
    if (document.location.href.indexOf('showcouponcode') > -1) {
    $('#dvCouponCode').show();
    }
    });
    </script>

  • Avatar
    Jeremy Roberts

    This is turning into a fun project -- but driving me up the wall -- it is just complicated enough to be a PITA!

    1. working backwards... I solved the apply parameter as variable to the coupon function:

    var dc = getUrlParameter('dc');
    console.log(dc); // added a console log to see what was happening in real time

    if ( typeof dc != 'undefined' ) { // this is to prevent an undefined dc firing the coupon code
    $(function () {
    $("#ctl26_txtCouponCode").val(dc); // val(variable) is now working this way
    $('#ctl26_btnAddCoupon').click();
    });
    }

    HOWEVER - 2 things:
    a) still does the extra page load (as you said, we can live with this);
    b) IF a customer tries to game the system and edits the URL parameter and inserts a coupon code that does not exist, this triggers an endless loop with a "not a valid coupon code" error. So there is some logic to the original idea of placing the permitted dc codes into the script, to prevent malicious or inadvertent dc code entires. IF the dc code is not exactly a permitted couponcode, then the script will not anything. I think we have to do this, right?

    I used a slightly different script to extract the URL parameter:

    // =================
    var getUrlParameter = function getUrlParameter(sParam) {
    var sPageURL = decodeURIComponent(window.location.search.substring(1)),
    sURLVariables = sPageURL.split('&'),
    sParameterName,
    i;

    for (i = 0; i < sURLVariables.length; i++) {
        sParameterName = sURLVariables[i].split('=');
    
        if (sParameterName[0] === sParam) {
            return sParameterName[1] === undefined ? true : sParameterName[1];
        }
    }
    

    };
    // =================

    1. NOW I'm gonna try to solve the cookie thing... one thing I was noticing on the shopping cart page: when the coupon code is applied, the variable 'dc' reset to undefined in the console log. Hmm. Gonna try again and I will report back asap.
  • Avatar
    Jeremy Roberts

    OK. I think I figured out why the cookie is getting reset to undefined on every page load...
    The script is trying to write a new cookie based on whatever is in the dc variable on every page load. And the script only knows the variable for the current page with the URL parameter.
    We need to trap the Cookies.set function to only write the cookie if there is a valid (not undefined) URL parameter.

    //only set cookie if variable is not undefined
    if ( typeof dc != 'undefined' ) {
    Cookies.set('couponcode',dc);
    }
    //now we're cooking with gas

    //And then on the shopping cart page:
    var cc = Cookies.get('couponcode');
    console.log(cc);

    if ( typeof cc != 'undefined' ) { //don't try to set coupon code if there isn't one to set
    $(function () {
    $("#ctl26_txtCouponCode").val(cc);
    $('#ctl26_btnAddCoupon').click();
    });
    }
    </script>

    // BUT THIS CAUSES an infinite loop on the shopping cart when the page reloads. The cookie keeps reloading and shopping cart page keeps reloading with the "new" coupon code.
    // ugh

    I tried using the
    one() event binding method
    http://www.sitepoint.com/create-one-time-events-javascript/

    but that prevented the coupon code from doing the (unexplained) page reload in the first place. Hmm...

    This may beyond my skillset. :-(
    Can you spot the loop and how we can prevent it?

  • Avatar
    Jeremy Roberts

    BINGO.
    I hired a js coder on Fiverr to help me sort out the page reload...
    (we were actually VERY close)

    I am going to include the ENTIRE solution here, fully commented. I hope this helps someone in the future. If anyone identifies a better way to accomplish any of this, please don't hesitate to share!!! Bryan, THANK YOU for getting this as far as you did!!!!!

    WHAT THIS DOES:
    a) Sets a coupon code from a url parameter by writing a cookie;
    b) This permits using an adcode based discount (using url parameter a=adcode IN ADDITION TO the coupon code (for a stacked discount offering);
    c) Coupon code is set on the shopping cart page from the cookie, which can be set on any page with the URL parameter

    1. Hide the coupon code input field on the shopping cart page and one page checkout

    Shopping Cart
    FIND:
    <div id="dvCouponCode" class="ShoppingCartCouponCode">

    REPLACE WITH:
    <div id="dvCouponCode" class="ShoppingCartCouponCode" style="display:none;">

    // (don't use the class, hide, since deputy writes this as !important)

    for one page checkout, find
    <ac:visibilityarea id="CouponCodeArea">
    and comment the entire CouponCodeArea out

    1. Install js-cookie plugin to head tags
      https://github.com/js-cookie/js-cookie

    2. In your footer, add this script - this parses the url parameter and sets a cookie, 'couponcode'

    <!-- footer on all pages -->
    <!-- parse parameter(s) from url -->
    <script>
    var getUrlParameter = function getUrlParameter(sParam) {
    var sPageURL = decodeURIComponent(window.location.search.substring(1)),
    sURLVariables = sPageURL.split('&'),
    sParameterName,
    i;

    for (i = 0; i < sURLVariables.length; i++) {
        sParameterName = sURLVariables[i].split('=');
    
        if (sParameterName[0] === sParam) {
            return sParameterName[1] === undefined ? true : sParameterName[1];
        }
    }
    

    };

    // set variable 'dc' from url parameter
    var dc = getUrlParameter('dc');

    // log the variable 'dc' for development only
    console.log(dc);

    // if the dc var is NOT undefined, set cookie, 'couponcode'
    if ( typeof dc != 'undefined' ) {
    Cookies.set('couponcode',dc);
    }

    </script>
    <!-- END footer on all pages -->

    1. Now the good part... On your Shopping Cart Page, I created a widget area for scripts...

    ABOVE:
    <div class="center">
    $$EMPTYCARTMESSAGE$$
    $$CONTINUESHOPPINGBUTTON$$
    </div>

    INSERT:
    <ac:widgetarea id="scripts">
    </ac:widgetarea id="scripts">

    Then go make a widget in your new scripts widget area...
    widget type: Custom HTML

    <!-- read cookie and set the coupon code -->
    <script>
    // get the cookie and assign to var cc
    var cc = Cookies.get('couponcode');

    // log the var cc for development
    console.log(cc);

    // make certain the var cc is not undefined
    if ( typeof cc != 'undefined' ) {

    // assign the value (val) of the CouponCode from the var cc
    $(function() {
    $("#ctl26_txtCouponCode").val(cc);

    // click the add coupon code button, but only one page reload
    // this is the secret sauce
    var ccset = window.localStorage.conf;
    if(ccset == 'couponcodeset' )
    console.log('couponcodeset');
    else
    $('#ctl26_btnAddCoupon').click();

    window.localStorage.conf = 'couponcodeset';

    });
    }
    </script>

    1. Done.

    so let's say your inbound url is:
    domain .com/?dc=testing123

    testing123 is your coupon code and it will be written to the cookie, 'couponcode'

    when your customer gets to the shopping cart, the coupon code, 'testing123' will now be stored.

    A FEW NOTES:
    a) If a crafty customer decides to test various coupon codes by changing the url parameter, once the first code is set in the cart, the script prevents further reloads to the coupon code (but the crafty customer could clear cookies and try again).

    b) If crafty customer tries to use a non-valid coupon code in the url parameter, it fires the "Coupon Code is not recognized" error. And it will be stuck there... THE WORKAROUND for us is to have a script to show the coupon code box fired by a url parameter...

    Make another custom html widget in the shopping cart scripts area:

    <!--show coupon code input IF url contains ?showcouponcode -->
    <script>
    $(function () {
    if (document.location.href.indexOf('showcouponcode') > -1) {
    $('#dvCouponCode').show();
    }
    });
    </script>

    Now, admin (or crafty customer when they call in frustrated) can simply append

    ?showcouponcode

    to the shopping cart url
    domain .com/store/shopcart.aspx?showcouponcodeand
    and the coupon box will appear.

    Wow.
    Bryan, THANK YOU THANK YOU for the inspiration to accomplish this.

    This technique, combined with using adcodes to fire other discounts, is INCREDIBLY POWERFUL and will make merchandising better.

    PLEASE -- if anyone has a better way to solve this, please, please share.

  • Avatar
    Placeholder Sales #1

    Dang. Nice work, guys!

Please sign in to leave a comment.