Setting up time-based pricing in 1C-Bitrix
The standard catalog module lacks a mechanism to change product prices based on the time of day. Price types, discounts, markups — all are static entities not bound to time. Yet the task is real: night rates for delivery, happy hour for restaurants, peak markups for capacity-limited services. Implementation requires intervention in the price calculation logic at the event level.
Price calculation mechanism in the catalog
Product price goes through a chain: base price from b_catalog_price → discount application from b_catalog_discount → rounding → result. The \Bitrix\Catalog\Product\Price::getPrice() method returns the final price, but catalog discounts are applied based on user groups and conditions (order sum, product quantity), not time.
Entry point — the OnGetOptimalPrice event from the catalog module. The handler receives product ID, quantity, user groups, and can return an array with an overridden price. This is where time-based logic is injected.
Implementation through event handlers
Create a handler in init.php or through a custom module:
-
Register the event:
AddEventHandler('catalog', 'OnGetOptimalPrice', ...). -
Determine current hour:
date('G')returns hour without leading zero (0–23). Account for server timezone —date_default_timezone_get()must match the business zone. -
Apply coefficient: night coefficient 0.85 for hours 22:00–06:00 is multiplied by base price. Coefficients are stored in
b_optionor in custom infoblock properties — depends on whether different rules are needed for different products.
Important: OnGetOptimalPrice handler is called every time price is displayed — in catalog, on product page, in cart. Don't make heavy requests in it. Cache coefficients in a static class variable or in \Bitrix\Main\Data\Cache with TTL of 300 seconds.
Caching and pitfalls
Composite cache and component caches by default don't account for time of day. The catalog.section component will cache a page with daytime prices, and a night visitor will see them until TTL expires.
Solution — add hour to cache key via CACHE_GROUPS parameter or through AddAdditionalCacheID() in component_epilog.php. Cache will reset every hour — acceptable for most shops.
For composite cache use dynamic area <bx:dynamic> around the price block. Price will be loaded via AJAX on each page view.
Displaying tariff information
Show users that price depends on time. Add to catalog.element component template a block with current tariff: "Night rate: 15% discount until 06:00". Calculate end time with server code and pass through $arResult. JavaScript countdown timer to tariff change increases transparency for buyers.







