Configuration of Price Drop Notification in 1C-Bitrix
Product price drops — need to notify users who added it to favorites or explicitly subscribed to price drops. The mechanism consists of two parts: tracking price changes and sending notifications to interested users. In Bitrix, both components are implemented without third-party services.
Capturing price changes
Catalog prices are stored in b_catalog_price. When price changes via API (CCatalogProduct::SetPrice() or \Bitrix\Catalog\PriceTable::update()), the OnCatalogPriceUpdate event fires. Subscribe to it:
AddEventHandler('catalog', 'OnCatalogPriceUpdate', function($fields) {
$productId = $fields['PRODUCT_ID'];
$newPrice = $fields['PRICE'];
$typeId = $fields['CATALOG_GROUP_ID']; // price type
// Get old price from our snapshot table
$oldPrice = PriceSnapshotTable::getLastPrice($productId, $typeId);
if ($oldPrice && $newPrice < $oldPrice) {
// Queue notification task
PriceDropQueue::add($productId, $newPrice, $oldPrice);
}
// Save new snapshot
PriceSnapshotTable::save($productId, $typeId, $newPrice);
});
Snapshot table bl_price_snapshot: fields product_id, catalog_group_id, price, currency, recorded_at.
Storing user subscriptions
Create bl_price_watch table with fields:
-
user_id— ID fromb_user(NULL for anonymous) -
email— notification email -
product_id— product ID -
target_price— desired price (optional, NULL = any drop) -
created_at -
notified_at— date of last notification
"Watch price" button on product page sends AJAX request, which inserts row in bl_price_watch. For authorized users, email is taken automatically from b_user.
Sending notifications
Agent runs every 30 minutes. Reads bl_price_drop_queue and for each product finds subscribers in bl_price_watch where target_price IS NULL OR target_price >= new_price. Notification is sent via \Bitrix\Main\Mail\Event::send() with type CATALOG_PRICE_DROP:
\Bitrix\Main\Mail\Event::send([
'EVENT_NAME' => 'CATALOG_PRICE_DROP',
'LID' => SITE_ID,
'C_FIELDS' => [
'USER_EMAIL' => $subscriber['email'],
'PRODUCT_NAME' => $productName,
'OLD_PRICE' => number_format($oldPrice, 0, '.', ' '),
'NEW_PRICE' => number_format($newPrice, 0, '.', ' '),
'PRODUCT_URL' => $productUrl,
'DISCOUNT_PCT' => round((1 - $newPrice / $oldPrice) * 100),
],
]);
After sending, set notified_at = NOW() and can add logic: don't notify again on same product more than once per 7 days.
What to configure
-
OnCatalogPriceUpdatehandler with snapshot table write and queue recording -
bl_price_snapshotandbl_price_watchtables - "Watch price" button UI in
catalog.elementcomponent template -
CATALOG_PRICE_DROPmail event type and HTML letter template - Notification agent with deduplication by
notified_at







