Налаштування роботи з цифровими товарами на 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 магазин заблокує покупку, що для цифрового товара бессенсовно.







