Настройка импорта/экспорта товаров OpenCart

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Настройка импорта/экспорта товаров OpenCart
Средняя
~2-3 рабочих дня
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Настройка импорта/экспорта товаров OpenCart

Ручное заведение каталога в OpenCart — это тупик при любом количестве SKU свыше нескольких сотен. Настройка пайплайна импорта/экспорта решает три задачи одновременно: первичное наполнение каталога, регулярное обновление цен и остатков, синхронизация с внешними системами (1C, МойСклад, ERP).

Встроенные возможности OpenCart

Стандартный OpenCart содержит базовый CSV-импорт через admin > Catalog > Import. Формат жёсткий: фиксированные колонки без поддержки вариантов товара, атрибутов, SEO-полей и мультиязычности. Подходит только для простейших случаев.

Таблицы, затрагиваемые при полном импорте:

Таблица Содержимое
oc_product Основные поля: цена, вес, модель, статус
oc_product_description Тексты по языкам
oc_product_to_category Привязка к категориям
oc_product_to_store Привязка к магазинам
oc_product_attribute Значения атрибутов
oc_product_option Опции (цвет, размер)
oc_product_option_value Значения опций с остатком
oc_product_image Дополнительные изображения
oc_product_to_layout SEO layout

Модули для импорта/экспорта

Журнал3 / QuickAdmin — встроены в некоторые темы, достаточно для простых каталогов.

Spreadsheet Price Manager (SPM) — работает с Google Sheets напрямую через API, удобен для команд без технических навыков.

Import/Export Pro (iSenseLabs / Opencart.com) — наиболее полный официальный вариант. Поддерживает XML, CSV, XLS, JSON. Маппинг колонок через UI, расписание по cron, обработка изображений по URL.

D-Import — альтернатива с акцентом на производительность; использует bulk INSERT с отключением индексов во время загрузки.

Кастомный импорт через скрипт

Для максимальной гибкости — CLI-скрипт, использующий OpenCart framework напрямую:

<?php
// tools/import_products.php
define('DIR_APPLICATION', __DIR__ . '/../admin/');
define('DIR_SYSTEM', __DIR__ . '/../system/');
// ... остальные константы

require_once(DIR_SYSTEM . 'startup.php');
require_once(DIR_APPLICATION . 'config.php');

$registry = new Registry();
// инициализация DB, Config, Load...

$csv = new SplFileObject('/tmp/products_feed.csv');
$csv->setFlags(SplFileObject::READ_CSV | SplFileObject::SKIP_EMPTY);
$csv->setCsvControl(';', '"');

$headers = $csv->current(); // первая строка — заголовки
$csv->next();

$db->query("SET foreign_key_checks = 0");
$db->query("SET unique_checks = 0");

while (!$csv->eof()) {
    $row = array_combine($headers, $csv->current());
    $csv->next();

    if (empty($row['model'])) continue;

    // Проверяем существование по model
    $existing = $db->query(
        "SELECT product_id FROM oc_product WHERE model = '" . $db->escape($row['model']) . "' LIMIT 1"
    );

    if ($existing->num_rows) {
        $product_id = $existing->row['product_id'];
        // UPDATE
        $db->query("UPDATE oc_product SET
            price = '" . (float)$row['price'] . "',
            quantity = '" . (int)$row['quantity'] . "',
            date_modified = NOW()
            WHERE product_id = $product_id"
        );
    } else {
        // INSERT + описание + категории
        // ...
    }
}

$db->query("SET foreign_key_checks = 1");
$db->query("SET unique_checks = 1");

Такой скрипт запускается по cron: 0 6 * * * php /var/www/opencart/tools/import_products.php >> /var/log/oc_import.log 2>&1

Форматы источников

CSV от поставщика — самый распространённый. Проблемы: кодировка (windows-1251 vs UTF-8), разделитель (; vs ,), нестандартные булевы значения (да/нет, 1/0, true/false).

Нормализация перед импортом:

# Конвертация кодировки
iconv -f windows-1251 -t utf-8 feed_supplier.csv > feed_utf8.csv

# Замена разделителя
sed 's/;/,/g' feed_utf8.csv > feed_normalized.csv

XML (YML — Яндекс.Маркет формат) — стандарт для российского рынка:

<offer id="SKU-001" available="true">
  <name>Кофемашина DeLonghi ECAM 22.110</name>
  <price>45990</price>
  <currencyId>RUB</currencyId>
  <categoryId>15</categoryId>
  <picture>https://cdn.supplier.ru/img/ecam22110.jpg</picture>
  <param name="Мощность">1450 Вт</param>
  <param name="Объём бака">1.8 л</param>
</offer>

Парсинг через SimpleXML или XMLReader (для больших файлов > 50 МБ).

REST API поставщика — получение данных по HTTP с пагинацией:

$page = 1;
do {
    $response = json_decode(file_get_contents(
        "https://api.supplier.ru/v2/products?page={$page}&per_page=200",
        false,
        stream_context_create(['http' => ['header' => "Authorization: Bearer {$token}\r\n"]])
    ), true);

    foreach ($response['data'] as $item) {
        // обработка товара
    }
    $page++;
} while ($response['meta']['current_page'] < $response['meta']['last_page']);

Экспорт для внешних систем

Выгрузка в Google Merchant Center (формат GMC):

// Генерация RSS/Atom фида для GMC
header('Content-Type: application/xml; charset=utf-8');
echo '<?xml version="1.0" encoding="UTF-8"?>';
echo '<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">';
echo '<channel>';

$products = $db->query("
    SELECT p.*, pd.name, pd.description
    FROM oc_product p
    JOIN oc_product_description pd ON pd.product_id = p.product_id
    WHERE p.status = 1 AND pd.language_id = 1
    LIMIT 5000
");

foreach ($products->rows as $p) {
    echo '<item>';
    echo '<g:id>' . $p['model'] . '</g:id>';
    echo '<g:title><![CDATA[' . $p['name'] . ']]></g:title>';
    echo '<g:price>' . number_format($p['price'], 2, '.', '') . ' RUB</g:price>';
    echo '<g:availability>' . ($p['quantity'] > 0 ? 'in_stock' : 'out_of_stock') . '</g:availability>';
    echo '</item>';
}

echo '</channel></rss>';

Обработка изображений

Загрузка изображений по URL — узкое место при массовом импорте. Оптимальный подход: очередь + параллельная загрузка через curl_multi:

function downloadImagesParallel(array $urls, string $targetDir, int $concurrency = 10): array {
    $mh = curl_multi_init();
    $handles = [];
    $results = [];

    foreach (array_slice($urls, 0, $concurrency) as $url) {
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 15,
            CURLOPT_FOLLOWLOCATION => true,
        ]);
        curl_multi_add_handle($mh, $ch);
        $handles[] = ['ch' => $ch, 'url' => $url];
    }

    do {
        curl_multi_exec($mh, $running);
        curl_multi_select($mh);
    } while ($running > 0);

    foreach ($handles as $item) {
        $content = curl_multi_getcontent($item['ch']);
        $filename = $targetDir . '/' . basename(parse_url($item['url'], PHP_URL_PATH));
        file_put_contents($filename, $content);
        $results[$item['url']] = $filename;
        curl_multi_remove_handle($mh, $item['ch']);
    }

    curl_multi_close($mh);
    return $results;
}

Валидация и логирование

Каждый импорт должен иметь отчёт: сколько создано, обновлено, пропущено, с ошибками. Минимальная структура лога:

[2025-01-15 06:00:12] Import started: feed_2025-01-15.csv (4821 rows)
[2025-01-15 06:02:44] Created: 12, Updated: 4791, Skipped: 18, Errors: 0
[2025-01-15 06:02:44] Import finished in 152s

При ошибках в строке — запись в отдельный файл import_errors.csv с номером строки и описанием проблемы.

Сроки

Настройка готового модуля с маппингом под конкретный формат поставщика: 1–2 дня. Кастомный скрипт с поддержкой XML/API, загрузкой изображений и логированием: 3–5 дней. Полноценная двусторонняя синхронизация с 1C или ERP: 1–3 недели в зависимости от сложности маппинга данных.