Base price of each item is kept in the products database. In fact, the three required fields for all items are code, price and description. Note that the default names are well suited for about all purposes, but you can change the actual names of the price and description columns using PriceField and DescriptionField directives.

Simple Pricing

The simplest method, as we've just hinted above, is flat pricing based on a fixed value in the products database. All you have to do is put item price in the price field and you're all set. If you want to change pricing based on quantity, size, color or arbitrary other factors, then read on.

Custom Pricing

Although the CommonAdjust directive provides a lot of options to describe pricing schemes, it might not match yours or you are just feeling more comfortable in writing code instead of delving through the following section. In this case you can simply write your own usertag calculating the price with the following settings for CommonAdjust and PriceField:

PriceField 0
CommonAdjust [calc-price]

The following example can be used to base your own usertag on. Product code and quantity for the price calculation can be found in the $item variable from the Vend::Interpolate namespace.

UserTag calc_price Routine <<EOR
sub {
	my ($code, $quantity, $set);

	$code = $item->{code};
	$quantity = $item->{quantity};

	$Tag->perl({tables => 'vendors_pricing'});

	$set = $Db{vendors_pricing}->query(q{select price from vendors_pricing where sku = '%s' order by price asc limit 1}, $code);

	if (@$set) {
		return $set->[0]->[0];
	} else {
		return 0;

"CommonAdjust" Pricing

A flexible, chained pricing scheme is available when CommonAdjust directive is set up.

CommonAdjust string, a term we'll use in this section, will be explained below.

Here are CommonAdjust usage rules, all assuming PriceField having the default value of price.

  • If CommonAdjust is set to any value (so, be it a valid CommonAdjust string or not), extended price adjustments are enabled

  • If the price field in the products database contains a CommonAdjust string (or a non-empty, non-zero value), it takes precedence over the default set with CommonAdjust

  • If the value of the CommonAdjust directive is set to a valid CommonAdjust string, and the price field is empty or specifically 0, then the CommonAdjust string will be used to set the price of the item. An effective way to make the price field empty is to use the PriceField directive to set field name to an invalid value, such as 0, none or noprice.

  • If no CommonAdjust strings are found, then the price will be 0, and subject to any later application of discounts

  • If, as a result of CommonAdjust string application, another CommonAdjust string is found, it will be re-parsed and the result applied. Chaining is retained; a fallback may be passed and will take effect

CommonAdjust Strings, Atoms and Settors

Using valid CommonAdjust strings, prices may be adjusted in several ways, but we first need to define "CommonAdjust string" as we've promised in the introduction. CommonAdjust strings are price definition strings which consist of individual actions called atoms. Atoms in turn consist of settors. Roughly, we could say atoms convey "control information" — they define when are contained settors applied, and settors define what is applied.

Price atoms can be of type final, chained and fallback.

  1. Final price atom is applied if it does not evaluate to zero

  2. Chained price atom is subject to further adjustment

  3. Fallback price atom is skipped if a previous chained price was not zero

Atom types are recognizable from the syntax used to define them.

  • Chained atom ends with a comma

  • Fallback atom has a leading semi-colon

  • Final atoms have no comma appended or semi-colon prepended

Atoms themselves are separated by whitespace and must be quoted if they themselves contain whitespace.

A settor is a mean by which the price is set. In other words, it is an expression contained in an atom which, when evaluated, affects the item price. Just as there are different types of atoms, there are different types of settors as well. Be aware that all settor types can yield new CommonAdjust strings, and it's quite possible to create endless loops this way. Therefore, the maximum number of initial CommonAdjust strings is 16, and there may be a maximum of 32 repeated CommonAdjust string iterations or loops before the price will return zero on an error. Those limits are only defaults and can be adjusted using general-purpose Limit config directive.


Common needs are easily shown but not so easily explained. Follow our pointers to examples if your vision starts to blur as you dive into the following section.

Let's take a look at available settor types. Settor types do not have distinguishable symbolic names, but their type is recognizable from the syntax used. Note that bold elements are required, while the rest are optional.

  1. -decimal

    A number which is applied to the current price value. For instance, a price of 10 and settor of 2 result in new current price of 12. May be a positive or negative decimal.

  2. -decimal%

    A number which is applied as a percentage of the current price value. May be a positive or negative number. For instance, a price of 10.00 and settor of -8% result in new current price of 9.20.

  3. table:column:key

    Causes a direct lookup in a database table. Table defaults to the products database entry for the item (subject, of course, to multiple products databases). Column argument must always be present, but you'd usually set it to price. (That scheme is often used in combination with setting PriceField to something different of price, because the price field would take precedence over the CommonAdjust string). The key defaults to the item SKU (except in a special case of attribute-based lookup).

  4. table:col1..col5,col10:key

    Causes a quantity lookup in database table which, again, defaults to products databases. Column specification is required and given as a set set of comma-separated fields (with ranges supported), looked up by the optional key. Key defaults to the item code as usual.

    Pay attention to the convenient range support; the following two settors are identical:


    With this quantity-based lookup, item quantity is compared to the numerical portion of the column name (leading non-digits are stripped). The price is then set to a value from the appropriate database column. The "appropriateness" is determined logically — since the numeric portion of the column name determines minimum quantity for the class, Interchange picks the "highest" class for which minimum quantity requirement is fullfiled (so that the item price is set according to quantity range).


    If the column value at the appropriate quantity level is blank, a zero cost will be returned from the atom. It is important to have all columns populated, because 0 is not appropriate.

    One excellent extra effect you can achive with this is "mix-and-match". It allows you to order different items which you put into the same "product group" to have their quantities added together to determine the appropriate price range.

  5. ==attribute:table:column:key

    Performs attribute-based lookup. Table specifies the table for lookup. Column defaults to the name of the attribute being looked for.

  6. & PERL_CODE The leading & character is stripped and the PERL_CODE block is passed to the equivalent of a [calc] tag. No Interchange tags can be used in there, but the tag_data() function ([data] tag, basically) is available, the current price is available in variable $s, and the current item details (code, quantity, price, and any attributes) are available inside the $item hash reference. All are found in Perl package Vend::Interpolate.

    That said,

    $Vend::Interpolate::item          is the current item hash reference
    $Vend::Interpolate::item->{code}  gives key for current item
    $Vend::Interpolate::item->{mv_ib} gives database ordered from
    $Vend::Interpolate::item->{...}   gives specified attribute's value

  7. [ITL_CODE] or __VARIABLE__

    Causes ITL_CODE to be parsed for Interchange tags with variable substitution, but without locale substitution. You may also define a price in a Variable.

  8. $

    Causes Interchange to look in the mv_price attribute of the shopping cart, and apply that price as the final price, if it exists. The attribute must be of numerical value.

  9. >>word

    Causes Interchange to literally return word as price. This is not useful in pricing, as it will evaluate to zero. But when CommonAdjust is also used for shipping, it is a way of re-directing shipping modes.

  10. word

    The value word (which must be unique — not match any other settors) is available as a key only for the next lookup. If that next settor is a database lookup and it contains a dollar sign ($), word will be substituted for it.

  11. (settor)

    The value returned by settor will be available as key for the next lookup. If that next settor is a database lookup and it contains a dollar sign ($), word will be substituted for it.

For actual examples, please see the CommonAdjust reference page.

Product discounts

For product discount settings, see the discount glossary entry.

DocBook! Interchange!