Настройка автоматического обновления цен поставщиков при дропшиппинге 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().







