Automate Everything w/ Bash, Linux & Command Line
  1. Magento: Automatically Apply a Coupon Code w/ jQuery

    I started working on planning a promotion a couple of days ago that would require a discount to be applied automatically. The site runs on Magento, which has very sophisticated coupon code and discounting tools. But this time, none of the built in options quite suited my needs.

    tl;dr; - I needed to apply a coupon code to a customer’s cart, before they actually had anything in their cart and without the visitor doing anything more than visiting a specific landing page. I was able to accomplish my goal with a little creativity, jQuery and determination. And, I don’t know PHP so this is a front end solution using jQuery and cookies. Read on for the code and how it works…

    How to Setup a Discount in Magento

    The first thing you’ll need to do is setup a coupon code with an associated discount of some type in Magento. It doesn’t really matter what type of coupon it is, you just need something to test with. I’m not going to explain how to do that here but for demonstration’s sake, I’ll assume that the coupon code you’ve chosen is testcouponcode and it gives the customer 20% off.

    Don’t be confused. Even though we’re setting up a coupon code, we’re not going to require any action from the visitor. We’re just going to use the back-end coupon capabilities of Magento to do the discounting in the shopping cart.

    Before we go any further, make sure you manually test the coupon code you setup by going into the cart and applying it the old fashioned way. Trust me that if you made a mistake, it’s much easier to discover and correct it at this stage.

    A Few More Notes About Coupons in Magento

    • When the customer enters a coupon code and clicks the apply coupon button, the code makes a HTTP POST to /checkout/cart/couponPost/ with the following data - remove=0&coupon_code=testcouponcode.
    • A coupon code cannot be applied to the shopping cart if there are no items in the visitor’s cart.
    • In my case, if the customer doesn’t checkout during the same session then I don’t want the discount to apply.

    With those three things in mind, let’s dive into how I’ve solved this problem.

    “Apply” Discount on the Landing Page, well Kinda…

    Remember the introduction - I want to apply a discount based on the landing page. However, in Magento, this is technically impossible. You cannot apply the coupon code to trigger the discount right away on the landing page. Since it’s the first page your visitor will have hit, the visitor will have zero items in their cart and that’s the problem.

    No worries though, there’s a way around that. All you have to do is create a session cookie that can be referenced if the visitor does end up putting items into his/her cart. The trigger will be the same (the landing page), but applying the discount will be technically deferred.

    To make the order of events easy to understand, here’s a list:

    1. Visitor hits the special landing page.
    2. Javascript on the page sets a special session cookie, signifying that a discount should be applied once an item has been added to the cart. This cookie will automatically be deleted when the session ends.
    3. Once the visitor views his/her cart (and there are one or more items in it), Javascript on the shopping cart page will make a POST to apply the coupon code that was specified back on that special landing page. This POST will happen in the background and then refresh the page quickly.

    Pretty simple right? Based on those three events, there will be two different blocks of code needed to make this work. One needs to be on the landing page and the other needs to be on the shopping cart view page.

    jQuery for the Landing Page

    Remember that the only goal for the code on this page is to set a session cookie that can be read and referenced later. I’m a newb when it comes to Javascript and for most things I use jQuery. Unfortunately there’s no built in way to write or read cookies in jQuery. The good news is that there’s a really great plugin for it and using the plugin is as easy as downloading it and including it in the HTML of your site. You can get it here, hosted on Google Code.

    Here’s the code:

    <script type="text/javascript" src="/path/to/js/jquery.cookies.2.2.0.min.js"></script>
    <script type="text/javascript">
        jQuery.cookies.set('nameOfCookie', 'testcouponcode', '/');
    </script>
    

    It’s really simple. All you have to do is name the cookie, give it a value and set the path that the cookie should be valid for. Setting a path of / means that it can be read or modified anywhere on the domain. I recommend making the value of the cookie equal to the actual coupon code. It’s most simple that way and I don’t think there’s any reason to try to hide it.

    Once you’ve downloaded the cookies plugin and included this code on your page, it’s a good idea to load the page and inspect your cookies to make sure the cookie was actually set. If it was, move on to the next step.

    jQuery for the Shopping Cart View Page

    This is the code you’ll need to put on the cart view page. The simplest way to implement this is to put it just before the closing <body> tag on the cart view page.

    <script type="text/javascript">
        var emptyCart = jQuery('.cart-empty').text();
        if ( (emptyCart == "") ) {
            jQuery.getScript('/path/to/js/jquery.cookies.2.2.0.min.js', function() {
                var couponCode = jQuery.cookies.get('nameOfCookie');
                if ( (/../i.test(couponCode)) && (!!couponCode) ) {
                    var postData = "remove=0&coupon_code=" + couponCode;
                    jQuery.post("/checkout/cart/couponPost/", postData, function() {
                        jQuery.cookies.del('nameOfCookie');
                        document.location = '/checkout/cart/';
                    });
                };
            });
        };
    </script>
    

    If you cannot add code to this page, you can place it in a file and include it in the head of the page. If you do that though, you’ll want to slightly modify it to execute after the page load is complete. You’ll also want to make sure that it only executes on the /checkout/cart/ page. It would look something like this…

    window.onload = function() {
        var emptyCart = jQuery('.cart-empty').text();
        if ( (/\/checkout\/cart\//i.test(page)) && (emptyCart == "") ) {
            jQuery.getScript('/path/to/js/jquery.cookies.2.2.0.min.js', function() {
                var couponCode = jQuery.cookies.get('nameOfCookie');
                if ( (/../i.test(couponCode)) && (!!couponCode) ) {
                    var postData = "remove=0&coupon_code=" + couponCode;
                    jQuery.post("/checkout/cart/couponPost/", postData, function() {
                        jQuery.cookies.del('nameOfCookie');
                        document.location = '/checkout/cart/';
                    });
                };
            });
        };
    };
    

    Here’s a quick explanation of what the code does:

    1. If you remember, a coupon code cannot be applied to a cart if there aren’t any items in the cart. The first part of the script grabs the text from the headline with a class equal to .cart-empty and it’s stored in the variable emptyCart.
    2. The following IF statement checks to make sure the emptyCart variable is empty. If it isn’t empty then that means the cart is empty and the rest of the code should not execute. If you used the second version, there’s also a condition that makes sure that the current document is the cart view page.
    3. Next, we need to make sure that the jQuery cookies plugin has been loaded.
    4. After the cookie plugin has loaded, the variable of couponCode gets set to the value of the coupon code from the landing page.
    5. Then there’s another IF statement that checks to see if a coupon code exists.
    6. If the coupon code does exist, then the next part makes a POST to /checkout/cart/couponPost/ with a query string equal to remove=0&coupon_code=testcouponcode which will actually activate the discount for the customer’s shopping cart.
    7. If that POST is successful, the cookie gets deleted and the page refreshes. The refresh is needed to let the customer see the discount in the sub-total. It’s unfortunate that the page refresh is necessary. I just haven’t been able to figure out a way to get around it. If you know how, please feel free to comment.

    I hope this has been helpful. Now, go forth and rockout some new landing pages!