Rules Examples for Shipping by Rules

Examples for "Shipping by Rules" for VirtueMart 2

Unless explicitly mentioned, all examples will only consider one country set. Also note that the Name=.... rule parts are optional and can be left out. Similarly, the shipping costs can be written without the leading Shipping= prefix. Also note that all variables are case-insensitive, so they can also be written in all lower-case.
Most of the rules here can be written in more than one way.

Fixed, flatrate shipping of 5€ per order, no free shipping, no minimum etc.


Fixed, flatrate shipping of 5€ per order, free shipping from 100€, no minimum etc.

Name=Free shipping above 100€;100<=Amount;Shipping=0

Different shipping costs for various postal code ranges (only orders up to 10kg)

Name=Vienna; 1000<=ZIP<1999; weight<10; Shipping=10
Name=Lower Austria; 2000<=ZIP<3999; weight<10; Shipping=25
Name=Upper Austria; 4000<=ZIP<4999; weight<10; Shipping=30

First article 3€, each additional article 1€, free shipping for 5 or more articles (see also advanced below)

articles==1; Shipping=3
articles==2; 4
articles==3; 5
articles==4; 6
articles>=5; Shipping=0

Condition on the maximum length/width (e.g. because a different kind of truck needs to be used for delivery)

Name=Delivery by Van; MaxLength<200; MaxWidth<100; Shipping=25
Name=Delivery by Truck; MaxLength>=200; Shipping=75 Name=Delivery by Truck; MaxWidth>=100; Shipping=75

Net Shipping cost calculated from given gross shipping amount charged to the user

When using ShipingWithTax instead of Shipping, the plugin will use the given amount as the total amount including taxes, which will be charged to the user. The tax amount and the net amount (without taxes) will be calculated automatically.

Name=Shipping cost given with taxes; Amount<100; ShippingWithTax=5

Different shipping costs to Hawaii and Alaska than to the rest of the USA

Simply distinguish Hawaii and Alaska from the mainland by conditions on the postal code. Remember, the first matching rule will be used, so the rest of the USA does not need a check for the ZIP code any more. In the advanced version, the two rules for Hawaii and Alaska can be merged using the OR operator.

Name=Shipping to Hawaii; 96700<=ZIP<96900; Shipping=8.95
Name=Shipping to Alaska; 99500<=ZIP; Shipping=8.95
Name=Shipping to rest of USA; Shipping=8.95

Rule name with special characters (semicolon, etc.)

The rule name typically can not contain a semicolon, as this is the separator of the different rule parts. However, by wrapping the name in quotes "...", one can still use it in the name. The rule name is always taken as a verbatim string, and cannot contain any HTML:

Name="A rule; condition is Amount<5"; Amount<5; Shipping=10

Handling some alphanumeric Post Codes

In the Netherlands, the postcode has the form 0000AA (i.e. four digits and two letters, where the two letters indicate the district and street). One can use the variables ZIP2 and ZIP4 (the first two and first four characters of the postcode) to write rules as one would do with any numeric post codes. Both rules yield the exact same result:

Name=Netherlands - Haarlem; ZIP2==20; Shipping=10
Name=Netherlands - Haarlem alternativ; 2000<=ZIP4<2999; Shipping=1

No shipping if certain conditions are met

By setting the shipping costs to NoShipping, the plugin will not check any more rules and will NOT offer any shipping at all. This can be used to exclude e.g. some islands or heavy packages from shipping:

Name=No shipping of heavy packages to a certain area; Weight>100; 8000<=ZIP<9000; NoShipping
Name=Flat rate otherwise; Shipping=15

 Displaying the weight in the rule name

The available variables can also be displayed in the rule names by {varname}:

Name=Order of weight {weight}, {articles} articles of {products} products; Shipping=3

 Require the customer to enter a postcode before shipping costs are shown

If no ZIP code was entered yet, the ZIP variable will behave as if a value of 0 was entered. So you can simply exclude shipping in this case:

Name=Please enter a valid ZIP to get a shipping rate; ZIP<=0; NoShipping
Name=Real Shipping; 1000<=ZIP<1999; Shipping=1



Examples for "Advanced Shipping by Rules" for VirtueMart 2

First article 3€, each additional article 1€ additional


Weight-dependent shipping, 5€ per kg (calculated exactly)


Weight-dependent shipping, 5€ per kg (partial kg count full, i.e. the weight is rounded up)

Starting from version 3.0 of the plugin, the ceil(..) function is available to round the weight up to the next full integer:


Weight-dependent shipping, different rates

Weight<5;  Shipping=10*Weight
Weight<10; Shipping=8*Weight
Weight<15; Shipping=7*Weight
Name=Shipping of 15kg and above; Shipping=6*Weight

Weight-dependent shipping with weight bands

Consider a weight-based shipping cost structure with weight bands. For example, assume that the first 5kg will cost 5€/kg, the next 5kg will cost only 4€/kg, and everything above 10kg will cost 3€/kg. So an order with 7.5kg will cost 35€ (25€ for the first 5kg at 5€/kg, and 10€ for the remaining 2.5kg at 4€/kg), while an order of 20kg will cost 75€.
Such a cost structure can be expressed by the following rules:

Weight<5; 5*Weight
5<=Weight<10; (5*5)+4*(Weight-5)
10<=Weight; (5*5)+(4*5)+3*(Weight-10)

Of course, the cost for the last weight category can also be written as 45+3*(Weight-10) or 15+3*Weight, but that does not display the actual calculation structure.

DEPRECATED: Shipping costs per full kg (Before version 3.0 of the plugin)

Some shipping structures calculate shipping costs either per full kg (e.g. the weight rounded down) or per started kg (the weight rounded up). Unfortunately, there is currently no dedicated function to round a variable in the shipping costs. However, you can achieve the same effect using the modulo operator (%):
   o) Rounding down can be achieved as:


   o) Rounding up can be achieved as:


However, the last example does not work for integer weights (e.g. if the weight is exactly 3kg, the result will be 4). One possibility to is subtract a tiny amount before the rounding:


Shipping costs per full kg (version 3.0 or later of the plugin)

Some shipping structures calculate shipping costs either per full kg (e.g. the weight rounded down) or per started kg (the weight rounded up). Starting with version 3.0, the round(...), floor(...) and ceil(...) functions are available to round, round down or up:
   o) Rounding down can be achieved as (e.g. floor(1.9) yields 1, floor(2.1) yields 2):


   o) Rounding up (to the next integer value) can be achieved as:


Free shipping if the average price per article is at least 5€

Name=Free shipping for average price above 5€; amount/articles >= 5; Shipping=0

 Rule matching several postal code ranges

Notice that the OR operator is implemented only in the advanced version.

Name=Rule for several postcodes; 4000<=ZIP<=4229 OR 4300<=ZIP<=4307 OR 4500<=ZIP<=4575; Shipping=12.95

 Offering USPS international shipping (condition on Length+2*(Width+Height) of the box) with erring on the safe side

The USPS apparently has an upper bound for international shipping. In particular, Length+2*(Width+Height) of the box needs to be below a certain threshold. Now, the plugin can not exactly determine how large your packaging box will be, but a nice upper bound can be obtained by simply stacking all products, one on top of each other (this ignores that you can usually put two or more products next to each other). The length of the resulting box will be MaxLength, the width will be MaxWidth, and the height will be TotalHeight. This is a crude upper bound, but if that upper bound already fulfills the condition, then the real box will fulfill them for sure. (On the other hand, if the upper bound does not fulfill the condition, you might still be able to optimize the packaging to fulfill the conditions, but the plugin cannot easily detect this. Mathematically, this is an optimization problem, and far from simple!)
Using this upper bound, you can now offer USPS shipping if that upper bound fulfills the conditions:
Name=USPS upper bound fulfilled; MaxLength+2*(MaxWidth+TotalHeight)<80; Shipping=25
If the condition is not fulfilled, the plugin does not offer a shipping method. But if it is fulfilled, the final box will be below the threshold for sure. So this approach errs on the safe side, insofar as it simply does not offer USPS shipping when it's not obvious that the USPS bounds are met. However, if it offers USPS shipping, the bounds are definitely met.

Checking whether a variable begins with a certain string or number

The ~ (tilde) operator checks wether the left and the right side coincide at the beginning (all characters of the shorter term need to be at the beginning of the longer term):

Name=ZIP starts with string CW1; ZIP~"CW1"; Shipping=10
Name=ZIP starts with numbers 123; ZIP~123; Shipping=1

Canadian postal codes

For Canadian postal codes (alphanumeric), there are five dedicated variables available for the conditions: Canada_FSA, Canada_Area, Canada_Urban, Canada_Subarea and Canada_LDU.

Name=Free Shipping to British Columbia; Canada_Area=="V"; Shipping=0
Name=Chicoutimi (Quebec); Canada_Area=="G" AND Canada_Urban==7 AND "G"<=Canada_Subarea<="K"; Shipping=5
Name=Saint-Joseph-de-Coleraine; Canada_FSA=="G0N" AND Canada_LDU=="1B0"; Shipping=7

Please notice that in the third rule, the separate checks for FSA and LDU are better than a check for ZIP=="G0N 1B0", since it will also work if the user enters multiple spaces between the FSA and the LSU.

UK postal codes

For UK postal codes (alphanumeric of the form "A[A]0[0][A] 0AA") there are five dedicated variables available if a postal code of the appropriate format is detected: UK_Outward, UK_Area, UK_District, UK_Subdistrict and UK_Inward.

Name="Free shipping to Birmingham"; UK_Area=="B"; Shipping=0 
Name="Free shipping to parts of Walsall"; UK_Area=="WS" AND 15<=UK_District; Shipping=0
Name=No Shipping to PO boxes in North London; UK_Outward=="N1P"; NoShipping

For British overseas territories, only the outward and the inward parts are assigned, while the area, district and subdistrict variables are empty.

Name="Free shipping to Gibraltar"; UK_Outward=="GX11" AND UK_Inward=="1AA"; Shipping=0 
Name="No shipping to Falklands"; UK_Outward=="FIQQ"; NoShipping

Differentiate shipping by state


You can use the Country, Country2, Country3, State, State2 and State3 variables to distinguish various countries in the country set and also the various states of the countries:

Name="Free shipping to California"; State2 == "CA"; Shipping=0 
Name="Flat rate to some other states"; state2 in list("TX", "WS", "MS"); Shipping=5

Free shipping if a certain product is purchased

The SKUs variable (a list of all skus of the order) can be used to check whether a particular product is included in the order.

Name="Free shipping if product A is purchased"; "your-sku" in SKUs; Shipping=0 

Shipping costs depending on categories in the cart

It is possible to make shipping costs depend on whether only products of a certain category or whether at least one product of a certain category are. The variable Categories provides a list of all categories of the products in the cart. You can use a condition "123 in Categories" to check whether the category with the ID 123 (see the virtuemart backend for the ID of your categories) is in the cart, and you can use the condition "Categories == list(123)" to check whether the category with ID 123 is the only category in the cart.

For example, if you want to prohibit shipping if a category is present, simply use the NoShipping indicator:

Name="Shipping not abroad not available for frozen items"; 1234 in Categories; NoShipping 
If you want to provide free shipping if only items of category 1234 are in the cart (e.g. only downloadable items, or only course registrations, or only small items indicated by a certain category), you can use the following rule:
Name="Free shipping of Books only"; Categories==list(1234); Shipping=0 
Starting with version 4.0 of the plugin, there are some more utility function to write conditions involving lists.

Shipping costs depending on products in the cart

Just like you can depend on the categories in the cart using the Categories variable (see above), one can depend on the individual articles in the cart by using the list variable SKUs:
Name=Free shipping if Product A is purchased (among others); "product-a" in SKUs; Shipping=0


 Notice, however, that it is currently no way to determine the quantity or the amount of a certain product in the cart. All the plugin provides is the list of SKUs in the cart.

VM - Shopping cart


Cart empty

Login Formular