MODULES
...
eCommerce
Cart, Checkout, Shipping and O...

Discount Codes Layout

44min
this article explains how to output a discount codes layout in either basic payment form, cart, checkout or subscription layouts introduction discount codes allow your client to provide special offers to their customers you can learn how to set up discount codes in the admin here the role of a discount code layout is to give the customer an opportunity to enter and apply a discount code on your site additionally, once a code is applied, the layout will give the customer information about how their code has been applied along with any terms and conditions, and the opportunity to remove the code this article will explain how you can include a discount codes layout in either your cart wrapper liquid file checkout form layout (discount code layouts for the cart and checkout will have the same syntax) basic payment form layout this will have slightly different syntax due to the unique properties of basic payment forms, but we'll cover this below subscription form layout this will have slightly special considerations because the discount has the potential to be applied to all invoices for a specified number of months it's also possible to use subscription discount codes to take 100% off the price giving a free trial once a customer uses the button in the layout to successfully add a discount code, this will be stored in their session alongside any cart data we'll store one code at a time for each payment type, with basic payment forms storing their codes in {{context session basic payment discount}} , cart saving its codes in {{context session cart discount}} and subscriptions saving their codes in {{context session subscription discount}} when a customer completes a payment form, the server side checks will apply the code and reduce the amount they are charged this means your site will be secure and safe against malicious users choosing their own discounts step 1 including the layout inside the cart, checkout, basic payment form or subscription form layout the screenshot below shows how the discount code layout can be nested inside the cart however, step 1 also applies in all kinds of layout 1a add your layout the following liquid will add the layout {% include 'ecommerce/discount code' layout "cart/default" %} the only parameter you'll need will be layout which refers to the file name of the layout we'll look at where to create the layout files in step 2 1b optional adding support for refreshing layout instead of whole page in order to better support adding discount code layouts on forms, we've added the option to reload just the layout, instead of the whole page the main benefit of this is that users will not have to refill their form data after adding a discount code we'll discuss this more in step 3) b) for now, you can add the data attribute data s e refresh layout discount code to the element which serves as a wrapper for your layout e g {% include 'ecommerce/discount code', layout "cart/default" %} in a cart layout, you may also wish to set prices to automatically update when the discount code is added you can add the following data attributes data s e live cart currency the element will be filled dynamically with the cart currency when the layout refreshes data s e live cart total the element will be filled dynamically with the updated cart total price e g total price {% include 'ecommerce/price total' format type 'formatted' %} related layout development docs developing cart layouts checkout tutorial https //help siteglide com/article/163 how to set up a shopping cart and guest checkout tutorial basic payment form tutorial step 2 create layout files or choose the discount code layout a discount code layout will typically contain an input field for the customer to enter a discount code a button which allows them to submit the code a button which allows them to remove a code (if perhaps the code is no longer valid and blocking payment) feedback to the user regarding successful and unsuccessful attempts to apply their discount code essential html, javascript and liquid which controls functionality file structure discount code layouts will be stored here, inside layouts/modules/module 14/discount code you'll just need a single liquid file with the same name as your layout optionally, you can use folders to organise layouts of different types if you haven't already, make sure your layout parameter in the liquid tag matches the name of your layout file any custom folders like 'cart/' should also be added to the layout parameter path as there are subtle differences in implementation depending on the type of payment, we've created three different default layouts to help you get started "basic payment/default" "cart/default" "subscription/default" for steps 3 and onwards, you may find it easier to copy and edit the code from the default layout, but we'll break this down into steps here so you can see all the elements you'll need step 3 add html and liquid to allow a customer to enter a discount code 3a add an \<input> element and \<label> discount code html attributes explained code purpose required data s e discount code attribute should be added to input field yes value="{% if discount code != blank %}{{discount code}}{% endif %}" or {% if discount code != blank %}value="{{discount code}}" readonly{% endif %} if a code is already successfully added, it will be autofilled or any successful code is autofilled and the current field value is readonly until removed in step b) one of these 3b add an "apply" button when adding the 'apply' button, you can customise how the javascript will behave on successful and unsuccessful attempts to add a discount in the examples below, we'll show the basic options recommended for different types of layout, then explain the full range of options you have for javascript behaviour applying to a cart layout \<button class="btn btn primary sg btn sg btn primary" id="s e discount apply" onclick="s e cart discount code( { spend '{{context exports cart base price data | json}}', reload true } )">apply code\</button> applying to a checkout form layout \<button class="btn btn primary sg btn sg btn primary" id="s e discount apply" onclick="s e cart discount code( { spend '{{context exports cart base price data | json}}', reload false } )">apply code\</button applying to a basic payment form layout \<button class="btn btn primary sg btn sg btn primary " id="s e discount apply" onclick="s e cart discount code( { spend document queryselector('#s e amount') value, reload false } );">apply code\</button> applying to a subscription layout note we recommend hiding the apply button after the subscription order has been created and the discount code has been redeemed see subscription specific instructions \<button class="btn btn primary sg btn sg btn primary" id="s e discount apply" onclick="s e cart discount code( { spend {{spend}}, reload false } );">apply code\</button> 3c javascript options explained at this stage, you have a choice about whether you'd like the whole page to reload after a successful discount code is added, or whether you'd like to only reload the discount code layout itself we'd strongly recommend that for layouts on forms that you set reload false as this will prevent the user having to re enter their form data, and will preserve any custom amount chosen on the basic payment form note also that the value of spend will be different for basic payment forms basic payment forms store the spend value in document queryselector('#s e amount') value as this can be dynamically changed by javascript, there is no liquid value for it cart and checkout forms can use the liquid value '{{context exports cart base price data | json}}' subscriptions store the spend in {{spend}} option required / default notes spend document queryselector('#s e amount') value '{{context exports cart base price data | json}}' '{{spend}}' required no default basic payment forms use spend document queryselector('#s e amount') value \ as this can be dynamically changed by javascript, there is no liquid value for it cart and checkout forms can use the liquid value spend '{{context exports cart base price data | json}}' reload true false default true setting true will refresh the entire page setting false will refresh the discount code layout only we'd strongly recommend that for layouts on forms that you set reload false as this will prevent the user having to re enter their form data, and will preserve any custom amount chosen on the basic payment form if you select false , you must add the data attribute data s e refresh layout discount code to the element which wraps around the layout see step 1) b) error cb custom javascript function name (don't call the function yet!) error cb myerrorfunction default a javascript alert message will display the error for arguments and how to customise your own function, head to step 6 success cb custom javascript function name (don't call the function yet!) success cb mysuccessfunction default depending on the reload option, will reload the page or layout if reload is false and the payment type is checkout, will update the total price by running the s e cart update prices(); for arguments and how to customise your own function, head to step 7 step 4 add html and liquid to allow a customer to remove a discount code you can optionally add a button to the layout which will allow the customer to remove a discount code that has already been applied {% if discount code != blank %} \<button class="btn btn danger" id="s e discount remove" onclick="s e cart discount code remove( { reload false } )">remove code\</button> {% endif %} the liquid if statement helps make sure the button is only displayed if there is a code present to be removed the javascript function will make the button functional option required / default notes reload true false default true setting true will refresh the entire page setting false will refresh the discount code layout only we'd strongly recommend that for layouts on forms that you set reload false as this will prevent the user having to re enter their form data, and will preserve any custom amount chosen on the basic payment form if you select false, you must add the data attribute data s e refresh layout discount code to the element which wraps around the layout see step 1) b) success cb default depending on how you set the refresh setting, will refresh the page or the layout for arguments and how to customise your own function, head to step 8 why is this helpful? although we check discount codes are valid when they are added, there are cases where the code is no longer valid by the time the customer reaches the checkout, for example the user may have adjusted the quantity of items in the cart, causing the spending amount to drop lower than the minimum payment allowed by the discount code the code may have been close to expiry adding a "remove" button gives the user a clear way to solve any problems stopping them from completing their purchase note you cannot remove a subscription discount code after the subscription order has been created and the discount redeemed see subscription specific instructions step 5 add html and liquid to give the customer feedback 5a displaying the discount amount on page refresh (or if you've chosen reload false on layout refresh), after a successful code is applied, the following liquid will explain the minimum spend needed and the discount available depending on where your layout is, different syntax may be needed to fetch the currency to display on cart and checkout layouts {% if discount code != blank %} discount {{context exports cart currency data}} {% include 'modules/siteglide ecommerce/ecommerce/price formatter' price data discount amount %} {% endif %} on basic payment layouts {% if discount code != blank %} discount {% include 'ecommerce/basic payment currency' format 'symbol' %} {% include 'modules/siteglide ecommerce/ecommerce/price formatter' price data discount amount %} {% endif %} on subscription layouts on subscription layouts it is important to know whether or not the subscription order has been created, if it has, then the discount will already be redeemed the difference in display needs to account for the fact that a redeemed discount is time limited for both situations, we can use the fields inside the discount variable to access details on the discount before the subscription order is created at this stage, we can use general details of the discount which is applied, but not yet redeemed, from the this object {% if discount code != blank %} discount {{this price currency symbol}} {% include 'modules/siteglide ecommerce/ecommerce/price formatter' price data discount amount %} every {% if this\['interval count'] != "1" %} {{this\['interval count']}} {{this\['interval']}} {% else %} {{this\['interval'] | pluralize 1}} {% endif %} for {{discount number of months to discount}} {% if discount number of months to discount == 1 %} month {% else %} months {% endif %} {% endif %} after the subscription order is created and the discount redeemed at this stage, we can use details of the actual discount code stored against the subscription order as this is time limited, we may also wish to give details of how much longer the discount will be active for and the specific subscription order will provide these details {% if discount code != blank %} discount redeemed {{this price currency symbol}} {% include 'modules/siteglide ecommerce/ecommerce/price formatter' price data discount amount %} saved every {% if subscription order\['plan interval count'] != "1" %} {{subscription order\['plan interval count']}} {{subscription order\['plan interval']}} {% else %} {{subscription order\['plan interval'] | pluralize 1}} {% endif %} for {{discount number of months to discount}} {% if discount number of months to discount == 1 %} month {% else %} months {% endif %} until {{subscription order\['plan discount ends at'] | date "%d/%m/%y"}} total due {{this price currency symbol}} {% include 'modules/siteglide ecommerce/ecommerce/price formatter' price data discount total remaining %} {% endif %} 5b displaying the minimum spend the following code can be used to display the minimum spend needed to keep using the discount on cart and checkout layouts {% if discount code != blank and discount minimum %} this code will only be valid on cart orders worth over {{context exports cart currency data}} {% include 'modules/siteglide ecommerce/ecommerce/price formatter' price data discount minimum %} {% endif %} on basic payment layouts the following code can be used to display the minimum spend needed to keep using the discount {% if discount code != blank and discount minimum %} this code will only be valid on orders over {% include 'ecommerce/basic payment currency' format 'symbol' %} {% include 'modules/siteglide ecommerce/ecommerce/price formatter' price data discount minimum %} {% endif %} on subscription layouts it's probably only really necessary to display the minimum spend before the subscription order is created and the discount redeemed once the discount is redeemed, the amount spent will be fixed {% if discount code != blank and discount minimum %} this code will only be valid on orders over {{this price currency symbol}} {% include 'modules/siteglide ecommerce/ecommerce/price formatter' price data discount minimum %} {% endif %} 5c displaying a message when the discount maximum is reached on basic payment forms, cart and checkout this code will display a message if the minimum spend is not set strictly enough and the resulting payment total is below that allowed by the payment gateway {% if discount saving maximum reached == true %} minimum transaction value reached to make the most of your discount, try adding another item to your cart {% endif %} discount saving maximum reached will always return false for subscriptions and these allow any size of discount (controlled only by the partner and client setting minimum spend values on each discount code in the admin ) therefore, it's not necessary to add this code to a discount code layout for a subscription read more about the discount maximum requirement summary of available fields when building your discount code layout discount code is a variable which contains the discount code successfully applied after page refresh discount minimum is a variable which contains the minimum spend needed for this discount code to be valid discount amount is a variable which stores the calculated saving on the current cart value {{context exports cart currency data}} will output the currency symbol on cart and checkout layouts {% include 'ecommerce/basic payment currency', format 'symbol' %} will output the currency symbol on basic payment layouts {% include 'modules/siteglide ecommerce/ecommerce/price formatter', price data discount minimum %} you can use this liquid tag to format any liquid price variable with the correct decimalisation to use, set the price data parameter to the variable you wish to format discount saving maximum reached if true , the minimum amount for the discount code has not been set strictly enough and the total payment due is below that allowed by the payment gateway you can use this to display a warning message that it has not been possible to apply the full discount for subscriptions, your layout will inherit the variables of the layouts it's nested within meaning it will inherit variables from the subscription detail page, then the subscription form see details of these objects here e g {{this price currency symbol}} step 6 optional add javascript to handle errors there are lots of reasons why the customer may enter a code but be refused a discount for example, the code may have expired, or the cart's value may not be above the minimum spend you can start with the javascript function below and make your own changes to decide how these errors are displayed to the customer \<script> function s e discount error(error) { console log(error type); / an error code which you can use in your logic / console log(error message); / a ready drafted error message / alert(error message); } \</script> as the comments in the example mention, each error returned from a failed discount code will give both a code and a default message you can choose which one you will use here are the full list error type error message notes no code error this discount code does not exist expired error this discount code has expired below min spend={min spend} error this discount code has a minimum spend of {min spend} used up this discount code has already been used the maximum number of times incorrect type error this discount code does not apply to this kind of payment it may apply in another area of the site by default, discount codes are only redeemable on cart / checkout flow you can change this for an individual code in the admin using the "valid on payment form type" field if you want to change the message, you can use logic to display different messages using the error code \<script> function myerrorfunction(error) { if (error type == 'no code' ) { alert('better luck next time discount code not found!'); } elsif (error type indexof('below min spend=') != 1 ) { //as the below min spend code can vary depending on the value, this code checks for the substring alert('you'll need to spend more before using this code '); } \</script> once you've created your function, use the error cb option in step 3) b) and pass it your function name e g error cb myerrorfunction step 7 optional customise the javascript behaviour when a code is successfully added setting reload to either true or false in the s e cart discount code function will both effectively refresh your discount code layout and the liquid will update with new values, so most use cases will not need a custom success function however, if you do need to make changes, you can use the function below as a starting point function mysuccessfunction(reload = true, discount, payment type, refreshed discount layout) { if(reload == true) { window\ location reload(); } else if (refreshed discount layout) { var slot = document queryselector('\[data s e refresh layout discount code]'); slot innerhtml = refreshed discount layout; if(payment type == 'checkout') { s e cart update prices(); } } } available arguments argument example purpose reload default true the value of the reload setting passed into the function defaults to true for backwards compatibility discount an object containing details of the newly applied discount code payment type 'checkout' or 'basic payment' can be used in logic refreshed discount layout a domstring containing the html generated by the refreshed discount code layout this can be used to refresh only the discount code layout, if you choose once you've created your function, use the success cb option in step 3) b) and pass it your function name e g success cb mysuccessfunction step 8 optional customise the javascript behaviour when a code is successfully removed setting reload to either true or false in the s e cart discount code function will both effectively refresh your discount code layout and the liquid will update with new values, so most use cases will not need a custom success function however, if you do need to make changes, you can use the function below as a starting point function mysuccessfunction(reload = true, payment type = 'checkout', refreshed discount layout) { if(reload == true) { window\ location reload(); } else if (refreshed discount layout) { var slot = document queryselector('\[data s e refresh layout discount code]'); slot innerhtml = refreshed discount layout; if(payment type == 'checkout') { s e cart update prices(); } } } available arguments argument example purpose reload default true the value of the reload setting passed into the function defaults to true for backwards compatibility payment type 'checkout' or 'basic payment' can be used in logic refreshed discount layout a domstring containing the html generated by the refreshed discount code layout this can be used to refresh only the discount code layout, if you choose once you've created your function, use the success cb option in step 3) b) and pass it your function name e g success cb mysuccessfunction specific instructions for subscriptions note we recommend for subscriptions to add some logic checking whether a subscription order has already been created and if so, to hide the apply button this is because once the subscription order is created any discount code already applied will be redeemed at this point it's not possible to apply or change the discount code, only display details of the order that's active the purpose of the form at this point is actually to allow users to edit their payment details only {% if subscription discount already redeemed == true %} {% endif %} you could add this logic around the whole layout (as in the default layout), or just around individual components for the sake of clarity, in the "subscription/default" layout, we've opted to wrap the logic around the whole layout, creating two distinctly separate blocks of liquid for before and after redemption you can also add the statement to check if the discount will apply to the next invoice or if the discounted period of months is over {% if rate still discounted == true %} {% endif %} related articles ecommerce discount codes adding and editing discount codes in the siteglide admin ecommerce discount codes how to avoid low prices which cost payment gateway charges