Simple Coupon Field

RevConceptRevConcept Member
in Help edited May 2012
Want to add a simple coupon field.

Clients want to run a promo with a single coupon code. If a shopper enters the correct code they will upgrade them to second day shipping. I don't need this to reflect anywhere in the product or shipping prices, the client will be handling this. All I want to do is add a single text input field to capture the promo code and let shoppers know if it's accepted or denied....but obviously I don't want the field to be "required".

The field would then pass onto the various confirmation emails so the store owners know who to upgrade (it would even be ok for an invalid code to pass through I guess, because they can make the distinction of valid promo codes on their own).

Trying to rush this since it's a promo running for Mother's Day. Suggestions?

One more question: What is the best method for testing things like this when the site is live? I obviously don't want to change the checkout template prior to testing. Thanks!
Comments
  • lancelance Member, Community Support Member
    edited May 2012
    @RevConcept -

    There are two possibilities that come to mind.

    1) You can create a coupon with a discount string of 1-0.01. This is a valid coupon that can be added to the cart and will give a discount of one penny. You can name it Shipping Upgrade and then it will be clear when it is present in the cart. Of course, it does require that a penny discount be offered.

    2) Unfortunately, a FoxyCart coupon code can't be used if it has no value. You can create a coupon code using a discount string of 0-0 or 1-0 and apply it, but the fact that you have used it on the order is not shown anywhere. If you really don't want to offer a discount, you could "self-host" the "Add a Coupon" field and have users enter the code in the store (client's server) and handle the validation logic on your end. If it is valid, you can add a custom, hidden field to the cart indicating that the coupon is present. This hidden field will be available in your XML datafeed or the transaction details in the FC back-end.

    Will one of these work for you?

    Lance


  • @lance -

    Number 2 sounds pretty decent...although I'm no wizard with figuring out how I would implement that, ha!

    I have no problem with running a simple test (unrelated to foxyshop on the client's server) to see if the text in the input field is equal to the discount code we want to use. I'm not even so much concerned about "validating" their entry...nor do I care if this has anything to do with actual "coupons". I just think it would be nice to let the customer know in some way that what they entered was a correct/incorrect promo code. From the shop owners side I just need it to show up in plain text...could even be a "note" on the order. Thoughts??

    - Chris
  • lancelance Member, Community Support Member
    Chris,

    Depending on whether or not you care about internet savvy users being able to find a code in your source, you could theoretically do all of this via JavaScript / jQuery. Check this out:

    http://pastie.org/3846601

    This assumes you have a code called "moms" and if they enter it correctly it will automatically add a hidden field to the cart that IDs it as having upgraded shipping and alerts them the code is valid. The button would look like this:
    <input type="text" size="20" id="ship-code" />
    <button id="ship-code-button" value="click">Click</button>
    

    Might that work?

    Lance
  • I think that might be perfect. The store owners don't really care, they just want the shoppers subscribed to their email updates to have an incentive, it will be a short-run on this promo anyway. Anyone who would think to use "view source" or the like in this situation can have a reward for their efforts ;) THANK YOU! I'll followup if I have additional questions related to this.

    Side Question: What is your method for testing changes like this on a live site? I don't typically deal with ecommerce, so I've never had to work/test on "sensitive" pages like the checkout.
  • lancelance Member, Community Support Member
    Chris,

    Your best bet would be to have a staging server where you can test everything. Barring that, you can always deploy something like this on a "hidden" page that only you have access to before you add it to the whole site.

    The button I've provided will need to go on your client's site rather than in the cart or on the checkout page. You might be able to get something up and running on the checkout page, but given that it sounds like you're looking for a quick turnaround, I think this is the best option for the time being.

    You can also do a lot of testing using Firebug if you're familiar with that. That impacts only your local environment without risking anything remotely.

    Lance
  • I actually just spent the last couple of hours setting up a local testing server on my Mac and threw in the site's WP database. I also created an additional demo store account through foxycart to use with it. Not sure if this method is perfect...but it seems to be running everything and will probably come in handy with request like this in the future.

    I will play with some options tomorrow and try to post back what method I used for anyone else looking for something like this.

    Thanks so much for your help and super quick responses!

    - Chris
  • fc_adamfc_adam FoxyCart Team
    Worth noting, starting from version 0.7.2 all coupons that have been added to the cart, whether they affect the cart or not, are displayed in the cart listing. So if you're on the latest version of FoxyCart you could utilise the normal coupon entry system for this to work.
  • sparkwebsparkweb Member, Integration Developer, FoxyShop, Order Desk
    Also remember that if you are using a local testing server and have the SSO stuff turned on, it will be hitting your live site for the SSO check, not the testing server. Probably not a big deal, but something to consider.
  • lancelance Member, Community Support Member
    Ah that's an interesting note, @fc_adam. Thanks for that, I wasn't aware of that change (obviously).
  • @sparkweb...thanks! It's off right now, but we used it last weekend and it seemed to work perfectly. Thanks again so much for that great solution!

    @fc_adam - I spent some time last night coming up with a solution that I think may work...if not, then I will look into that.

    What do you guys think of this? Not sure if this is going to negatively effect something, but it seems to be working on my test server:

    1. I added the following to my checkout template in fc_custom_fields:
    <input type="text" name="coupon" id="coupon" value="" />
             <script type="text/javascript">
                  var coupon = new LiveValidation('coupon', { validMessage: 'Valid Code', wait: 500});
    	      coupon.add(Validate.Format, {pattern: /^mom$/i, failureMessage: "Invalid Code" } );
    	</script>
    

    2. I uploaded the following JS to my server and called it in the checkout template header: http://kpmaclane.com/wp-content/themes/kp_maclane/scripts/live-validate.js

    3. I cached my template within FoxyCart admin. I didn't get any warnings etc.

    4. When I test this, it simply lets me know if the promo code I enter is good or not (in real time). Once I submit my order, the promo code is sent through as additional information and shows on receipt page / shop owner email / customer email.

    Thoughts???
  • fc_adamfc_adam FoxyCart Team
    @RevConcept - if it works for your needs and you've tested that it works, then that's great!

    One gotcha with that approach - as I think Lance posted earlier, as the actual code is included in your javascript then it is possible for someone to get the correct code by viewing the source code of the page. If that's not an issue for you, then that's ok.
  • @fc_adam In this situation, we are okay with that.

    One more question: is there a way to remove the data passed in fc_custom_fields from the receipt page and the confirmation email the shoppers receive? I only want the info to show for the store owners.

    Thanks!
  • lancelance Member, Community Support Member
    Chris,

    Do you want to remove the data entirely, or would you be satisfied just to hide it on the receipt page? You can easily hide anything you want on the receipt page by using CSS.

    If you can whisper a link to a receipt page and provide an idea of what you want to accomplish, I can point you in the right direction.

    Lance
  • I think I can hide it with CSS and perhaps edit the email template to remove that too. XHTML and CSS are my friends...it's javascript and the like that I have trouble with ;)
  • I can't seem to remove the custom fields from the email template. There is a placeholder of ^^receipt^^ spitting out an unordered list with no inline css to designate one list item from the next. Any way around this?

    - Chris
  • lancelance Member, Community Support Member
    Chris,

    Can you whisper me a link to a receipt?

    Lance
  • lancelance Member, Community Support Member
    So, if the promo code is valid, are you happy to have it display on the receipt email? If so, then clearing invalid codes would work to ensure you only have valid codes coming through.

    If code validation fails, you could always just use this:

    $('#coupon').val("");

    This will clear the entered value.

    Lance
  • That would be great. I don't care if the custom field shows up as long as it's valid...it just wouldn't make sense to have a line in the receipts that says "Coupon: Some Invalid Code".

    I tried to use what you pasted above, but it didn't work. Do I have this right?
    <input type="text" name="Coupon" id="Coupon" value="" />
             <script type="text/javascript">
                  var Coupon = new LiveValidation('Coupon', { validMessage: 'Valid Code', wait: 500});
                  Coupon.add(Validate.Format, {pattern: /^mom$/i, failureMessage: "Invalid Code"} );
                  $('#Coupon').val("");
             </script>
    
  • fc_adamfc_adam FoxyCart Team
    @RevConcept.

    You could also take the approach that you have two fields. One is the visible coupon entry field, and one is a hidden field. If you prepend the visible entry field name with "x:" then it won't be submitted with the order, so that would prevent invalid coupons being submitted. Then in your javascript, if the entry is valid you could copy the value of the visible field to the hidden field - which in turn will be submitted with the order.

    That way, only the valid coupon code will be added to the order.

    Either way, whether this approach or lance's, you'll need to be able to designate functionality to happen only if the validation fails - is that possible to do? What you've scripted above just blanks out the coupon value on page load, not after a failed entry.
  • lancelance Member, Community Support Member
    Chris,

    I just wanted to follow up on this. Did you get something working?

    Lance
  • Not yet, busy day!

    I think this idea from @fc_adam above sounds ideal. Again, not exactly sure how to write the script for it though:
    You could also take the approach that you have two fields. One is the visible coupon entry field, and one is a hidden field. If you prepend the visible entry field name with "x:" then it won't be submitted with the order, so that would prevent invalid coupons being submitted. Then in your javascript, if the entry is valid you could copy the value of the visible field to the hidden field - which in turn will be submitted with the order.

    So I think this is what he's suggesting:
             <input type="text" name="x:Coupon" id="Coupon" value="" />
             <input type="hidden" name="Valid-Coupon" id="Valid-Coupon" value="" />
             <script type="text/javascript">
                  var Coupon = new LiveValidation('Coupon', { validMessage: 'Valid Code', wait: 500});
                  Coupon.add(Validate.Format, {pattern: /^mom$/i, failureMessage: "Invalid Code"} );
             </script>
    


    But not sure how to populate the hidden input field with the value of the visible field if it's valid :(
  • lancelance Member, Community Support Member
    Chris,

    Essentially if the coupon is valid, you would write it out like this:
    <script type="text/javascript">
    if(valid) {
         $('#Valid-Coupon').val("$('#Coupon').val()");
    }
    </script>
    

    If the third-party JS you're using supports a success function, you could just invoke that code in the success function. If it does not have a success function, you will either need to add this to the third-party script or you will need to have a way to determine whether or not the code was valid and then invoke this script on success.

    Lance
  • I'm not sure how to check for that or how to implement your workaround :( Javascript is like kryptonite to me!

    However, there is a class added to the input field if it's valid. Is there a way to use that? Here is what happens when the code matches:
    <input type="text" name="Coupon" id="Coupon" value="" class=" LV_valid_field" />
    

    So, would there be a way to simply test for the existence of that class and then have a message passed through to the receipt?

    @fc_adam tried adding name="x:Coupon" but the field values were still passed through?

    - Chris

  • fc_adamfc_adam FoxyCart Team
    @RevConcept,

    If you're only including livevalidation for this purpose only, and considering it doesn't have callback functionality - your best bet might be to just run your own little validation script. Based on the manual coupon entry script on our snippets section of the wiki, I've pulled the following together: http://pastie.org/private/avra1slam5hmx8p73evbq

    Note that no name is given for the visible coupon entry field - this will prevent it submitting with the form. I've also set some very basic obfuscation to the coupon code that the customer needs to enter, so it's not as simple as someone viewing the source of the page to get the code. To create the obsfucated code, you simply go to this page and apply the ROT13 algorithm and paste the result into the FCtoken variable. Note that customers don't add the obsfucated code - but they type it in normally and the code will validate it for you. For example, if the code was "MyCode" this would become "ZlPbqr" - but your customers would have to enter "MyCode" to validate.
  • @fc_adam....this is great! It works perfectly. I added a button to ensure shoppers get the correct message, and some <span>'s with classes for the alerts so they are colored.

    Thanks also for the FCtoken variables. That's much better than just having the code sitting there ;)

    As usual, you've all been a great help! I'm pasting my full code for anyone else who wants to use something like this.
    <input style="margin-left:10px;" type="text" id="coupon_entry" value="" />
    <input type="hidden" name="Applied Promotion" id="order_coupon" value="" />
    <input type="button" value="Apply Code" />
    <p id="coupon_message" style="display:none; font-weight:bold; margin-top:8px;"></p>
    
    <script type="text/javascript">
        jQuery(document).ready(function() {
            FCtoken = "ZBZ";
    
            jQuery("#coupon_entry").change(function() {
                    FSvalidate();
            });
    
            FSvalidate();	
        });
    
        function FSvalidate() {
            if (FScheck(jQuery("#coupon_entry").val())) {
                jQuery("#order_coupon").val(FSparse(jQuery("#coupon_entry").val()));
                jQuery("#coupon_message").html("<span style='color:#71BF44;'>Promotion Applied</span>").show();
            } else {
                jQuery("#order_coupon").val("");
                jQuery("#coupon_message").html("<span style='color:#D03C3A;'>No Promotion Applied</span>").show();
            }
        }
    							
        function FScheck(FSval) {
            return (FCtoken.replace(/[a-zA-Z]/g, function(c){return String.fromCharCode((c<="Z"?90:122)>=(c=c.charCodeAt(0)+13)?c:c-26);}) == FSval);
        }
    							
        function FSparse(FSval) {
            return FCtoken.replace(/[a-zA-Z]/g, function(c){return String.fromCharCode((c<="Z"?90:122)>=(c=c.charCodeAt(0)+13)?c:c-26);})
        }
    </script>
    
    

  • fc_adamfc_adam FoxyCart Team
    @RevConcept,

    Glad you got it working!
Sign In or Register to comment.