As we start developing mini-products to offer to our clients, we've found we actually need to group multiple products under one purchase. For example, this month's Privacy Tuneup product is actually a combination of 3 different items:
- A taxable, recurring license that we resell from another vendor
- Privacy Policy setup
- Cookie Consent setup
How do we get Drupal Commerce to add all 3 at once, at a given price, with the appropriate tax charged and subscriptions set?
It was not as obvious as I would think. I tried 4 different approaches before reaching one I'm happy with for our needs. This blog post highlights these approaches, capturing the results of this investigation.
The winner: Promotions
Drupal Commerce has "Promotions" built into Commerce Core. This is a very flexible solution, and after trying a the other alternatives, I ended up back here with just Promotions.
To get this working, first I created the 3 individual products with their variations. Then I created the "bundle" product, the "Privacy Tuneup." And then I created 4 Commerce Promotions:
- Privacy Bundle - Termageddon License. Buy X Get Y. Customer buys specific product: Privacy Tune-up. Customer gets specific product: Termageddon License. Automatically add the offered product to the cart. 100% value, show only in the order summary.
- Privacy Bundle - Privacy Policy Setup. Buy X Get Y. Customer buys specific product: Privacy Tune-up. Customer gets specific product: Privacy Policy Setup. Automatically add the offered product to the cart. 100% value, displayed in the displayed unit price.
- Privacy Bundle - Privacy Policy Setup. Buy X Get Y. Customer buys specific product: Privacy Tune-up. Customer gets specific product: Cookie Consent Setup. Automatically add the offered product to the cart. 100% value, displayed in the displayed unit price.
- Privacy Bundle - Privacy Policy Setup. Fixed amount off each specific product. $150 off product: Privacy Tune-up. Show only in order summary. Expires 1/31/2025.
This got pretty much the result I wanted -- we need to collect sales tax on the taxable product, so the discount for that needs to get applied to the order, not the line item -- but the non-taxable services can be included with their prices zeroed out.
And then the last item is our sale price for the batch we are doing this month -- we'll continue to sell this product after the end of the month, but at a higher rate.
Read on for the other alternatives!
ECA - Add items to cart based on particular rules
We actually rolled this out before settling entirely on promotions. I had built out the promotions to include the sub-products, but because I had the discount applied on the order item instead of the order, it did not apply the tax correctly. So I created a rule using the Events, Conditions, and Actions (ECA) module, to add the Termageddon product whenever the Tune-up was added.
The ECA Commerce module provides ECA support for a variety of Commerce events and conditions. But at this writing, there is only one action, to override the price of an order item.
It's possible to wire together a bunch of other actions to get a result -- create an order item, set the product, quantity, order, and save, and then add it to the order. After going through this and getting an error and losing my work, I decided it needed a much easier action to "Add an item to the cart." So I created one.
Now it's easy to add an item to the cart based on just about anything you can think of.
This was an acceptable solution before I figured out that leaving the full price on the taxable item in its promotion solved it better. With the ECA solution, I used the "List price" on the bundle to show the total, and lowered the actual price by the price of the license product. The main difference was that the license showed up in the cart as editable, with the quantity and remove button. But otherwise this was a fine solution.
Commerce Product Add-on Module
The Commerce Product Add-on module was also something I tried. This module didn't work well for this particular scenario -- but it's certainly a useful module for upselling related products, and it's pretty straightforward to use.
The fundamental thing this module does is provide an alternative "Add to cart" field style that includes "Add-on" options. To use it, you add an entityreference field to a product type, referencing other products. Then on the manage display page for the product type, change the "Variations" field formatter to "Add to cart form with Add-ons", and hide the actual entityreference field.
Once you've done that, you can edit each product and add any related products you would like to highlight when the customer goes to add to the cart.
The add-ons can be shown as checkboxes, making it really easy to add an "installation" product along with the product license, and vice-versa.
The main issue I had with this user experience was that the checkboxes were unchecked by default, and I didn't see an easy way to make them checked, or required.
I suspect we'll add this for some of our simpler product bundles, especially when the add-ons are optional up-sells.
Commerce Variation Add-on Module
The Commerce Variation Add-on module was the first one I tried using for this scenario. I think this might've solved the issue, but I got confused by the structure -- there are "parent" and "child" variations, as well as "Variation Groups", and I found it hard to understand what each was for. I spent a few hours trying to get it to work, but kept ending up with selects that I didn't want, pricing that added up multiple times, and just general confusion.
I think this might be useful for sites that have products with a bunch of different variations, with some dependent on others. For example, something that comes in a bunch of different colors, but with different features tied to specific colors. I'm sure it makes great sense in some contexts, but it did not fit what I was trying to do -- or if it did, it wasn't clear how to get there!
Add new comment