Skip to content
intermediate Phase 48 · Checkout Production

Cart Price Rules

Cart price rules including coupons, discounts, conditions, actions, and catalog rules

45m
0 problems
Topic Progress 0%

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?

Question 1 options

2. What does coupon_type = 1 mean?

Question 2 options

3. How do you prevent multiple rules from stacking?

Question 3 options

Flashcards

Question

Cart Price Rule purpose?

Answer

Apply discounts during checkout based on cart contents and conditions

Question

Catalog Price Rule purpose?

Answer

Modify product prices before add to cart

Question

stop_rules_processing?

Answer

Prevents subsequent rules from applying after current rule matches

Question

Coupon types?

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