Cart Price Rules Overview
Cart Price Rule Model
// Magento\SalesRule\Model\Rule
namespace Magento\SalesRule\Model;
class Rule extends \Magento\Framework\DataObject implements
\Magento\SalesRule\Api\Data\RuleInterface
{
/**
* Get rule data
*/
public function getName(): string
{
return $this->getData('name');
}
public function getDiscountAmount(): float
{
return (float) $this->getData('discount_amount');
}
public function getCouponCode(): ?string
{
return $this->getData('coupon_code');
}
public function getFromDate(): ?string
{
return $this->getData('from_date');
}
public function getToDate(): ?string
{
return $this->getData('to_date');
}
}
Rule Types
| Type | Description |
|---|---|
| Cart Price Rule | Applied to cart contents during checkout |
| Catalog Price Rule | Applied to product prices before add to cart |
Coupon Codes
Coupon Generation
namespace Vendor\Promotion\Service;
class CouponManager
{
public function __construct(
private \Magento\SalesRule\Model\RuleFactory $ruleFactory,
private \Magento\SalesRule\Model\CouponFactory $couponFactory
) {}
public function generateCoupons(
int $ruleId,
int $quantity,
string $format = 'alphanumeric'
): array {
$rule = $this->ruleFactory->create()->load($ruleId);
$codes = [];
for ($i = 0; $i < $quantity; $i++) {
$code = $this->generateCode($format);
$coupon = $this->couponFactory->create();
$coupon->setRuleId($ruleId);
$coupon->setCode($code);
$coupon->setUsageLimit(1);
$coupon->save();
$codes[] = $code;
}
return $codes;
}
private function generateCode(string $format): string
{
$length = 8;
$characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$code = '';
for ($i = 0; $i < $length; $i++) {
$code .= $characters[random_int(0, strlen($characters) - 1)];
}
return $code;
}
}
Applying Coupons
// Apply coupon to quote
$quote->setCouponCode('SAVE10');
$quote->collectTotals()->save();
// Remove coupon
$quote->setCouponCode(null);
$quote->collectTotals()->save();
// Check if coupon is valid
$coupon = $this->couponFactory->create()->loadByCode('SAVE10');
if ($coupon->getId() && $coupon->isUsed()) {
// Coupon is valid and can be used
}
Conditions and Actions
Rule Conditions
// Cart price rule conditions
$rule->setConditionsSerialized(json_encode([
'type' => 'Magento\SalesRule\Model\Rule\Condition\Combine',
'attribute' => null,
'operator' => null,
'aggregator' => 'all',
'value' => '1',
'is_value_processed' => null,
'new_child' => [
[
'type' => 'Magento\SalesRule\Model\Rule\Condition\Product',
'attribute' => 'qty',
'operator' => '>=',
'value' => '3',
],
[
'type' => 'Magento\SalesRule\Model\Rule\Condition\Product',
'attribute' => 'category_ids',
'operator' => '()',
'value' => [4, 5],
],
],
]));
Rule Actions
// Discount action types
$rule->setSimpleAction('by_percent'); // Percentage discount
$rule->setSimpleAction('by_fixed'); // Fixed amount discount
$rule->setSimpleAction('cart_fixed'); // Fixed amount for whole cart
$rule->setSimpleAction('buy_x_get_y'); // Buy X get Y free
// Set discount amount
$rule->setDiscountAmount(10); // 10% or $10 depending on action
// Apply to shipping
$rule->setApplyToShipping(true);
// Stop further rules processing
$rule->setStopRulesProcessing(true);
Example: Buy 3 Get 10% Off
$rule = $this->ruleFactory->create();
$rule->setName('Buy 3 Get 10% Off');
$rule->setIsActive(1);
$rule->setWebsiteIds([1]);
$rule->setCustomerGroupIds([0, 1, 2, 3]);
$rule->setSimpleAction('by_percent');
$rule->setDiscountAmount(10);
$rule->setCouponType(1); // 1 = specific coupons
$rule->setUsesPerCoupon(1);
$rule->setUsesPerCustomer(1);
// Condition: qty >= 3
$rule->setConditionsSerialized(json_encode([
'type' => 'Magento\SalesRule\Model\Rule\Condition\Product',
'attribute' => 'qty',
'operator' => '>=',
'value' => '3',
]));
$rule->save();
Catalog Price Rules
Catalog vs Cart Rules
// Catalog Price Rules - applied to product prices before add to cart
// Affects product listing and detail page prices
// Cart Price Rules - applied during checkout
// Affects cart totals and final price
Catalog Rule Model
namespace Magento\CatalogRule\Model;
class Rule extends \Magento\Rule\Model\AbstractModel
{
public function getName(): string
{
return $this->getData('name');
}
public function getDiscountAmount(): float
{
return (float) $this->getData('discount_amount');
}
public function getFromDate(): ?string
{
return $this->getData('from_date');
}
public function getToDate(): ?string
{
return $this->getData('to_date');
}
}
Catalog Rule Application
// Catalog rules are applied via cron or manual run
// Products get their prices updated in catalog_product_index_price
// Check catalog rule discount
$catalogRulePrice = $this->catalogRule->calcRulePrice(
$productId,
$websiteId,
$customerGroupId
);
// Product displays discounted price
$product->setPrice($catalogRulePrice);
Quiz
1. What is the difference between cart and catalog price rules?
2. What does coupon_type = 1 mean?
3. How do you prevent multiple rules from stacking?
Flashcards
Question
Cart Price Rule purpose?
Click to reveal answer
Answer
Apply discounts during checkout based on cart contents and conditions
Question
Catalog Price Rule purpose?
Click to reveal answer
Answer
Modify product prices before add to cart
Question
stop_rules_processing?
Click to reveal answer
Answer
Prevents subsequent rules from applying after current rule matches
Question
Coupon types?
Click to reveal answer
Answer
1 = specific coupons, 2 = auto-generated, 3 = no coupon
Revision Notes
Key Takeaways
- 1. Cart price rules apply discounts during checkout based on conditions
- 2. Catalog price rules modify product prices before add to cart
- 3. Coupon codes can be auto-generated or manually created
- 4. Conditions filter rules by product attributes, quantities, categories
- 5. stop_rules_processing prevents rule stacking
Interview Tips
- • Explain when to use cart rules vs catalog rules
- • Describe the coupon lifecycle: generate → apply → validate → use
- • Discuss how conditions aggregate (all/any) for complex promotions
Cheat Sheet
Cart Price Rules:
Apply during checkout
Conditions: product qty, category, attributes
Actions: percent, fixed, cart_fixed, buy_x_get_y
Coupons: specific, auto-generated, none
Catalog Rules:
Apply to product prices before cart
Run via cron or manual application
Key Settings:
stop_rules_processing: prevent stacking
uses_per_customer: limit per customer
uses_per_coupon: limit per coupon code