Product Pricing Rules (with screencasts)

Discounts in Drupal Commerce


  • Create a discount using a rule
  • Create a weekend (date-based) sale discount using a rule
  • Create a tag-based weekend sale discount using a rule

Simple Discount

An example of a simple discount: You want to take 10% off everything in your store until further notice.

  1. Go to Store -> Configuration -> Product Pricing Rules
  2. Click "Add a pricing rule"
  3. Give your rule a name
  4. Under "Actions" click "Add Action"
  5. Under "Commmerce Line Item" choose "Multiply the Unit Price by Some Amount"
  6. The data selector should be "line_item"
  7. The amount should be .9 (in other words, multiply the price by .9).
  8. Now all products have 10% taken off of them.

Adding a Date Window to the Discount

Now we need to take our simple discount and make it effective for just one period of time. We'll use the "Simple Discount" approach above, but now we'll make it only applicable during this upcoming weekend.

  1. Create a discount as in the "Simple Discount" above.
  2. This time we'll add two conditions to the product pricing rule:
    • System Date is Greater than Midnight April 23
    • System Date is Less than Midnight April 25.

That's it. To test in a Linux environment you can temporarily change the server date using

sudo date MMDDHHMM

for example

sudo date 04231237

Don't forget to change the time back. Changing it like this makes a big mess of things.
sudo ntpdate

Drupal Commerce Date-Based Discounts from Randy Fay on Vimeo.

Adding a Taxonomy Term To Drive Discounts

Now we're going to go much farther. We'll add a taxonomy term to our product entity to determine which sale events it should be subject to, and also add a date range.

There is a rather major complexity in this one. Rules does not have the ability currently to follow references (like product references and term references) very well, so we have to jump through some hoops to get access to them. It is do-able, but a bit mind-bending. We hope to see the rules issue relating to this land soon, but for now we have to use the tools we have.

  1. Add a taxonomy vocabulary called "Sales Events"
  2. Add a term to the vocabulary called "April Weekend Madness Sale"
  3. Add a term reference field to the "Product" product type referencing "Sales Events"
  4. Set the "Sales Events" value in one or more products to "April Weekend Madness Sale". We're essentially marking them for this sale.
  5. Create a rules component that determines whether the weekend is here:
    • Administer -> Configuration -> Workflow -> Rules -> Components -> Add new component.
    • Component plugin is "Condition set (AND)"
    • Name is "Weekend of April 23"
    • Continue
    • Add two conditions which do data comparison against system date to select the weekend timeframe just as we did in the earlier, simpler example.
  6. Create another rules component that accepts a product as a variable which will determine whether the product is marked to be part of the sale. Note that the first three conditions we're adding here are just to force Rules to understand how to traverse the data. They seem quite complex at first, but it's actually just cookbook stuff.
    • Administer -> Configuration -> Workflow -> Rules -> Components -> Add new component.
    • Condition set (AND)
    • Name: "Product is on sale"
    • Variables: Data type "Entity - Product", Label "Product", Machine name "product"
    • Add a condition
    • Entity has field
    • Data selector: product
    • Field: field_sales_event
    • Add another condition
    • Data value is empty
    • Data selector: product:field-sales-event
    • Click negate.
    • Add another condition
    • Data value is empty
    • Data selector: product:field-sales-event:tid
    • Click negate.
    • Add a final condition
    • Data comparison
    • Data Selector: product:field-sales-event:tid
    • Value equals (the tid of the taxonomy term we created)
  7. Now we'll create a product pricing rule at Store -> Configuration -> Product Pricing Rules.

    • Add a pricing rule with the name "April weekend sale"
    • Under actions, add an action to multiply the price by 0.8 (we'll give them an even bigger discount than we did last time!)
    • Under conditions:
    • Add condition "Component: April Weekend Sale", which will add the date-based conditions to our rule.
    • Add condition "Entity has field" (This is just to bring the product into scope due to the Rules issue mentioned above.)
      • Data selector: line-item
      • Field: commerce_product
    • Add condition "Component: Product is on sale."
      • Data selector: line-item:commerce-product

    Now we have a product pricing rule that does two things. First it checks the conditions in the "Weekend of April 23" to see if the date is correct, and then it uses the "Product is on sale" component (to which we pass the line item's product) to determine whether the item is on this sale.

    We can change the server date to experiment, and should see that the products we marked now have their sale prices.

Drupal Commerce Complex Pricing Rules from Randy Fay on Vimeo.


guy_schneerson guy_schneerson on June 7, 2011

I came to the conclusion that bringing user created commerce product fields into scope using Rules 2 (as described above) only makes them available to conditions. If you need to use them in actions you will need to use the hook_entity_property_info_alter() to add metadata to the commerce_product to let rules know of their existence.

guy_schneerson guy_schneerson on July 26, 2011

Looks to me like it only works if the field is a direct property of the entity the event is on.
So if the event is “After updating an existing commerce product” and you bring the stock field into scope using Entity has field, then you get access to it in actions

However if you are on a pricing rule event “Calculating the sell price of a product” (line item) end you bring the product and then the stock field using two “Entity has field” conditions, then you don’t get access ):

in the second case i am still convinced that the only way is to use hook_entity_property_info_alter().

EuroDomenii on July 25, 2011

An workaround is to use rules actions with php evaluation. Don't forget to enable the core module PHP filter.
Here is a sample code, for the use case Adding a Taxonomy Term To Drive Discounts, see also
The rule is: event Calculating the sell price of a product, Conditions Order is a shopping cart,Parameter: Order: [line-item:order], Actions Multiply the unit price by some amount,Parameter: line-item:line-item-id
At amount , click switch to data selection

This code works only with Conditions Order is a shopping cart,Parameter: Order: [line-item:order], because before adding to cart line item object doesn't exists.
In php evaluation input the following code:

['0'] = $value; #$value from rules with data selector line-item:line-item-id
$van_product_ent=entity_load('commerce_product', $van_product_id);
$van_tags = $van_product_ent[$van_product_id[0]]->field_tag_subdomenii['und'];  
     foreach (
$van_tags as $van_tag  ) {
$van_tag_objects[] =  taxonomy_term_load($van_tag['tid']);
     #Return whatever values depending on the taxonomy found...

Tom Geller on September 21, 2011

Hi, Randy -- great video. I really appreciate that you've made these.

I went through the VAT process, but it showed prices with the discount already in place -- e.g. a $10 item with a 20% discount simply appears as $8 throughout the site. Then on the checkout page it looks odd, even in your screencast. (Look at 5:48: The three items are $9 each, and it adds up to $30?).

But I found that it works just fine if I create a negative sales tax. I don't have to create a new Tax type, either -- just use the existing sales tax type. Then the price shows up as $10 in the product display node, $10 on the checkout page, and the discount is finally taken as a line item in the checkout.

Or am I missing something?

rfay Randy Fay on September 21, 2011

It sounds like you've found a technique that works fine...

A lot of people want to show the actual discount in the cart and with pricing rules, and are working on ways to do that just with formatters. I'll pay attention and try to post links to those issues when I see them.

Tom Geller on September 21, 2011

That's fair -- it seems to just be a matter of taste. I'll mention that in the video about discounts, and will acknowledge you for this trick. :)

Tom Geller on September 22, 2011

Hi, Randy! Yes, I'm still working on it, and will record in early November. (I can't say when it'll come out: There's a long post-production process.)

I actually sent a note to Greg with some questions a few days ago, but it might have been to an old address. I'll send you the same note through your d.o account. (Your timing is perfect: I'm running into a bit of a wall.)



timodwhit on November 16, 2011

Great Screen Casts.

My question goes a step further on these: I imagine this is fairly common need, but haven't seen it addressed.

I'm filling popcorn tins and the larger tins need to be fillable with three flavors. The pricing however changes dependent on what flavors are selected.

For example:

Caramel, Cheese, Movie = 40;
Caramel, Cheese = 45
Caramel = 45
Movie = 30
Caramel, Movie, Kettle = 35

Using taxonomy terms as a line item makes the product very easy to create and I was able to limit it to three selections.

The problem I am facing is setting up the rules: I get to the second "NOT Data Value is empty" and I'm presented 4 choices. "product:field-flava:0", "product:field-flava:1", "product:field-flava:2"; "product:field-flava:3".

After selecting one and negating it: I add a third step "NOT Data Value is empty" and I choose "product:field-flava:item 0:tid" and then choose the appropriate term ID in the "Compare Data" condition.

The problem I am facing is that I don't know what "product:field-flava:0", "product:field-flava:1", "product:field-flava:2", "product:field-flava:3"; are equal to. I would try to trouble shoot this, but the possibility for error in steps I wouldn't know where I went wrong.

Is "product:field-flava:0" when no choices are selected, is "product:field-flava:1" the first selection, and so on?

If you could clarify, I would greatly appreciate and once my product rules are set up and working, I wouldn't mind writing a FAQ page for this because the rules procedure is fairly complex. Thank you!

timodwhit on November 23, 2011

Figured this out. rfay recommends using the process

• Data selector: product:field-sales-event
• Click negate.
• Add another condition
• Data value is empty
• Data selector: product:field-sales-event:tid
• Click negate.
• Add a final condition
• Data comparison
• Data Selector: product:field-sales-event:tid... etc.

I changed the procedure slightly and came up with a pretty decent pricing scheme. I exported the rules that I used to achieve the results I needed here.

It is a pretty ugly rule that I am sure can be cleaned up. But the quick and dirty of it work.

Thanks for the original screencast.

Brian on November 25, 2011

Thanks for the detailed description. Usually I only have one or two discounted products for promotion purposes.

Is there a way to just rule one Product for discount? Like

If SKU = 12345 then multiply .5

I haven't found the Producct ID/SKU in the conditions.

rfay Randy Fay on November 25, 2011

Sure. Create a product pricing rule. Add conditions:

Condition: Entity has field, Commerce Line Item, Commerce product
Condition: Data Comparison, commerce-line-item:commerce-product:sku, Comparison =, Data "SOMESKU"

Action: Set the unit price to a certain amount, commerce_line_item, value (in minor units, like cents), component (probably discount)

timodwhit on November 26, 2011

Hey Randy,

Thanks for the description above: would you be able to do something similar if you knew the sku structure? This is just a thought question, of no real importance.

Lets say the sku = xx_xx_xx

The first two designate type of item. The second two designate size of item. The third two designate color

Would it be possible to use the data comparison to select the item based simply on the specific digit of a sku?


rfay Randy Fay on November 27, 2011

Sure. You should experiment with this. But you can match the beginning of the sku. If you use php snippets you could do far more significant things with processing the sku based on meaningful components.

bengt on December 10, 2011

Thanks Randy for all your help here and everywhere!

I have read this FAQ and a lot of other posts, but I still have questions concerning using custom fields with pricing rules. Probably it is something I miss...

1. Is the Rules issue solved? I am using 7.x-2.0 (2011-Oct-11).

2. It seems as if people are saying that it is solved, but still I can't use custom fields when I use product pricing rules with the event "Calculating the sell price of a product" (with other events it works fine). Yes, I can find my custom field when I under Conditions choose "Entity has field" and choose my field, but that doesn't seem to help me in finding it for other Conditions or Actions.

3. My scenario: I want to apply a discount on products with a certain taxonomy term (the term part is not the problem). That term is related, so to speak, to another product custom field (let's call it "field_discount_value") where the admin puts a value, e.g. "25" (for 25% discount). The pricing rule I try to create should use this custom field value to determine how much discount the product should have. But I am, as I said, unable to find my custom field in conditions (except for in "Entity has field") and actions. I don't want to create a term for every possible discount value. What do I miss here?

rfay Randy Fay on December 12, 2011

1. Custom fields still require you to use conditions like "Entity has field" or "Data Comparison -> Type". [This FAQ]( explains it; the rules issue is long since fixed, but I think we have to live with this approach. All screencasts that you find will use this approach, so there's lots of models.
3. There are plenty of examples of doing this using rules, including recent screencasts on Just today [this comment]( explained a similar use case.

Good luck!

bengt on December 13, 2011

It works fine! Thanks for the references and the clarifications. I had missed the "Data Comparison -> Type" condition and also that you sometimes may need two (or more?) "scope-conditions".

camorim on February 26, 2012

First of all: Great tutorial!
I'm facing a slightly different problem/use case. Maybe I'm doing it wrong on the architectural side but I'll try to explain it as clear as I can.

I'm preparing a small commerce site intended to sell training courses. Each course has 3 "standard" formats:
- one day "live" on class room
- two month web-based with training materials and online support
- one month web-based with training materials and online support
As the contents and purpose of all the three variants are the same, my idea was to have a single product (SKU) with a base price (let's say 100$) and expose three different "product displays" each one with their own discount. As an example, the one day would get the base price (100), the two month online would get a 25% off (75) and the one month online edition a 50% off (50).

As an attempt to get this going I added on each of the "product displays" a new field called field_discount. This field is a list with the above mentioned variants.
My problem is that I don't seem to get to the field_discount on the price calculation rule. I've tried every "data comparison" and "entity has field" I could remember of, but it still only exposes fields that are part of the "product" and not of the "product displays". So, I'm unable to apply a separate discount to a "product display".

I know that maybe the solution is to create one distinct SKU for each variant, but it seems a lost of time to make a complete copy of an SKU only to modify the price.

Is there any solution to this particular use case?

Thanks in advance,

ñull on February 2, 2012

I used the simple discount example and I have two questions.

  • I get a flooded with watchdog messages like this
    rules 02.02.2012 - 14:22 Rules debug information: " Reacting on event....
    How can I get rid of them?
  • These messages proof that a lot is going on behind the scenes and I was wondering if performance is hit by this method? I would think that for each page load where prices are loaded the rule kicks in and that should make things slower.


zapple on March 4, 2012

Not sure if this is the right place to post this...

I'm just wondering if I can do the following with rules (rather than having to write a module):

* I'm building a site where the prices of products update every minute.
* When a user adds a product into their cart I want that price to 'freeze'.
* So when the product updates in the background the old prices remains in the cart.
* The price remains frozen for up to two hours

The trouble I'm having is setting the variable. It would seem the best place would be to set the variable upon adding an item to the cart. But I need another rule for calculating the sell price for the user. The variable isn't carried from one rule to another.

Any suggestions or advice would be greatly appreciated.


olivier_a on March 12, 2012

As a distributor, I purchase products from different providers. For each provider, I want to calculate price with 2 coefficients (for example: 1.5 and 2). The providers are defined with taxonomy terms, that contents the field : field_price_coeffient (real with 2 values).
In product, I've defined a new product type with fields to identify the provider (field_provider as referenced term to the vocabulary 'providers') and coefficient code (field_coefficient_code). This last field contents integer that identify the coefficient to take for a specific provider (for ex.: value 0 -> 1.5, value 1 -> 2).

Could you help to create a "Product pricing rule" ?

I've tried to bring the fields into scoop with conditions
Entity is of type
Parameter: Entity: [commerce-line-item], Entity type: Commerce Product
Entity has field
Parameter: Entity: [commerce-line-item], Field: commerce_line_items
Parameter: Entity: [commerce-line-item], Field: field_provider
Parameter: Entity: [commerce-line-item], Field: field_coefficient_code
Parameter: Entity: [commerce-line-item], Field: commerce_price

and component :
Commercer Line Item/Line Item/line_item/parameter
Taxonomy term/Provider/field_provider/parameter
Text/Coefficient code/coefficient_code/parameter
Decimal number/Provider coefficient value depending on coefficient_code/parameter
Price/Calculated price/calculated_price/provided

But finaly I can't define any actions as I don't see the fields into scoop.
Could you help to create this rule ?

timodwhit on March 12, 2012


I'm not sure exactly what you are doing, it seems like you have a lot going on here. But you're rule should be: "Calculating the sell price of a product".

Conditions: Entity has field:
P: [commerce-line-item] F: commerce-product

Entity has field
P: [commerce-line-item] F: field_coefficient_code

Here I would do a data comparison:

field_coefficient_code = (something)

set the unit price to a specific amount.

Does that help?

olivier_a on March 12, 2012

When I try to add the data comparison, I don't see the field_coefficient_code in the data selectors.
And if I try something like :

Data selector
The data is invalid.

timodwhit on March 12, 2012

hmmm... there could be multiple reasons for this:

Try this:

Make a component: condition set (and).

Data type=> commerce Product
Label => Product
machine name => product

Entity has field:
P: product

Data Value is Empty:
F: field_coefficient_code

Data Value is Empty:

Data Comparison:
You choose

Then insert this component into the rule

olivier_a on March 27, 2012

I've finally found a rule that does part of job. For some reason, it works if I do the 'data comparison' before 'Entity has field'. And also I can check for only one Entity field. Hopefully the other fields appear into scoop.

So the nice thing is that I can modify price with a data stores as field ('field-price-coefficient') in my taxonomy 'provider'. Here is the rule :

{ "rules_price_calculation_with_coefficient_in_taxonomy_term_field" : {
"LABEL" : "price calculation",
"PLUGIN" : "reaction rule",
"REQUIRES" : [ "rules", "entity" ],
"ON" : [ "commerce_product_presave" ],
"IF" : [
{ "entity_is_of_type" : { "entity" : [ "commerce-product" ], "type" : "commerce_product" } },
{ "data_is" : { "data" : [ "commerce-product:type" ], "value" : "my_special_product_type" } },
{ "entity_has_field" : { "entity" : [ "commerce-product" ], "field" : "field_provider_price" } },
{ "NOT data_is_empty" : { "data" : [ "commerce-product:field-provider-price" ] } }
"DO" : [
{ "variable_add" : {
"USING" : {
"type" : "integer",
"value" : [ "commerce-product:field-coefficient-code" ]
"PROVIDE" : { "variable_added" : { "variable_coefficient_code" : "Variable Coefficient Code" } }
{ "data_calc" : {
"USING" : {
"input_1" : [ "commerce-product:field-provider-price:amount" ],
"op" : "*",
"input_2" : [ "commerce-product:field-provider:field-price-coefficient:0" ]
"PROVIDE" : { "result" : { "result" : "Calculation result" } }
{ "data_set" : {
"data" : [ "commerce-product:commerce-price:amount" ],
"value" : [ "result" ]

For the moment, the price calculation only works with one price coefficient:
"input_2" : [ "commerce-product:field-provider:field-price-coefficient:0" ]

I'm still looking for a way to select one coefficient between up to 4 coefficients, based on the field 'commerce-product:field-coefficient-code' (an integer that refers to the coefficient number. '0' gives the first coefficient,... ).

Something like
"input_2" : [ "commerce-product:field-provider:field-price-coefficient:" & "commerce-product:field-coefficient-code" ]

I don't have found that right synthax (all the arguments are available to write the action of the rule).

Kirk Monteux on March 15, 2012

I have setup a pricing rule with "extra rules conditions" to rule the pricing of the total item amount of digital products.

Works fine so far.

Except the sidebar cart block doesn't show any discounts. Is this a bug or did I something wrong?



garyg on December 24, 2012

Similar issue. If a product add to cart form is present on a page the cart block will show the retail price. On any other page the cart form shows the discounted price per the rules.
Did you find a solution?

bendev on April 22, 2012

thanks for the tip. It works fine.

How could I display both prices ?
I would be useful to display the list price (may be striked through) on top the price with the discount.

By displaying the reference term, I can show the sales action and the discount. but the visitor doesn't know if the discount is already applied or not...


mwled on May 8, 2012


I have a client that wants to set up a store where there are discounts for certain users.

I'm using profile2 to add custom profile fields to each users profile.

I'd like to use Product Pricing Rule to apply discounts to certain customers, eg. is the customer a member of a discount scheme?

So far so good, but the problem is, that the client doesn't offer a percentage discount but a fixed amount e.g. if the customer is a member of the discount scheme they get £X off product Y.

I've added a custom field to products called discount where I enter the amount of discount a member of the discount scheme gets off that product.

I'm trying to create a rule that checks if they are a member of the discount scheme and if they are, subtract the amount that is stored as a custom field in the product from the product price. The first part works ok, but I can't get the rules to reference the custom field in the product. I've tried using Entity has field in the conditions, but still can't get access to the custom field.

Any ideas?



mwled on May 8, 2012


I've worked it out.

I was trying to use commerce-line-item to refence the entity rather than commerce-line-item:commerce-product


lucadeluchis on May 9, 2012

Hi! I need a rule to add a product to the cart every time i click on "add another item" button generated by the "field collection module" that i add to the inline product fields.

I thought it wold be just a matter of rules and I've tried to add this one:

event: after udpating existing field collection item action: add product to the cart Parameter: User: [site:current-user], Product SKU: [field-collection-item:item-id] Provides variables: Added product line item (product_add_line_item)

but actually i'm not good with rules... Can someone help me please?

milkovsky on July 6, 2012

I use rules component in loop
Question. How can I return value from loop component?

(Drupal commerce)
I have two prices in my products. I want to use price 2 field if total of price2 in cart is bigger than 1000$.

I want to count the total price in my cart(Drupal commerce).
1. I create rule with condition Calculating the sell price of a product.
2. I create value to store total
3. I start my loop in cart for each line-item.
4. In loop for each line item I use rule component to get price2 of related product. I send line item and my value as parameters
5. In the component I Set a data value to price2 * quantity.
6. ??? I want to return calculated price of product to main rule and go to nwxt line item in loop

apasajja on July 19, 2012

I need different discount rate for different product.
So, I'm struggling to make this module works per-product instead of same discount rate for every product.

I've created integer field field_discountrate in the Commerce product field. field_discountrate purpose is for discount rate. I can put any number from 1 to 99.

So, the price after discount should be:
<commerce_price> * <field_discountrate> / 100

So I'm trying to use PHP in Rules to make it happen

But the problem is:

First problem: I really unfamiliar with commerce. Below codes is how to get value in node. But I have no idea what entity hold commerce field.

// Extract the first field item
$specific_items = field_get_items('node', $node, 'field_namehere');
$specific_item = array_shift($specific_items);

// Get the field value
$thevalue = $specific_item['value'];

Second problem: Since this is not change data value, but calculate data, I have no idea how to end the calculation in this case.

With lack of reference of PHP in rules for this case, I'm stuck.

I've read the guides and videos above, and I've already done like in the last video.
Based on the last video, if we need 20% discount, we need to have one rule to calculate.
If we need 20% discount for product A and 30% discount for product B, we need to have two rules.

The problem is, we cannot have flexibility in the discount percentage. If we want to allow any number from 10% to 90% discount rate, we must have 81 rules. Thats too many.

I hope someone can come with a solution.

Thanks in advance.

Vasilii Lukasevich on November 14, 2014

Like this:

function my_module_commerce_product_calculate_sell_price_line_item_alter($line_item){

$price = 100; //1 dollar

//alter the price in cart & order
function my_module_commerce_cart_line_item_refresh($line_item, $order_wrapper){

$price = 100; //1 dollar
$line_item->commerce_unit_price[LANGUAGE_NONE]['0']['data']['components']['0']['price']['amount']=$price; //alter the base_price component


parvanova on August 13, 2012

I created a discount with a Taxonomy Term and Date window as described here.
Now I am trying to create a view to show all discounted products.
I can add as filter criateria the product to has a term = tid of my term for discount.
But how can I make this view to return results only in the Date window specified in the component?

Thanks for the great tutorial!

dready2011 on August 13, 2012

I am trying to set up a user based discount, and the VAT Hack looks promising. But i do not want to change the prices in the cart line-items, I'd prefer them to stay the same, and then add a line-item to show the discount.
Could anyone give me a hint on how to accomplish this?

cavax on March 1, 2013

I'm reading many post's around but nobody provide a nice solution for a discount to a product.

So i'll try to develope something that could work in this way:

-Installing commerce discout create a vocabulary "discount"
-When i create a discoutn the module will create a term into the vocabulary "discount"
-In the pricing rule the module will add the discount matching the taxonomy of the product...

I think is the easyest way to get a userfriendly interface and doscoutn system

Sky Buzz on June 18, 2014

I have tried your idea. But there is no option to select vocabulary, And if I create a discount from store settings -> Promotions -> Discount It won't create term in discount taxonomy. Please explain me how did you created the discount with this module.

Rick on May 18, 2013

Is it possible to show explanation for product pricing rule. For example, user see a discount in "product page" or "checkout page" and want to know, why he get low price?

gibry21 on June 4, 2013

Can somebody please help!

Great tutorial and I got it working fine if my taxonomy field was inside my product vairation, so I guess part of the commerce-product entity.

However if my taxonomy field is outside of the variation, so just on the content type node (I have done this to assist in a few other areas) then I can't get the field in scopt to compare against, all I see is the commerce-product and my field doesnt appear to be part of that entity...

The whole this is confisuing the crap out of me....

I really need a help getting this working if the taxonomy field is outside the product variation.

Thanks in advance.