Last updated

May 21, 2024, 03:11:49 AMa month ago

Medusa Pricing Groups

What is it?

Medusa Pricing Groups is a plugin for the Medusa headless commerce system that enables one to group products together for the purposes of price calculation.

Quick Start

  1. Install the plugin by running Copy to clipboardnpm i -S medusa-products-pricing-groups.
  2. Add the following to Copy to clipboardmedusa-config.js to the Copy to clipboardplugins array: Copy to clipboardjavascript { resolve: `medusa-products-pricing-groups`, options: { enableUI: true } }
  3. Run Copy to clipboardnpx medusa migrations run
  4. Start the medusa backend
Once installed, you will see a new entry , Copy to clipboardPricing Groups in the sidebar. From here you can create pricing groups, add and remove products (click on the newly created group to manage the products).
The plugin will also add an admin widget to the product details view. This widget will show which pricing groups a product is currently associated with.

What problem does it solve?

Out of the box, Medusa has the capability of creating prices for variants of a product in multiple currencies, at multiple different levels, through the use of Copy to clipboardmin_quantity & Copy to clipboardmax_quantity (only possible via API requests currently,
fingers crossed it appears in the dashboard UI soon).
Pricing flexibility is further enabled by price lists, which allow one to set custom prices depending on the audience.
The problem arises when one has a set of products that when purchased together should each contribute towards the volume discounts of the other products in the cart.

Use Case & Example


Let's say we have 10 different t-shirts, in varying colours and sizes.
We have a storefront, which retail customers can access and purchase from. We also have two other audiences that will be using the storefront; small quantity resellers, and high volume resellers.
Each of these audiences have their own terms and price lists respectively.
Each variant of t-shirt has volume price breaks.
Each t-shirt variant can have different prices.
For the sake of the example we will assume the following prices apply:
For retail customers:
  • 1-3 t-shirts: 20
  • 3+ t-shirts: 18
For the small quantity & high volume reseller audiences:
  • 1-5 t-shirts: 20
  • 5-10 t-shirts: 15
  • 10+ shirts: 12
All t-shirts cost the same in the example, though in practice the prices can differ, and be set as normal.


What we are looking to achieve is the following criteria:
  • Each product variant can have its prices set independently in all supported currencies
  • Products can easily be grouped and ungrouped
  • Products can have different volume breakpoints (i.e. Copy to clipboardmin_quantity/Copy to clipboardmax_quantity thresholds can differ between grouped products)
  • Any applicable volume discounts should be automatically applied
  • If multiple discounts are available for a set of products in the cart the best discount should be chosen.

The Example

We have our example case & criteria set out above.
The following are the expected cart totals:
  • A retail customer adds Copy to clipboard1 x red & Copy to clipboard1 x blue to their cart.
    • Pricing tier: Copy to clipboard1-3 t-shirts
    • Cart total: 40 (20 + 20)
  • A retail customer adds Copy to clipboard1 x red, Copy to clipboard1 x green & Copy to clipboard2 x purple to their cart.
    • Pricing tier: Copy to clipboard3+ t-shirts
    • Cart total: 72 (18 + 18 + 36)
  • A small reseller adds Copy to clipboard1 x red, Copy to clipboard1 x green & Copy to clipboard2 x purple to their cart.
    • Pricing tier: Copy to clipboard1-5 t-shirts
    • Cart total: 80 (20 + 20 + 40)
  • A small reseller adds Copy to clipboard4 x blue, Copy to clipboard4 x green, Copy to clipboard3 x purple to their cart.
    • Pricing tier: Copy to clipboard10+ t-shirts
    • Cart total: 132 (48 + 48 + 36)
The problem can be partially solved with promotional codes, though this becomes a complexity nightmare, in terms of tracking active codes, calculating fixed/percentage discounts, monitoring edge cases, and so on. It quickly becomes impossible to achieve pricing structures due to the rigidity of fixed/percentage discounts, whilst also being a poor user experience in terms of the user having to choose & manually apply one of potentially many codes.

How this plugin solves it

The concept of a pricing group is introduced. A pricing group is a very simple structure, comprised of an identifier and a name, along with a set of products tagged with the identifier.
The plugin implements a pricing group service that retrieves these linkages between the pricing group and products.
The plugin implements a pricing strategy that calculates and returns the best price for the variant in question.
In simple terms we do the following:
  1. Retrieve all variants in the cart.
  2. Iterate all variants, and retrieve associated groups for each variant.
  3. Create a map of Copy to clipboardVariant ID => [Group IDs]
  4. Create a map of Copy to clipboardGroup ID => Calculated Quantity
  5. Iterate variants in cart, increment Copy to clipboardCalculated Quantity for each Copy to clipboardGroup ID associated with current Copy to clipboardVariant ID by Copy to clipboardVariant Quantity
  6. Use Copy to clipboardCalculated Quantity to retrieve the Copy to clipboardBest Price available.
  7. Calculate line item total as Copy to clipboardVariant Quantity x Best Price.
N.B. If the cart is undefined for the request, we fall back to retrieving the price for the variant as if it were a standalone product rather than a grouped one.

Development Notes

When developing the package, attempting to run this plugin on a medusa backend will cause issues if you install Copy to clipboard@medusajs/medusa into the Copy to clipboardnode_modules folder of the plugin directory, due to dependency conflicts with the medusa backend.
To workaround this:
  1. Copy to clipboardcd into Copy to clipboardnode_modules/@medusajs/medusa from the root of the medusa backend directory, and run Copy to clipboardyarn link.
  2. Copy to clipboardcd into the plugin directory, then run Copy to clipboardyarn link @medusajs/medusa. The plugin will now build using the Copy to clipboard@medusajs/medusa dependency from the backend.
  3. Run Copy to clipboardyarn link in the root of the plugin directory.
  4. Copy to clipboardcd into the backend directory again, and run Copy to clipboardyarn link medusa-products-pricing-groups.
  5. You can now run Copy to clipboardyarn dev to start the backend, make some changes to the plugin, and run Copy to clipboardyarn build in the plugin directory to see the changes live reloaded on the backend dashboard UI.

Afterthought / Disclaimer

I am fully aware the code quality isn't perfect as things currently stand - this was somewhat of a proof-of-concept project to familiarise myself with Medusa and see if it would suit our needs.
There may be bugs, I haven't fully tested this plugin in production.
Also, the data table elements were lifted from the core admin dashboard and modified, as they more or less suited my needs and I wasn't about to write them from scratch.

Build your own plugins

Develop your own plugins with our API to speed up your processes.

Make your plugin available via npm for it to be shared in our Plugin Library with the broader Medusa community.