Zen Cart Quantity Discounts

A Zen Cart™ discounting module for bulk purchases.

Zen Cart has a built-in quantity discounting mechanism (native quantity discounts),
which allows you
to discount bulk purchases of a single item. However, some merchants wish
to discount quantity purchases of a group of
items from a category or even the entire number of items purchased or
dollars spent. The Quantity Discounts contribution permits you to offer
discounts that are structured in ways like this.

For a comparison of native quantity discounts and this contribution,
click here.

See it Live: Go to my demo shop and add ten of any item to your cart (excluding gift certificates).
You will immediately see the discount because of
Discount Preview, but
without it, you would see the discount on the second page of checkout.
Also note the marketing text
for Quantity Discounts on the Product Info page. The format
shown in example 1 is used.

Add-Ons:
Quantity Discounts is an order total module, so the discount is
not visible until the second page of checkout. If you want
to see the discount on the shopping cart page (or sidebox), look at
Discount Preview.

For example, in
my demo shop,
adding 10 of the same item to the cart
displays the discount on the shopping cart page
because of
Discount Preview.

Alternatives: Quantity Discounts is not perfect for every situation.
Please match the scenarios below with your store's needs:

Description

Solution

You have different quantity discounts (and possibly none)
for each product in your store.

STOP. Quantity Discounts is not right for you. You should
look at the native Quantity Discounting mechanism in Zen Cart,
which is called the Products Price Manager. Search the forum
for help or read some details in the
FAQ for this mod.

You have different quantity discounts, or different quantity or
purchase requirements for discounts, for specific categories
in your store.

STOP. Quantity Discounts is not right for you.
Please look at
Table Discounts.

Overview:

This mod permits a shop to define up to five admin specified quantity discount levels on a
per-product, per category or total number of items purchased basis. The
discounts may be expressed in percentage or currency units. Various
user exits are provided to make it easy to extend the mod to meet
shop requirements.

The limit of five levels can be exceeded using a simple interface in
the code to define additional levels.

Detailed Description:

The image to the right shows a shop which gives 10% off items bought in
quantities of 5 or more.

Discount Level 1..5 and Discount Amount 1..5 are fields which contain
a set of five discount levels (min. quantity required to get to this level,
discount amount) may be specified.
The Discount Basis radio buttons determine if quantity required to
get to a discount level is counted as bulk purchases of a single item
(Total By Item), by purchases within a category (Total By Category)
or by the total number of items in the cart (Total Items in Cart).
The Discount Units radio buttons allow the units of discount levels to
be specified as percent off, currency units off (i.e. dollars off the total),
or currency units per item off (i.e. dollars off per item).

Note that the category used is the parent category. This means
that when using Total By Category for products in subcategories,
the "category" will be the parent subcategory, not the
top level category.

Men's Clothing
|
----> Shirts
|
-------> shirt A
shirt B
shirt C

In this example, the parent category of "shirt A" is "Shirts," not
"Men's Clothing." "Men's Clothing" would be considered the top level category.

In stores where the first level of categories has products directly underneath it, the top level category and the parent category are the same.
If have the ability to reference categories other than the parent category is important
to your store, you may wish to consider purchasing
Table Discounts,
Combination Discounts
or
Big Chooser.

Specifying "include tax = true" will gross the discount up by the amount
of tax that would have been paid on the goods prediscount. This is
appropriate for shops under a price inclusive sales tax system, such as
the UK VAT. Specifying Re-calculate tax = Standard will recalculate the
entire tax based on the original subtotal minus the quantity discount.
Even more information about tax is provided at the bottom of this file.

Counting Method allows discounting by dollars spent rather than units
purchased as is normally done. The default value for this field is "items."

User Exits
Some shops will want to further customize their discounting policy.
Additional user exits are provided to permit the following customizations:

Include or exclude certain categories from discounting.

Include or exclude certain products from discounting.

Modify the discounts for particular categories if discounting
by category.

Modify the discounts for particular items if discounting by item.

Specifically:

The function exclude_category() shows you how to add categories to
a list of categories to not be discounted. This may be used with any
Discount Basis.

The function exclude_product() shows you how to add products to
a list of products to not be discounted. This may be used with any
Discount Basis.

If you are using the Discount Basis "Total By Category," you may
customize the discount for a specific category using the function
apply_special_category_discount().

If you are using the Discount Basis "Total By Item," you may
customize the discount for a specific item using the function
apply_special_item_discount().

Each of these functions contains a simple example of how to use it using
item and category numbers like 99999, 99998, etc. See the FAQ below for more examples.

The user exits are within the Quantity Discounts contribution, in includes/modules/order_total/ot_quantity_discount.php

Quantity Discounts discounts off the *gross* price of the goods.
This can result in a larger than expected discount if other discounts
are added (such as coupons or group discounts), so bear this in mind
when creating your discount strategy.

Checkout Page User Interface
Quantity Discounts is an "Order Total" module, which means
that by default, the discount
is not shown until the second page of checkout (Payment Information).
However, using the Discount Preview
module will allow you to show the discount in the
shopping cart.

Depending on your configuration,
the second page of checkout will look something like this:

Notice that "Quantity Discount" is a link, which will show the breakdown of
the discount, depending on the Discount Basis you selected on the Admin screen.
For instance, if the Discount Basis is "Total Items in Cart," with a Discount Level 1 of "4" and a Discount Amount 1 of "10," you would see this dialog if you
clicked the "Quantity Discount" link:

With a Discount Basis of "Total By Category," assuming these items were all in the same category (and the category was "Fish"), you would see this dialog if you
clicked the "Quantity Discount" link:

Next, we'll use a Discount Basis of "Total By Item."
The original items were all in the same category, and we'll add
four more of another item from the same category.
The two items have model numbers "BLUEFISH-127" and "REDFISH-492".
You would now see this dialog if you
clicked the "Quantity Discount" link:

Breaking the five level barrier
Suppose your discounting strategy is as follows:

Level

Amount

5

5% off

10

10% off

15

15% off

20

20% off

25

25% off

100

50% off

How do you create that last discount?

Quantity Discounts 1.4 has the answer. In the file
includes/modules/order_total/ot_quantity_discount.php, there is a
function called setup(). From there, you may add a call to a
function to add additional discounting levels and discounts in
the following manner:

Big Spender vs. Quantity Discounts by Dollars Spent:Big Spender offers discounting
by dollars spent with many more options than Quantity Discounts.
Configuration of Big Spender is in PHP, much like Better Together.
If you simply wish to offer a price sensitive discount on the entire cart,
you can use Quantity Discounts, but if you want to do things like
offer a free gift over a certain level of spending, or have multiple
price sensitive offerings which are mutually exclusive, you should
check out Big Spender.

Free Gift Spender vs. Quantity Discounts by Dollars Spent:Free Gift Spender offers discounting
by dollars spent with many more options than Quantity Discounts
with a built-in admin panel.
If you simply wish to offer a price sensitive discount on the entire cart,
you can use Quantity Discounts, but if you want to do things like
offer a free gift over a certain level of spending, or have multiple
price sensitive offerings which are mutually exclusive, you should
check out Free Gift Spender.

Installation Instructions:

Back up everything! Try this in a test environment prior to installing
it on a live shop.

If you already have the Quantity Discounts module installed, please
deinstall your old copy by going to Admin->Modules->Order Total,
selecting "Quantity Discount" and pressing the "Remove" button. Make
a note of your settings so you can apply them to the new version.

Copy the contents of the unzipped folder to the root directory of your
shop.

Login to admin and in Modules->Order Total you will see 'Quantity Discount' listed along with all the other modules available.

Click on 'Quantity Discount' to highlight the module and click on 'Install'

Decide on the parameters you wish to use. The easiest way to do this
is to open a shopping cart in another window, and just try different
discounting models. The discounts are shown on the second step of checkout in
"Your Total" under "Quantity Discount," which is itself a link that
explains the calculation.

Customization: If you have a single discounting policy for your shop,
you're all set. If you wish to tailor the policy, you will have to
add code to the user exits as described above.

If you wish, follow the guidelines in marketing
to advertise your discounts.

If you wish, install a Quantity Discounts Promotional Page by following the links at the top of this page.

Optional Installation Instructions:

I highly recommend
Discount Preview
with all my discounting modules.
Without Discount Preview, your customers cannot see the price reductions
they are entitled to until the second page of checkout (checkout confirmation). Obviously this is a disadvantage, particularly for new customers
who need to go through the additional step of creating an account before they can see this information.
Sometimes seeing is believing, so here's
a video showing Discount Preview in action.

I believe it is potentially confusing
to show the shopping cart sidebox on pages
which already display the shopping cart contents.
Zen Cart has a built in feature to turn off the shopping cart sidebox
on the shopping cart page (Go to Admin->Configuration->Layout Settings->Shopping Cart Box Status, and set this value to 2.).
However, turning it off on additional pages is not difficult, and I
recommend doing so. Here are the steps:

If you do not have a includes/modules/sideboxes/YOUR_TEMPLATE/shopping_cart.php file, create one by copying the file
includes/modules/sideboxes/shopping_cart.php.

Marketing

If you would like to have a Quantity Discounts Promotional Page that
describes your store quantity discounts as part of your categories sidebox,
you may download a copy here.

You can also add any of these examples of marketing code you like
to your own product info page.
Create your custom template and edit the file
tpl_product_info_display.php to
add one of the code blocks shown below.

Store Quantity Discount Policy

Buy 2 or more of any item, get 5% off Buy 5 or more of any item, get 10% off
Buy 10 or more of any item, get 15% off
Buy 50 or more of any item, get 50% off

If you want your discounts to appear in "largest first" order,
use get_discount_info (which returns an array) instead of
get_html_policy (which returns a string).
Then simply reverse sort the array.
Since we have each item broken out into an array element,
we'll make a table with
a single column this time:

If you want to do something close to what the
native Quantity Discounts does, which is show each of the prices
and the range required to get that price, it can also be done.
However, note that this only works for discount units percentage.
I also believe that it only makes
sense for a Discount Basis of Total By Item, but this restriction
is not enforced.

To show final, discounted prices at various quantity levels, you
could do something
like this:

Some of the examples above - examples 3 and 4 for instance,
do not work well when using Counting by Currency.
Here are is a modification to example 3 to show the effect of
discounting by dollars spent.

If you have used the apply_special_category_discount() or
apply_special_item_discount() exits, and you are using the marketing text,
bear in mind that the marketing text doesn't know and cannot figure out
how your have coded the apply_special* functions.
You will need to hardcode the marketing text for these cases.

If you have multiple quantity discounting schedules for different categories
or items, I would encourage you to look at
Table Discounts.

If you have used one of the user exits - for example,
exclude_category() or exclude_product(), you will
need to change the marketing text code to wrap it in a check
for the exclusion.
For category exclusions, change tpl_product_info_display.php from

If you have linked products,
remember that $current_category_id may not be the master category
id of the product in question.
This is important if
you are handling different categories in different ways
(i.e. using exclude_category() or apply_special_category_discount()). In this case,
it's safer to query the category id value directly than to rely on $current_category_id.
My
Zen Cart Category Issues page discusses how to get this value.

If you are also using the
Discount Preview Extension, please be sure that the second and
third statements above in your code are "include_once" and not
"include" as they were formerly.

You may also put the marketing logic described above into tpl_product_info_display.php if you
wish to advertise your discounts there. In the case of get_discounted_prices(), this is the only place where it would make sense.

Use get_discounted_prices() with caution - it only makes sense for
Discount Units percentage and Discount Basis Total By Item.

The examples shown here do inline styling. What you likely want to do
is create the file includes/templates/YOUR_TEMPLATE/css/product_info.css and put the styling in there. For example, using Example 3,

Quantity Discounts and Discount Preview

Discount Preview makes
Quantity Discounts pop!
It shows the discount on the shopping cart page, instead of making your customers wait until the checkout payment page to see their discounts.
Here's a screenshot of the shopping cart page on a cart using Discount Preview and Quantity Discounts.
The discount was $2 per bag off over 25.

Notes on Taxes

If you don't use embedded taxes, and don't have a mix of
taxable and tax-free products, and don't have a different rate of tax
for shipping, please skip this section.
However, if you any of the above apply to you, please read my
Notes on Taxes.

Be sure that the sort order for the Tax module (set in Admin->Modules->Order Total->Tax) is greater than the largest order total sort order,
so that your taxes are shown after all discounts. 399 is a good value for most stores.

Files

Earlier versions of Quantity Discounts included a customized copy
of includes/classes/shopping_cart.php; this was removed in Quantity Discounts
1.2 because the customization which Quantity Discounts required was
incorporated into the 1.3.5 Zen Cart core code. Thus, Quantity Discounts
1.2 and higher are only compatible with Zen Cart 1.3.5 and higher.

Major Versions

1.12 07/25/2016 Updating to new style constructor for PHP7. No functional changes.

1.12 04/16/2013 Code inspection and cleanup. No functional changes.

1.11 04/03/2010 Add VAT setting for taxes.

1.10a 02/13/2010 Remove donate link for forum rules compliant.

1.10 05/10/2008 Make explanatory link show up only on checkout page, adding discounts by dollars spent.

Users wishing to sort native discounts (such as Coupons or Group Discounts) after my discounts, with tax recalculation, should look at
this page.

Quantity Discounts versions prior to 1.8
require a patch to run under Zen Cart 1.3.8. Take
this function and paste it
right above the function calculate_deductions()
in the file includes/modules/order_total/ot_quantity_discount.php
The latest versions include this patch, but if you haven't upgraded,
you must manually apply the patch.

If your Zen Cart version is 1.3.0 (or higher) but less than 1.3.5, you may still run Quantity Discounts version 1.1, but not 1.2 or higher. If your Zen Cart version is less than 1.3.0, you must upgrade to a more
recent version of Zen Cart in order to run Quantity Discounts.

FAQ

Q: I have different levels and/or amounts for different categories.
How can I handle this using Quantity Discounts? A: If you have multiple discounting schedules with different
levels or amounts, you should look at
Table Discounts.

Q: I'm using Discount Basis Total by Category, or a category related user exit, like exclude_category() or apply_special_category_discount(), and it's not working! A: There are several possible root causes.
Please see the Category Issues
page for solutions.

Q: I can't seem to get Quantity Discounts to work. What am I doing wrong?A: Please check the following things:

Go to Admin->Modules->Order Total. Do you see Quantity Discounts? If not, then you haven't installed it. Follow the README.

If you do see it, the circle at the right hand end of the row for
Quantity Discounts should be green. If it's not green, reinstall it.

Click on Quantity Discounts. The Level and Amount fields are all numeric. Do not use dollar or percent signs in these fields.

If you're using Discount Basis "Total By Category," see the previous FAQ question.

If you've used any of the exits, make a backup of your ot_quantity_discount.php file and re-install from scratch; then apply your changes one at a time to see where it breaks. The most common error I have seen in exits is using the assignment operator ("=") where an equivalence test ("==") was intended.

Remember that the "levels" (Discount Level 1, Discount Level 2, etc.) are numbers of items, not number of dollars spent (unless you configure counting method to be by currency).

Q: I want to use discount units 'currency per item' but I don't see it!A: This feature was added in Quantity Discounts 1.7 and requires a database change.
Please download version 1.7 (or better), and copy the files to your store.
Then, in Admin->Modules->Order Total, press remove on
Quantity Discounts, then press install. You will have to reconfigure
Quantity Discounts with your desired settings at this point.

Q: How do I tell if my stock is organized into subcategories?A: In the Admin page, go to Catalog -> Categories/Products, and click
on the category you're not sure about. If the entries that appear
on the next page have file folders to the left of their names,
then these are subcategories. If the products are directly below
these folders, then these folders are the parent folder numbers you
will use for category inclusions, exclusions and special discounts.
If what is below these subcategories is more subcategories, continue
drilling down until you get to products, and then go back one level.
This is the "parent" category you will need to use.

Q: Why is there a Quantity Discounts contribution in the first place? A: Zen Cart has a number of intrinsic discounting mechanisms: coupons,
specials, sales, group discounts, discounts via the products price
manager, etc.
While each of these fills a need, some retailers have different
discounting needs that cannot easily be met by any of these features.
The Quantity Discounts contribution was
designed to meet these needs.

Q: What is the Products Price Manager?A: The Products Price Manager implements Zen Cart's native Quantity Discounting mechanism.
Go to Admin->Catalog->Categories/Products, select a product, and
press the green $ sign. You are now in Products Price Manager.

Q: Is the Quantity Discounts contribution related to the native Quantity Discounting feature in Products Price Manager?A: No. The Quantity Discounts contribution has its own configuration (through
Modules->Order Total) and database entries, and is completely separate
from the Products Price Manager.

Q: What does the Quantity Discounts Contribution do that
Zen Cart's native Quantity Discounting mechanism doesn't? A: Installing the Quantity Discounts Contribution and trying it
out is the best way to get an understanding of the differences.
A partial list is:

Zen Cart's Quantity Discount feature

That Software Guy's Quantity Discount Contribution

Only allows per-product quantity discounts

Allows you to discount by item, by parent category, by all items
in the cart or by dollars spent.

Must be configured for every
product on which you want to offer quantity discounts

Quantity Discounts Contribution applies to all products (except those
you specifically exempt)

Allows unlimited numbers of discount levels, but discounts must be individually configured on each product

Allows only five discount levels in the admin panel
with the ability to add more in the setup() function;
discounting is applied to all products except where specified

Changing behavior involves modifying core code

Changing behavior involves modifying the contribution.

Marketing text is fixed, automatically generated

Marketing text may be customized to your needs, but must be added manually

Discounting by items purchased only

Discounting by items purchased *or* by dollars spent

Q: What does the Quantity Discounts Contribution using counting by currency do that
the Price Sensitive Discount doesn't? A: Here's the list:

Q: I have a table on my product info screen that looks like this (below). Is
this the Quantity Discounts Contribution? A: No - this is the native Quantity Discounts mechanism.
Go to Catalog->Categories/Products and find the product this that
shows this table. Press the green $ to enter Products Price Manager,
and delete these discounts; they are separate from (and will be applied
in addition to) any discounts you configure in the Quantity Discounts
Contribution.

Q: Why does the Quantity Discounts contribution not provide more
discounting levels in the Admin Screen? A: Having a fixed number of discounts in the Admin screen is a design consequence
of the Order Total implementation.
I thought five was a reasonable compromise.
Remember that a limitless
number of discount levels are available by calling the
add_extra_level_discount() function in setup().

Q: Why are there user exits for customization? Why didn't you put
this in the Admin panel?A: There are an endless number of combinations and permutations
of how people want discounting to work. Rather than design
a complicated user interface to present all these options,
I have provided a framework
that anyone with at least a beginner's knowledge of PHP should be able to
extend.

Q: I would like my discounts to show up in the shopping cart.
Why don't they?A: The way the Order Total modules work is that they show up at
checkout time. However, if you require the discounts to
show up in the shopping cart, you may wish to consider
purchasing the
Discount Preview
module for $30.

Alternately, you can indicate that you have a quantity discount policy
by adding to TEXT_INFORMATION in includes/languages/english/shopping_cart.php, and inform the user that the discounts will be
calculated (and visible) at checkout time.
Additionally, changing SUB_TITLE_SUB_TOTAL in the same file to
something like 'Sub-Total BEFORE Discount' will emphasize the fact that
a discount will be added at checkout time.

Q: I only want discounts applied to items in category 11 and 12. How do I do this?A: Update the function exclude_category() in includes/modules/order_total/ot_quantity_discount.php as follows:

Q: I want to double my regular discounts for category 9 if the customer buys 10 or more, and triple them if he buys 100 or more. How do I do this? A: Update the function apply_special_category_discount() in includes/modules/order_total/ot_quantity_discount.php as follows:

Q: I don't want discounts applied to items whose DESCRIPTION fields include the phrase "Sold:NET" or "No Quantity Discount". How do I do this? A: Update the function exclude_product() in includes/modules/order_total/ot_quantity_discount.php as follows:

Q: How can I present my discounting schedule on the product page? A:Create your custom template
if you haven't already done so.
Then customize the file includes/templates/template_default/templates/tpl_product_info_display.php
Look at the examples in marketing.
Add the one that fits your needs best to
tpl_product_info_display.php; start by putting it after
the product description (although the placement is a matter
of personal taste).

Q: Why are there four ways of getting the discounting information -
get_html_policy(), get_discount_info(), get_discount_parms() and get_discounted_prices()?
A: I was too nice to deprecate the first two. Everything can actually be derived from get_discount_parms(); the other functions exist simply as a convenience.

All product names, trademarks and registered trademarks are property of their respective owners. All company, product and service names used in this website are for identification purposes only.
My terms of use and privacy policy are pretty standard. I don't track you; I am not ad-supported. Here's my GDPR statement.