Настройка работы с цифровыми товарами на 1С-Битрикс
Цифровой товар продан, деньги списаны, письмо с файлом не пришло. Или ссылка на скачивание пришла, но работает бесконечно. Или файл доступен без оплаты при прямом переборе URL. Все три проблемы — следствие неправильной настройки типа товара и защиты файлов.
Тип товара и поле файла
Цифровой товар в Битриксе — товар с типом TYPE_ELECTRONICAL (значение 5) в поле TYPE таблицы b_catalog_product. Файл для скачивания привязывается через свойство инфоблока типа "Файл" (FILE) или через специальный механизм b_catalog_product — поле FILE_ID, которое ссылается на b_file.
Установка типа и файла:
\Bitrix\Catalog\ProductTable::update($productId, [
'TYPE' => \Bitrix\Catalog\ProductTable::TYPE_ELECTRONICAL,
]);
// Прикрепление файла через свойство инфоблока
\CIBlockElement::SetPropertyValuesEx($productId, $iblockId, [
'DIGITAL_FILE' => [
'VALUE' => \CFile::MakeFileArray('/path/to/file.zip'),
],
]);
Защита файлов от прямого доступа
Файлы цифровых товаров не должны лежать в /upload/ с прямым HTTP-доступом. Стандартный механизм Битрикса — папка /upload/protected/ с правилом в .htaccess или nginx, запрещающим прямой доступ. Скачивание идёт через защищённый URL, генерируемый системой.
Конфигурация nginx для защиты директории:
location /upload/protected/ {
deny all;
return 403;
}
Доступ к файлу предоставляется через компонент bitrix:sale.personal.order или отдельный обработчик, который проверяет наличие оплаченного заказа с этим товаром и генерирует временный URL.
Доставка файла после оплаты
Стандартный механизм отправки файла — обработчик события OnSaleOrderPaid в модуле sale. При оплате заказа система проходит по позициям корзины, находит товары с TYPE = 5 и отправляет ссылку на скачивание на email покупателя.
Ограничение количества скачиваний и срок действия ссылки управляются свойствами товара. В стандартном модуле catalog нет встроенного счётчика скачиваний — это добавляется кастомно через отдельную таблицу или свойства заказа.
Реализация выдачи файла с проверкой прав:
// В обработчике запроса на скачивание
$orderId = (int)$_GET['order'];
$productId = (int)$_GET['product'];
$hash = $_GET['hash'];
// Проверить токен
$expected = md5($orderId . $productId . $userId . SITE_ID . $_SERVER['HTTP_HOST']);
if ($hash !== $expected) {
die('Access denied');
}
// Проверить оплаченность заказа
$order = \Bitrix\Sale\Order::load($orderId);
if (!$order || $order->isPaid() !== true) {
die('Order not paid');
}
// Выдать файл
$fileId = getDigitalFileByProduct($productId);
$file = \Bitrix\Main\IO\File::createInstance(\CFile::GetPath($fileId));
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($file->getPath()) . '"');
$file->readFile();
Срок действия ссылки
Ссылка со временным токеном должна протухать. Простой подход — включать timestamp в подпись и при проверке отклонять запросы старше N часов:
$timestamp = (int)$_GET['ts'];
if (time() - $timestamp > 86400) { // 24 часа
die('Link expired');
}
$expected = md5($orderId . $productId . $userId . $timestamp . SITE_KEY);
Для ограничения числа скачиваний нужна таблица с записями (order_id, product_id, user_id, downloads_count, max_downloads). При каждом скачивании счётчик увеличивается, при превышении — доступ блокируется.
Остатки и повторная покупка
Цифровые товары обычно не имеют физического остатка. В b_catalog_product для них рекомендуется QUANTITY_TRACE = 'N' и CAN_BUY_ZERO = 'Y' — тогда остаток не отслеживается и товар всегда доступен к покупке. При QUANTITY_TRACE = 'Y' с остатком 0 магазин заблокирует покупку, что для цифрового товара бессмысленно.







