How to create custom cart rules in magento 2
Magento 2 offers powerful cart rules by default. However, sometimes you need more, and you might want to create custom cart rules rather than just override core functionality.
Below is a clear guide on how to add a custom cart rule in Magento 2.
Why Add a Custom Cart Rule?
Cart rules allow promotions like discounts, free shipping, and more. Yet, the standard set may not always match your business needs.
Therefore, by creating a custom cart rule, you can tailor the rules exactly to your marketing strategy. Moreover, this makes your Magento instance cleaner since you avoid core overrides.
Overview of the Process
To build a custom cart rule in Magento 2, you need to:
- First add your custom option to the “Apply” dropdown in the Admin panel.
- Second map the custom option to a new discount calculator class via dependency injection.
- Finally write the logic for discount calculation in your new class.
Step 1: Add Your Custom Option to the Admin Dropdown
First, create a plugin for the Magento\SalesRule\Model\Rule\Metadata\ValueProvider::getMetadataValues() method.
This plugin should inject your new option under simple_action.
For example, in Webkul/CartRule/etc/adminhtml/di.xml define:
<type name="Magento\SalesRule\Model\Rule\Metadata\ValueProvider">
<plugin name="salesrule-plugin" type="Webkul\CartRule\Plugin\Rule\Metadata\ValueProvider" sortOrder="1"/>
</type>
Then, in the plugin class Webkul\CartRule\Plugin\Rule\Metadata\ValueProvider, implement afterGetMetadataValues(...) to push your custom action such as “Buy X Get next Y with M% discount”.
Step 2: Tie the New Option to a Discount Calculator via DI
Next, connect your custom simple_action key to a discount-handling class. This is done through Magento’s DI (dependency injection) configuration.
<type name="Magento\SalesRule\Model\Rule\Action\Discount\CalculatorFactory">
<arguments>
<argument name="discountRules" xsi:type="array">
<item name="buy_x_get_next_y_with_percent" xsi:type="string">\
Webkul\CartRule\Model\Rule\Action\Discount\BuyXGetNextYWithPercent\
</item>
</argument>
</arguments>
</type>
This tells Magento which class to use when the action type buy_x_get_next_y_with_percent is selected.
Step 3: Implement the Discount Logic
Now you need a class (for example, BuyXGetNextYWithPercent) under Webkul\CartRule\Model\Rule\Action\Discount\.
This class should extend AbstractDiscount or implement the required interface.
Within it, you define:
calculate(...): entry point, receives rule, item, qty._calculate(...)(or similar helper): logic to compute how many items match X, which items should get Y, percentage discount, rounding, etc.
You also have to set the discount amounts (base, original) properly.
Step 4: Create and Test the Rule
Once your plugin, DI, and discount class are in place, flush cache, run setup:di:compile, and then:
- Go to Admin → Marketing → Cart Price Rules.
- Create a new rule. You should now see your custom action “Buy X Get next Y with M% discount” in the Apply dropdown.
- Test with various cart scenarios to ensure correct discount application.
Best Practices & Tips
- Always account for edge cases — if a customer adds more than X, or mixture of items, fractional quantities, etc.
- Ensure correct currency handling (base vs store) and rounding so totals match across pages.
- Maintain translation support for labels.
- Include unit / integration testing to avoid regressions when Magento or your other modules update.
For more details and implementation, please check the blog: cart rule for Buy X Get next Y
Related Tools & Extensions
If you want to expand cart-rule capabilities without custom code, you might like Webkul’s Magento 2 Special Promotions module, which adds many pre-built advanced cart/checkout promotions.
You can explore it here: Magento2 Special Promotions Module.
Also, to learn how to create cart rules in magento 2 you can explore it here: Create a cart price rule
Conclusion
Creating a custom cart rule in Magento 2 involves injecting a custom option in admin, wiring that option via DI to a discount calculator class, and implementing the discount logic.
With proper planning, careful testing, and attention to edge cases, you can deliver flexible promotions tailored to your business. Happy coding!