Price Types & Calculation
Describe price types and generation: product page (base, special, catalog rules), cart (tiered, options, tax, cart rules), calculation process, customization, and price rendering.
Price Types & Calculation
Price Generation Basics
Magento has multiple layers of pricing calculation depending on where the price is displayed.
Product Page Price (Before Cart)
- Base Price: The
priceattribute value. - Special Pricing: Temporary discount set on product (date range optional).
- Catalog Rules: Rule-based discounts from indexed
catalogrule_product_pricetable.
Shopping Cart Price (After Quantity Determined)
Once a product is added to cart with a specific quantity, additional pricing applies:
- Tiered Pricing: Volume discounts based on quantity, customer group, and website.
- Options Price: Price added by custom options (e.g., engraving, gift wrap).
- Tax / VAT: Applied depending on tax configuration and checkout stage.
- Shopping Cart Rules: Promotional discounts applied in cart (e.g., "10% off cart total").
Price Calculation Process
The primary price calculation for product pages happens in the Price model.
Calculation Sequence (Product Page)
- Base Price: Start with
priceattribute or existing calculated price. - Special Pricing: Apply if
special_priceis set and within date range. - Catalog Rules: Apply lowest applicable rule price from
catalogrule_product_pricetable.
// Simplified flow in calculatePrice()
$price = $product->getPrice(); // Base price
// Apply special price if applicable
if ($specialPrice && $specialPrice < $price) {
$price = $specialPrice;
}
// Apply catalog rule price if lower
if ($rulePrice && $rulePrice < $price) {
$price = $rulePrice;
}
return $price;
Identifying Final Price Components
To identify what composes a product's final price:
- Check Base Price: Product's
priceattribute. - Check Special Price:
special_priceattribute and date range (special_from_date,special_to_date). - Check Catalog Rules: Query
catalogrule_product_pricefor active rules matching product/customer group. - Check Tiered Pricing: Product's tier price table for quantity/customer group.
- Debug: Set breakpoint in
calculatePrice()and step through.
\Magento\Catalog\Model\Product\Type\Price::calculatePrice() to trace price calculation.Customizing Price Calculation
Two approaches to customize price calculation:
- Plugins (Preferred): Use
afterplugin oncalculatePrice(). - Preference: Replace entire price calculation class (more invasive).
Example: Plugin on calculatePrice()
di.xml:
<type name="Magento\Catalog\Model\Product\Type\Price">
<plugin name="vendor_module_custom_price"
type="Vendor\Module\Plugin\Product\Type\Price"
sortOrder="10" />
</type>
Plugin Class:
namespace Vendor\Module\Plugin\Product\Type;
class Price
{
public function afterCalculatePrice(
\Magento\Catalog\Model\Product\Type\Price $subject,
$result,
$product,
$qty = null
) {
// Apply custom logic
// Example: Add 10% markup
return $result * 1.10;
}
}
Price Rendering
Price rendering is configured via layout XML and uses dedicated renderer blocks.
A block named product.price.render.default is created in default.xml.
Using Price Renderer Block
You can use this block to render pricing elsewhere in the application.
Example from Downloadable Product:
<referenceBlock name="product.price.render.default">
<arguments>
<argument name="price_render" xsi:type="string">product.price.render.default</argument>
<argument name="price_type_code" xsi:type="string">final_price</argument>
</arguments>
</referenceBlock>
Price Rendering Templates
Templates for price renderers are located in:
Key Templates
price/final_price.phtmlprice/tier_prices.phtmlprice/special_price.phtmlprice/minimal_price.phtml
JavaScript UI Component for Prices
Magento also provides a JS UI component to render prices dynamically.
See: Render Prices on the Frontend
Use Cases
- Dynamic price updates (e.g., when selecting configurable options)
- AJAX-loaded prices
- Custom price displays
How to Render Price in Custom Location
To render price in a custom location:
- In Layout XML:
<block class="Magento\Framework\Pricing\Render" name="custom.price.render"> <arguments> <argument name="price_render_handle" xsi:type="string">catalog_product_prices</argument> </arguments> </block> - In Template (.phtml):
<?php /** @var \Magento\Catalog\Block\Product\AbstractProduct $block */ $product = $block->getProduct(); ?> <?= $block->getLayout() ->getBlock('product.price.render.default') ->render( 'final_price', $product, [ 'include_container' => true, 'display_minimal_price' => true, 'zone' => \Magento\Framework\Pricing\Render::ZONE_ITEM_LIST ] ); ?>
Modifying Price Rendering
To modify how price is rendered:
- Override Templates: Copy template to your theme and modify.
- Custom Renderer: Create custom price renderer class extending
\Magento\Framework\Pricing\Render\AbstractRenderer. - Layout XML: Update
catalog_product_prices.xmlto use your renderer. - CSS/JS: Style via CSS or add dynamic behavior with JS.
final_price.phtml to add custom badges or formatting.Price Types Summary
| Price Type | When Applied | Description |
|---|---|---|
| Base Price | Product Page | Product's price attribute |
| Special Price | Product Page | Temporary discount with optional date range |
| Catalog Rules | Product Page | Rule-based discounts from indexed table |
| Tiered Pricing | Cart | Volume discounts based on quantity/group |
| Options Price | Cart | Custom option surcharges |
| Tax / VAT | Cart/Checkout | Tax based on configuration and location |
| Cart Rules | Cart | Promotional discounts in cart |
Further Reading
Exam Tips
- Product Page: Base price, special pricing, catalog rules.
- Cart: Add tiered pricing, options price, tax/VAT, cart rules.
- Calculation:
Product\Type\Price::calculatePrice(). - Customize: Plugin on
afterCalculatePrice()or replace entire class. - Rendering:
product.price.render.defaultblock indefault.xml. - Templates:
Magento/Catalog/view/base/templates/product/. - JS UI:
Magento/Catalog/view/base/web/template/for dynamic prices. - Custom Render: Use layout XML to reference price renderer block.