discount — implement per-customer item or order discounts


Attribute Pos. Req. Default Description
code Yes      
discount_space | space        
interpolate     0 interpolate input?
reparse     1 interpolate output?
hide     0 Hide the tag return value?


The tag is used to implement per-customer discounts. Discounts can be applied to individual items, groups of items, or total orders.

The tag accepts Perl code in its body. Two special variables, $q and $s, are available and represent item quantity and base price.

Perl variables can be shared among [calc] blocks and the [discount] tag within the same page, allowing for greater flexibility. See the section called “EXAMPLES”.

For an introduction and theory behind item discounts, please see the discount glossary entry.


This tag does not appear to be affected by, or affect, the rest of Interchange.


Example: Straight 20% discount on all items

[discount ALL_ITEMS] $s * .8 [/discount]

Or the same as above, with named attributes:

[discount code=ALL_ITEMS] $s * .8 [/discount]

Example: Discount of 25% for an individual item

To take 25% off of item SKU 00-342, use:

[discount 00-342] $s * .75 [/discount]

Example: Discount of 25% for an individual item, only if quantity ordered is 1

[discount 00-342] $q == 1 ? $s * 0.75 : $s [/discount]

Example: A discount of 5 on entire order

[discount ENTIRE_ORDER] $s - 5 [/discount]

Example: Resetting discounts

To reset a discount, simply set it to the empty string:

[discount ALL_ITEMS][/discount]

Example: Dynamic discounts using Perl

Perl code can, of course, be used to apply the discounts. Sometimes, this needs to include some pre-processing which you need to do outside the [discount] tag. You can freely do this within the [calc] tag, as the values will be retained and visible inside [discount]. For each item ordered, this example gives a 10% discount for a minimum quantity of 2, with 5% more for each "extra quantity" (but up to a maximum discount of 30%):

    $totalq{"[item-code]"} += [item-quantity];
  return '';

  [discount code="[item-code]"]
    return ($s)       if $totalq{"[item-code]"} == 1;
    return ($s * .70) if $totalq{"[item-code]"} > 6;
    return ($s * ( 1 - 0.05 * $totalq{"[item-code]"} ));

Example: Applying discount to a specific "instance" within ordered quantity

Here is an example of a special discount for item code 00-343 which sets the price of the second "instance" ordered to 0.01:

[discount 00-343]
  return $s if $q == 1;
  my $p = $s/$q;
  my $t = ($q - 1) * $p;
  $t .= 0.01;
  return $t;

Example: Displaying the discount amount received

If you want to display the discount amount to the user, simply use the item-discount tag:

  Discount for [item-code]: [item-discount]

Example: Displaying the total discount

When you want to display the total discount for an item, you need to use [calc]:

Total discount applied to [item-code] is: [currency][calc]
                                       [item-discount noformat=1] * [item-quantity]

Example: Using wholesale price for special promotions

In the following example, items with modifier "promotion" receive the price defined in products:wholesale instead of products:price.

[perl tables='products']
my %seen = ();

foreach $item (@{$Items}) {
  next unless $item->{promotion};
  next if $seen{$item->{code}}++;

  my $promo_price = $Tag->data('products','wholesale',$item->{code});

  $Session->{discount}->{$item->{code}} = "$promo_price * \$q";



discount is available in Interchange versions:

4.6.0-5.9.0 (git-head)


Interchange 5.9.0:

Source: code/SystemTag/discount.coretag
Lines: 66

# Copyright 2002-2007 Interchange Development Group and others
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.  See the LICENSE file for details.
# $Id: discount.coretag,v 1.7 2007-03-30 23:40:49 pajamian Exp $

UserTag discount            Order        code
UserTag discount            AddAttr
UserTag discount            attrAlias    space discount_space
UserTag discount            hasEndTag
UserTag discount            PosNumber    1
UserTag discount            Version      $Revision: 1.7 $
UserTag discount            Routine      <<EOR

# Sets the value of a discount field
sub {
my($code, $opt, $value) = @_;

# API compatibility
if(! ref $opt) {
  $value = $opt;
  $opt = {};

if (! ($::Discounts
    and $Vend::Session->{discount_space}
    and $Vend::Session->{discount}
    and $Vend::DiscountSpaceName)) {
     = $Vend::Session->{discount}
    = $Vend::Session->{discount_space}{ $Vend::DiscountSpaceName = 'main' }
    ||= ($Vend::Session->{discount} || {});

my $dspace;
if ($Vend::Cfg->{DiscountSpacesOn} and $dspace = $opt->{discount_space}) {
  $dspace = $Vend::Session->{discount_space}{$dspace} ||= {};
else {
  $dspace = $::Discounts;

if($opt->{subtract}) {
  $value = <<EOF;
my \$tmp = \$s - $opt->{subtract};
\$tmp = 0 if \$tmp < 0;
return \$tmp;
elsif ($opt->{level}) {
  $value = <<EOF;
return (\$s * \$q) if \$q < $opt->{level};
my \$tmp = \$s / \$q;
return \$s - \$tmp;

$dspace->{$code} = $value;
delete $dspace->{$code}
  unless defined $value and $value;
return '';


Interchange Development Group


DiscountSpacesOn(7ic), DiscountSpaceVar(7ic)

DocBook! Interchange!