Налаштування автоматичного оновлення цін поставщиків при дропшипінгу 1С-Бітрікс
Дропшипінг на Бітриксі — це не просто "показуємо товари поставщика". Це щоденна синхронізація прайсів, яка повинна відпрацювати непомітно: ціни оновилися, маржа пересчиталася, товари з нульовим остатком пішли в "немає в наявності". Якщо цього не відбувається — магазин продає за застарілими цінами й отримує збитки або суперечки з покупцями.
Формати прайсів поставщиків
Поставщики відають прайси в кількох форматах: CSV, Excel (.xlsx), XML (в тому числі CommerceML), JSON через API. Кожен формат потребує свого парсера. В Бітриксі для XML/CommerceML є стандартний імпорт через "1С → Обмін з 1С", але він розраховий на ручний запуск і повний імпорт, а не на інкрементальне оновлення цін.
Для автоматизації потрібен користувацький компонент оновлення. Структура:
/local/modules/vendor.priceimport/
├── lib/
│ ├── Parser/
│ │ ├── CsvParser.php
│ │ ├── XlsxParser.php
│ │ └── XmlParser.php
│ ├── PriceUpdater.php
│ └── StockUpdater.php
└── install/
└── index.php
Імпорт CSV: парсинг і маппінг
CSV поставщика містить артикул, ціну закупки, остаток. Маппінг на поля Бітрикса — через конфігураційний файл, щоб при зміні формату поставщика не переписувати логіку:
// config/vendor_a.php
return [
'delimiter' => ';',
'encoding' => 'windows-1251',
'skip_rows' => 1, // Заголовок
'columns' => [
'sku' => 0, // Артикул — перша колонка
'price' => 3, // Ціна — четверта
'stock' => 5, // Остаток — шоста
],
'price_type' => 2, // ID типу ціни в b_catalog_price
'markup' => 1.25, // Наценка 25%
];
Парсер:
class CsvParser {
public function parse(string $filePath, array $config): \Generator {
$file = new \SplFileObject($filePath);
$file->setFlags(\SplFileObject::READ_CSV | \SplFileObject::SKIP_EMPTY);
$file->setCsvControl($config['delimiter']);
$row = 0;
foreach ($file as $line) {
if ($row++ < $config['skip_rows']) continue;
yield [
'sku' => trim($line[$config['columns']['sku']]),
'price' => (float)str_replace(',', '.', $line[$config['columns']['price']]),
'stock' => (int)$line[$config['columns']['stock']],
];
}
}
}
Генератор (yield) обов'язковий при файлах від 50MB — дозволяє не завантажувати весь файл в пам'ять.
Оновлення цін в таблиці b_catalog_price
Маппінг артикулу на елемент інфоблока — через властивість ARTICLE або XML_ID:
class PriceUpdater {
public function updateFromParsed(iterable $rows, array $config): array {
$stats = ['updated' => 0, 'not_found' => 0];
foreach ($rows as $row) {
// Знайти елемент по артикулу
$el = \CIBlockElement::GetList(
[], ['PROPERTY_ARTICLE' => $row['sku'], 'IBLOCK_ID' => CATALOG_IBLOCK_ID],
false, ['nTopCount' => 1], ['ID']
)->Fetch();
if (!$el) { $stats['not_found']++; continue; }
$newPrice = round($row['price'] * $config['markup'], 2);
\CPrice::SetBasePrice($el['ID'], $newPrice, 'RUB', $config['price_type']);
$stats['updated']++;
}
return $stats;
}
}
CPrice::SetBasePrice() робить INSERT або UPDATE в b_catalog_price — правильний інструмент для одиничних оновлень. При масовому оновленні (10 000+ позицій) швидше прямий SQL через тимчасову таблицю з подальшим UPDATE ... FROM.
Розписання через агенти Бітрикса
Агент запускає оновлення раз на 4 години:
\CAgent::AddAgent(
'VendorPriceImport::run();',
'vendor.priceimport',
'N', // Не одноразовий
14400, // Інтервал 4 години
'', 'Y',
date(DATE_FORMAT, time() + 14400)
);
Метод run() скачує прайс з FTP/HTTP поставщика, парсить, оновлює ціни й остатки, пише лог в b_event_log. При помилці — відправляє лист адміністратору через CEvent::Send().







