Setting up a time limit for the sale of goods (alcohol) in 1C-Bitrix

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages

Time-Based Sales Restriction for Products (Alcohol) in 1C-Bitrix

Russian legislation prohibits the sale of alcohol at night — from 23:00 to 08:00 (Federal Law No. 171-FZ). Regions may impose stricter restrictions. An online store is obligated to block the ability to place an order containing alcoholic products during the restricted hours.

Blocking Points in Bitrix

The restriction must be applied in several places simultaneously — otherwise the customer will either bypass it or see a confusing error at the last step:

  1. "Buy" button on the product card — hide or disable during restricted hours
  2. Adding to cartOnSaleBasketItemAdd event handler
  3. Order checkout — check before saving the order in OnBeforeSaleOrderSaved

Determining the Time Window

The key question is which time zone to use. Three approaches:

  • By server time — simple, but incorrect: the server is in Moscow while the customer may be in Vladivostok
  • By the customer's time zone — via IP geolocation (MaxMind GeoIP database or equivalent)
  • By delivery time — for courier delivery, the relevant time is in the recipient's city

The most correct approach for an online store with delivery is to determine the time zone by the customer's IP. In Bitrix, the sale.location module or a third-party geolocation database is used for this.

Simple check using Moscow time (UTC+3):

function isAlcoholSaleAllowed(): bool {
    $hour = (int)date('H', time() + 3 * 3600); // Moscow time
    return ($hour >= 8 && $hour < 23);
}

Marking Alcohol Products

A property UF_IS_ALCOHOL (type "Yes/No") is created in the catalog infoblock. Or section-based: if the "Alcohol" section has the flag UF_TIME_RESTRICTED, all products in it fall under the restriction.

Checking whether a product belongs to a restricted category:

function isTimeRestrictedProduct(int $productId): bool {
    $element = CIBlockElement::GetByID($productId)->Fetch();
    if ($element['PROPERTY_UF_IS_ALCOHOL_VALUE'] === 'Y') return true;

    // Check the section
    $section = CIBlockSection::GetByID($element['IBLOCK_SECTION_ID'])->Fetch();
    return $section['UF_TIME_RESTRICTED'] === '1';
}

Cart Add Handler

AddEventHandler('sale', 'OnSaleBasketItemAdd', function(&$arFields) {
    if (!isTimeRestrictedProduct($arFields['PRODUCT_ID'])) return;
    if (!isAlcoholSaleAllowed()) {
        $arFields['ERROR_MESSAGE'] =
            'Alcohol sales are permitted from 08:00 to 23:00 Moscow time';
        return false;
    }
});

Visual Block on the Frontend

On the product card and in the catalog, the "Buy" button is replaced with a message about time restrictions. JavaScript checks the client's time — but this is a supplement to the server-side check, not a replacement:

const hour = new Date().getHours();
if (isAlcoholProduct && (hour < 8 || hour >= 23)) {
    document.querySelector('.buy-btn').disabled = true;
    document.querySelector('.buy-btn').textContent = 'Sales from 08:00 to 23:00';
}

Regional Restrictions

If the store operates in regions with stricter-than-federal restrictions, the time zone and time window are determined dynamically based on IP geolocation. A database of regions with their restrictions is stored in a separate table.

What Is Included in the Setup

  • Creating the UF_IS_ALCOHOL or UF_TIME_RESTRICTED property in the infoblock
  • Server-side time check accounting for the customer's time zone
  • OnSaleBasketItemAdd handler blocking alcohol products
  • Pre-save order check in OnBeforeSaleOrderSaved
  • Visual "Buy" button block during restricted hours
  • If needed — support for regional restrictions