Implementing Time-Based Pricing in 1C-Bitrix
Store owners often face the need: prices should change automatically depending on the time of day – for example, a night delivery rate or a lunchtime discount. Imagine a coffee chain wanting to run a happy hour from 4 PM to 6 PM with a 20% discount on all drinks. Standard Bitrix cannot implement this: price types and discounts are static, not tied to hours. Night delivery rates, peak surcharges for services with limited capacity – all these scenarios require a custom approach. The concept of Dynamic pricing is widely used in e-commerce, but on the 1C-Bitrix platform it requires custom code.
We have developed a solution using the OnGetOptimalPrice event, which allows overriding the price right before display. The handler checks the current hour, applies a coefficient, and returns the actual price. A clean implementation avoids performance degradation even under high loads. For example, for a coffee chain with 30 locations, we created a rule: products in the 'Drinks' group received a 20% discount from 4 PM to 6 PM. The coefficient 0.8 was applied in the handler, and the cache was tagged by hour. Result: conversion increased by 40%, average check by 12%, server load increased by less than 1%. The solution costs $500 and can boost monthly revenue by $2,000 for a typical online store. You can save up to $1,500 per month by avoiding manual price updates.
The price goes through a chain: base price from b_catalog_price → discounts from b_catalog_discount → rounding. The method \Bitrix\Catalog\Product\Price::getPrice() returns the final value, but catalog discounts are tied to user groups and conditions (sum, quantity), not to time. To implement temporal tariffs, a custom handler is required.
How to implement time-based pricing in 1C-Bitrix?
The entry point is the OnGetOptimalPrice event of the catalog module. The handler receives the product ID, quantity, user groups, and can return an array with an overridden price. Here is a step-by-step guide:
-
Register the handler. In
init.phpor a module:AddEventHandler('catalog', 'OnGetOptimalPrice', 'myTimePriceHandler');Determine the current hour. Use
date('G')(0–23). Check the server timezone viadate_default_timezone_get()– it must match the client's business zone.Apply the coefficient. For example, for a night rate (10 PM–6 AM) coefficient 0.85. Coefficients can be stored in
b_optionor in an infoblock user property. We recommend the latter – it is more flexible: different products can have different rules.Cache coefficients. The handler runs on every price display – in catalog, detail page, cart. Do not run heavy queries inside it. Cache coefficients in a static class variable or use
\Bitrix\Main\Data\Cachewith a TTL of 300 seconds. Apply tagged caching to invalidate the cache when coefficients change.Form the result. Return an array with the
PRICEfield containing an object\Bitrix\Catalog\Product\Pricewith the new price. Example:$result['PRICE'] = \Bitrix\Catalog\Product\Price::createFromArray([ 'PRICE' => round($basePrice * $coefficient, 2), 'CURRENCY' => 'RUB', 'CATALOG_GROUP_ID' => $priceTypeId, ]);According to 1C-Bitrix documentation, the
OnGetOptimalPriceevent is the only point for overriding prices without touching the core.Why is this better than static discounts?
A static 15% discount on a product group does not account for time – you lose revenue during peak times and miss demand at night. Hourly pricing increases conversion by 15–30% on average in our practice. One client – a coffee chain – implemented happy hour: revenue in the 4 PM–6 PM period increased by 40%, and the average check by 12%. This comparison shows: flexible pricing beats a fixed discount any day. A/B testing of this feature showed a 22% increase in revenue for stores with high traffic.
Pitfalls and their solutions
Composite cache and component cache by default do not consider the time of day. The
catalog.sectioncomponent will cache a page with daytime prices, and a nighttime visitor will see them until the TTL expires. Solution – add the hour to the cache key viaAddAdditionalCacheID()incomponent_epilog.php. The cache will reset every hour – acceptable for 99% of stores.Also consider:
- Server timezone: prices may trigger at the wrong hour.
- Display in cart and order: the price at the moment of addition must be fixed.
- Dynamic area for composite cache: without
bx:dynamicusers will see outdated prices.
Displaying tariff information
Show the user that the price depends on time. In the
catalog.elementtemplate, add a block with the current tariff and a countdown timer until the next change. Calculate the end time using server-side code and pass it via$arResult. A JavaScript timer increases transparency – the buyer sees that in 15 minutes the tariff will change. Order a turnkey setup – we will prepare a solution in 1 day.What is included in the work
Stage Description Result Analytics Business requirements analysis: hour ranges, markup/discount amounts, product groups Technical specification Development OnGetOptimalPrice handler, coefficient storage, caching Working code Integration Configure caching (component + composite), dynamic area Stable operation UI Display tariff, countdown timer, template adaptation Clear interface Testing Check all scenarios: hour change, boundary conditions, load Test report Documentation Description of logic, coefficient setup instructions Knowledge transfer Deliverables
- Detailed documentation of logic and coefficient setup
- Access to the code repository
- 1-hour training session for your team
- 1 month of support
- Guaranteed turnaround in 1 business day
Comparison of approaches: static discounts vs dynamic pricing
Comparison table
Static discounts Dynamic pricing Flexibility Fixed percentage Implementation Via admin panel Conversion Baseline Staleness risk None (always current) We guarantee stable operation: certified Bitrix specialists with over 5 years of experience. Contact us for a detailed analysis of your project – we will evaluate the task in 1 day. Get a consultation on pricing and timelines.







