====== FoxyCart Coupons and Discounts ====== Coupon codes can be a very significant marketing tool, so it's important to understand what is and isn't possible with FoxyCart's coupon and quantity discounting functionality. While coupon codes and quantity discounts may not seem inherently related, FoxyCart uses almost the same logic and syntax for both, so we'll discuss them together. We've found that stores with coupon codes tend to generate 60% more revenue and 83% more transactions than stores not utilizing coupon codes, and those numbers increase (significantly) as the number of coupon codes increases. (Stores with 10 or more coupon codes do 3.8x the revenue and 3x the transactions. According to our data, at least. No joke.) It's not a magic bullet, but simply having coupon codes available can motivate an otherwise "too busy" merchant or marketer to do some email marketing or advertisements promoting the coupon codes. Try it! According to our system-wide data, you won't regret it. ===== How They Work ===== It's important to understand that both coupon codes and discounts can apply a **value** or **percentage** based discount, based on the **value** or **quantity** "tier" of the cart (or of specific categories, or specific products, depending). This is a critical piece to understand, because in FoxyCart you cannot simply apply a "$5 discount" without a tier, even if that tier is simply "minimum quantity of 1 product". That might sound confusing, but once you understand the logic and syntax you'll see how it's possible to create very advanced discount structures without much trouble at all. ==== Important Words to Understand ==== In order to make sure we're on the same page, let's review the terms we'll be using. ; ''Discount Name'' : The text displayed to the customer where a discount is applied. For example, "Spring Cleaning Special" or "Wholesale Quantity Discount". ; ''Discount Method'' : The type of discounting method being applied, such as "discount by the price based on the quantity" or "discount by a percentage based on the cart subtotal". [[#discount_methods|Details.]] ; ''Discount Type'' : The specific type of discount, such as an "all units quantity discount", a "one off" discount, a "Buy One, Get One", or etc. [[#discount_types|Details.]] ; ''Discount Tier'' : The threshold (either a currency value or a product quantity value) that must be reached in order for a the corresponding ''discount amount'' to be applied. All discount types can accept multiple tiers except for the ''repeat'' type. ; ''Discount Amount'' : The amount of the discount, either applied as a set dollar (or other currency) amount or as a percentage of the product price. ; ''Discount Logic'' : The combination of the discount type (if specified) with the discount tiers and amounts. For example this could be ''allunits|1-10|2-20'' or ''1-5|5-10|3-50'' or ''1-50''. ==== Discount Methods ==== Four different methods are provided for discounts to dictate what type of discount is applied based on what criteria {{section>.:cheat_sheet#discount_methods&noheader&noeditbtn&permalink&footer&nodate&nouser}} ==== Discount Types ==== {{section>.:cheat_sheet#discount_types&noheader&noeditbtn&permalink&footer&nodate&nouser}} ==== Syntax ==== The discount syntax below shows all the pieces to creating a discount. In a coupon or category discount, the ''discount_method'', ''Discount_Name'', ''discount_type'' and the discount tiers are specified separately from each other within the FoxyCart administration. See the next section on [[#creating_a_discount|Creating A Discount]] for further details on that. {{section>.:cheat_sheet#discount_syntax&noheader&noeditbutn&permalink&footer&nodate&nouser}} ===== Creating A Discount ===== There are three different ways that a discount can be applied - automatically at the product level or and the category level, or manually by the customer in the form of a coupon. **Need a hand creating your discount tiers?**\\ [[:snippets:discounts|Try out our helper interface]] to create your discount. ==== Product Discount ==== {{ :v:2.0:product_discount.png?direct&300|}} A product level discount applies to a single product //and that product only//. This is often desired for items that may be ordered in bulk, like screws or other hardware items. For Product Discounts, ''allunits'' is the default discount type unless otherwise specified. === How are they created === Product discounts are added to the cart inside the product add to cart link or form that the product is created in. === How are they added to an order === Product discounts are automatically added with the product when it is added to the cart === How are they displayed === Product discounts are displayed as an option for the given product it applies to === Example === As part of a link: * ''discount_quantity_percentage=My Discount{allunits|5-10|10-20}'' As part of a form: * '''' ==== Category Discount ==== {{ :v:2.0:category_discount.png?direct&200|}} A category discount is applied to all products that are assigned to that category equally, so category-based discounts work best when the category contains similarly priced items or you work with percentage based discounts. If you would like your category discount to be applied only in certain cases (like when a customer is a member of a group that receives the discount), then you can create two categories, one with and one without the discount, and use the discounted category (or not) when adding products to your cart. The default discount type for category discounts is ''allunits''. === How are they created === {{ :v:1.0:discounts_categorysettings.png?direct&300|}} Category discounts are created from within your store's FoxyCart administration, within the settings for each individual category. === How are they added to an order === Category discounts are automatically added to any products associated the category it applies to. === How are they displayed === A discount applied to products from a category level discount appear as an attribute for the relevant products in the cart display. It also modifies the per item price of the product based on the discount. === Example === ; Category Discount Type : ''Discount by a percentage based on the quantity'' ; Discount Name : ''My Discount'' ; Discount Details : ''allunits|5-10|10-20'' === Note === When using a category discount with a type of single, this will distribute the discount equally across all products. This means that in a situation with 2 products, 1 $10 and 1 $20 product, with a discount by an amount based on the quantity of ''single|1-10'' (which says for 1 or more products, discount $10), the discount will apply $5 on each of the two products. Otherwise the discount is applied equally to each product, so for an example, a discount of $10 would mean that $10 is discounted from each product in the category. ==== Coupon Codes ==== {{ :v:2.0:responsive_2.0_cart_coupons.png?direct&300|}} Unlike product or category quantity discounts, coupon codes apply one single discount as a line-item in the cart, and do not affect the individual product prices. Coupon codes also can apply to one or many categories, but cannot be product-specific (unless the product is the only product in a given category). The default discount type for coupons is ''single''. === How are they created === Coupons are created from within your store's FoxyCart administration, on the coupons page. === How are they added to an order === Coupons can be added in two ways. == Automatically == Coupons can be added with a product add to cart link or form by specifying the ''coupon'' parameter with the coupon's code as the value (after you've created the coupon in the admin). Multiple coupon codes can be added at one time, separated by a comma, for example: ''coupon=code1,code2,code3''. This means that the customer won't need to take any action for the coupons to be applied, and will appear in their cart when the order matches the coupons requirements. Here are examples for both link and form add-to-cart types. I've created a coupon in the admin with a code of ''20OFF20'' that gives a bulk 20% discount when a customer orders 20 or more products. **Link Example** Add to Cart **Form Example**
If making use of the [[v:2.0:hmac_validation|add to cart link and form encryption]] - the ''coupon'' parameter does not need to be encrypted. == Manually == A customer can enter a coupon manually on the cart page of the FoxyCart checkout process. If a valid coupon exists for the store, a link to 'Add a coupon' will appear within the carts totals area between the subtotal and the total. Clicking this link will display a text input that customers can enter the code into and click to update the cart and add the coupon. Something to note here is that if there is currently no valid coupon for the store, then the 'Add a coupon' functionality won't be displayed in the cart. This prevents possible cart abandonment as people may possibly leave your store in search of a coupon that doesn't exist. There are a couple ways that a coupon may not be valid or active: * The current date is outside of the active date range set for the coupon * The coupon has been used as many times as is allowed === How are they displayed === A coupon is displayed as a line item in the totals section of the cart as a single discount amount. === Details === {{ :v:1.0:discounts_couponsetting.png?direct&300|}} Coupon codes have a variety of configuration options in addition to the discounting functionality described above. ; Coupon Name : The name displayed in the cart, once a coupon has been added. For example, "Loyal Customer 20% Off Coupon". This allows both the customer and store admin to easily see what coupon has been applied to their cart. ; Coupon Code : This is the "coupon" itself; the actual text that is distributed by the merchant and entered by the customer. Codes can include letters and numbers, as well as ''-'', ''_'' and ''.'', to a maximum of 50 characters, but care should be taken to ensure it's easily readable (ie. 0 versus O, 1 versus l (lowercase L) versus I (uppercase i), etc.). Coupon codes are case insensitive, so ''MyCoupon1'', ''MYCOUPON1'' and ''mycoupon1'' are all considered the same. ; Coupon Variations : FoxyCart allows for a single coupon code to be defined, but to generate multiple distinct coupon variations (up to 100 at a time). This allows for easy creation of multiple unique codes, all with identical discount options, which can be very useful for mail merges or other coupon distribution where any individual coupon code may only have 1 single use, but you may need dozens or hundreds (or thousands). ; Coupon Type : The type of discount you want to apply (see above for details on that) ; Coupon Details : The discount logic, such as ''incremental|1-5|2-10'' ; Combinable : If the "combinable" checkbox is left unchecked when creating a coupon it will not be added to the cart if another coupon is already in the cart. Similarly, if this coupon is added first, no other coupons will be able to be added to the cart. Note: The discounts that coupons generate are based off the product subtotal, and other coupons don't impact the generated discount. For instance, if you have a $100 transaction with both a $20 and a 10% off coupon, the order total will be $70 (and not $72, as would be the case if the % discount calculated //after// the $-discount. ; Shared Codes Allowed? : If checked, this option allows codes from this coupon to be shared with other coupons on the store. This can allow a single code added to the cart to add multiple different coupons at the same time. The ''combinable'' checkbox will be ignored for coupons that have ''shared codes'' enabled and also share the same code that is being added. All other validations will apply as normal though. If at least one of the coupons linked to the shared code is added, then any that generate an error will fail silently, just adding those coupons to the cart that were successful. If all coupons from the shared code fail though, then the errors will be displayed. : Codes that are shared with other coupons will include a ''[s]'' note next to the code in the admin summary for the coupon. Hovering over that note will show the names of the coupon(s) that this code is shared with. : Note that shared coupons are handled slightly differently in the cart JSON object, as an array of coupons linked to the coupon code. [[v:2.0:templates:view_data#cart|Review the structure on the template view data]] for details on how it looks. ; Multiple Codes Allowed? : If this checkbox is checked, then multiple codes from the current coupon can be added to the cart at the same time. If unchecked, an error will be returned if attempting to add a code that belongs to a coupon that is already present on the cart. ; Taxable : If the "taxable" checkbox is checked when creating the coupon taxes will be applied //before// the coupon's discount is applied. Check with your tax professional if you have questions about how you should calculate taxes. ; Category Discounts : If this box is checked, category discounts will //not// be applied to the relevant parts of an order (and the coupon discount will be applied //instead//). As an example, let's say you have a 15% quantity discount (when quantity is 2 or greater) applied for ''category=shirts'', and you have 3 shirts in the cart at $10 each. This quantity discount would be $4.50. Now let's say you have a coupon code with this checkbox checked. When that coupon is added to the cart, the quantity discount will be //removed//, and only the coupon discount will remain. This is most often useful in situations where you do not want coupons discounts to be added together with other discounts. ; Line Item Discounts : This is nearly identical to the "Category Discounts" above, but applies to product-level discounts. ; Valid Dates : If the coupon has dates set, it can only be used within those date ranges. The start and end dates are inclusive, so coupon codes can be used on the start and end dates as well. [[#notes|See notes]] ; Apply to Categories : Similar to the category quantity discounts, but can be applied to multiple or all categories. So if a coupon code only applies to the T-Shirt category and there are no T-Shirts in the cart, no discount will be applied. ; Restrict Usage by Product Code : If you want to limit which products can use this coupon, you can enter a comma separated listed of product codes or partial product codes using ''*'' as a wild card at the beginning and/or end of the value. So ''abc123'', ''fun_*'', ''*-small'' would match ''abc123'', ''fun_'' and ''fun_times'', and ''example-small''. It wouldn't match ''abc12'', ''abc1234'', ''fun'', or ''good-smalls''. If a code starts with ''-'' it will be considered as a block instead, matching everything except products that match that code. For example ''-*-small'' would match every product that does not have a code that ends in ''-small''. Allow lists and block lists can also be combined, ''foo*, -foobar'' would match all products that begin with ''foo'' except any products with a code of ''foobar''. Currently restricted to a maximum length of 5000 characters. ; Restrict by Item Options : You may have arbitrary item options (like ''brand'', ''publisher'', ''size'', ''location'', etc.) that determine what type of discount to apply. Using this setting, you can restrict coupons using similar logic as the "restrict usage by product code" above. Instead of a single comma-separated list of values to match against, input here is per item option. Wildcards can be used in option //values// but not option //names//. : The functionality is only available in the new admin and via the API. : Though not technically item options, the following native item values can also be matched against: ''name'', ''parent_code'', ''url'', ''image'', ''sub_frequency''. ; # of Uses (Total) : If you want to limit the number of uses this coupon as a whole can be used, enter a number here. If, for example, only the first 50 customers can use the coupon, enter 50 here. This relates to coupon variants and the number of uses per code (below). If you have 1 coupon code and 10 uses, the coupon will not be able to be used after 10 successful transactions. If you have 1 coupon with 100 variants but only 50 uses, only the first 50 uses will be allowed, regardless of the number of uses per code. ; # of Uses (Per Code) : This is similar to the total number of uses, but only limits individual coupon code variants. So if you have 100 coupon code variants and this value is set to 1, each variant will only be able to be used once. The total uses allowed (above) is a higher priority than this, however, so if a coupon's total uses has already been reached then this value doesn't matter. ; # of Uses (Per Code Per Customer) : If you want to limit the number of uses an individual customer can use each code for a given coupon, enter the number of uses here. For example, if each customer is only allowed to use each of the coupon's codes once, enter 1. This is based off of the customer's email address, not a payment method, ip address, shipping address or browser cookie, so the customer could conceivably enter a different email address to receive the discount again. For the three options that limit a coupon based on usage (either in total, or by code or customer), a coupon is only considered used if it applies an actual discount on the transaction. This means for subscriptions that have a future start date, making their initial transaction $0, that won't count towards the usage for a coupon. **Selling subscriptions with the PayPal Express Checkout (Legacy) integration?** Limitations on changes that are possible to subscriptions managed by PayPal mean that coupons that only apply for a certain number of uses (either by dates or number of uses for the coupon, code or customer) won't behave as expected for legacy PayPal subscriptions. While the coupon will be removed within Foxy, the customer will continue to be charged the discounted amount by PayPal as they were from their first charge. We don't recommend utilising limited usage coupons with PayPal Express Checkout (Legacy) based subscriptions. ===== Tax-Inclusive Pricing with Coupons & Discounts ===== Coupons and discounts get a little trickier, and how you want coupons to work in the context of [[./taxes|tax-inclusive pricing]] isn't as obvious or globally agreed-upon as you might hope. (Please read the docs on that page first, if you haven't, as it has important context for this section of our documentation.) In particular, percentage-based discounts are generally "easy", but set-amount discounts may require a few minutes to understand. This is easiest to communicate by way of example. Assume an $100 (tax-exclusive) product ($110 tax-inclusive price), a 10% tax (inclusive), and a $15 coupon. Take a look at this table, and note the tips and warning: ^ **Scenario** ^ **#1** ^ **#2** ^ **#3** ^ **#4** ^ **#5** ^ | **Template Set** | Tax-Exclusive | Tax-Exclusive | Tax-Inclusive | Tax-Inclusive | Tax-Inclusive | | **Item Price (displayed)** | 100.00€ | 100.00€ | 110.00€ | 110.00€ | 110.00€ | | **Item Price (actual)** | 100.00€ | 100.00€ | 100.00€ | 100.00€ | 100.00€ | | | | | | | | | **Coupon's ''is_taxable''** | false | true | false | false | true | | **Coupon's ''inclusive_tax_rate''** | 0 | 0 | 0 | 0.10 | 0 | | **Coupon Discount (actual)** | 15.00€ | 15.00€ | 15.00€ | 15.00€ | 15.00€ | | **Coupon Discount (displayed)** | 15.00€ | 15.00€ | 15.00€ | 13.64€ | 15.00€ | | | | | | | | | **Item Price, post coupon (not displayed)** | 85.00€ | 85.00€ | 95.00€ | 95.00€ | 95.00€ | | **Item Price, post coupon (actual)** | 85.00€ | 85.00€ | 85.00€ | 86.36€ | 85.00€ | | | | | | | | | **Tax** | 8.50€ | 10.00€ | 8.50€ | 8.64€ | 10.00€ | | | | | | | | | **Order Total** | 93.50€ | 95.00€ | 93.50€ | 95.00€ | 95.00€ | The three settings to note are: - The template set's tax inclusive setting. - The coupon's "taxable" setting. In some industries or situations, a discount might be "after tax". For instance, say you want to offer customers 100% off, but you still need to collect tax for the full sale amount. Set the coupon to taxable and the tax will be applied //before// the coupon's discount is applied. - The coupon's "inclusive tax rate" value. This gets a little more complicated, but if you compare scenario #3 and #4 above, you can see the impact. Setting a coupon's ''inclusive_tax_rate'' will decrease the //applied// (but not //displayed//) discount by that inclusive tax percentage. So a 15€ coupon becomes ''15 / 1.1 = 13.64''. The end result is a 15€ "tax-inclusive" discount, as you can see in the Order Total row. * This is only important for "discount by an amount" coupons, not for "discount by a percentage" coupons, as %-based coupons will result in the correct order total regardless tax-inclusive or tax-exclusive settings. * Scenario #3 shows what would happen without an inclusive tax rate. (It behaves identically to scenario #1, which is tax-exclusive.) * The inclusive tax rate should be the default tax rate for the customers who'll use the coupon. This ensures your coupon is always for the expected amount, even if a customer's tax rate is different. This also prevents tax-exempt customers from receiving a higher-than-desired discount. * The inclusive tax rate functionality behaves identicaly regardless the tax-inclusive or taxable settings, but it's generally only useful in the tax-inclusive scenarios. **We'd love to hear from you.** Please [[https://foxy.io/contact|send us a quick note]] if you have a requirement with taxes and coupons that's not covered here, along with your country and industry. **This topic can be complicated.** One of our team (in Paris) went through their receipts and pulled 3 of their orders from non-Foxy merchants, and we found each of their transactions mapped to scenarios 3, 4, and 5. If you're unsure which of the above approaches make sense to you, please contact your tax professional for what will surely be an exhilarating conversation. :) ===== Notes ===== * **Time and dates are relative to your store's timezone settings.** * The coupon code entry block is hidden from the cart unless the store has at least one valid coupon, where "valid" means "applicable here and now". * If a customer attempts to complete a transaction with a coupon that has since become invalid (for example if another customer has since completed a purchase with it, causing the maximum uses limit to be met), then the customer will be sent back to the checkout with the coupon removed and an error message (checkout language string for ''error coupon'' if you want to customise it). ==== Tracking $0 coupons as used ==== By default, only those coupons that apply an actual discount to the cart are tracked as used on completed transactions. This means that if you have a coupon set with a discount tier like ''1-0'', that won't be tracked as used on the transaction once completed, and won't count against usage restrictions. To track $0 coupons, you can set up the tier as ''0-0'' instead, and these coupons, even though they don't apply a discount, will be tracked as used. They will also be counted against any usage restrictions in place for the coupon as well. ==== General Discount Notes ==== It is important to note that the discount tiers only count against the portion of the cart that will actually receive a discount. So a category-wide quantity discount that has a quantity tier of 5 will not apply if there are only 3 products in the category, regardless the number of products in other categories. All product and category quantity discounts are applied to the products themselves, and not as a separate line item like a coupon code. So if a product is ordinarily $10 and has a 10% discount, the discount is reflected in the product details and the product price becomes $9. Product quantity discounts can be combined with category quantity discounts, as well as coupon codes, however it will likely result in confusion to mix product-specific and category-specific quantity discounts, so it's best avoided if possible. ===== Common Discount Examples ===== Below is a list of common discounts in stores detailing their discount method and logic. For applying to a specific type of discount (product, category or coupon), please see details above. Buy two products, take $2 off of //both//. * **Method:** ''discount_quantity_amount'' * **Logic:** ''allunits|2-2'' Orders of five or more get a 10% on //every// item ordered. Orders of 10 or more get a 20% discount on //every// item ordered. * **Method:** ''discount_quantity_percentage'' * **Logic:** ''allunits|5-10|10-20'' Buy two products, get additional products at $5 off. (The first two are not discounted.) * **Method:** ''discount_quantity_amount'' * **Logic:** ''incremental|3-5'' With a quantity of 1-10, all products are at 100%. With a quantity of 150, 10 products would be at 100%, 40 would be at 90%, 50 would be at 85%, and 50 would be at 80%. * **Method:** ''discount_quantity_percentage'' * **Logic:** ''incremental|11-10|51-15|101-20'' Buy one, get one free (100% off). * **Method:** ''discount_quantity_percentage'' * **Logic:** ''repeat|2-100'' Buy 3, get the 4th at 50% off. * **Method:** ''discount_quantity_percentage'' * **Logic:** ''repeat|4-50'' Buy any 5 products, get $10 off your order. * **Method:** ''discount_quantity_amount'' * **Logic:** ''single|5-10'' Take 10% off orders of $99.99 or more. * **Method:** ''discount_price_percentage'' * **Logic:** ''allunits|99.99-10''