OpenCart Product Import/Export Setup

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.
Development and maintenance of all types of websites:
Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Showing 1 of 1 servicesAll 2065 services
OpenCart Product Import/Export Setup
Medium
~2-3 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    822
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    847
  • image_website-sbh_0.png
    Website development for SBH Partners
    999
  • image_website-_0.png
    Website development for Red Pear
    451

OpenCart Product Import/Export Setup

Manual catalog entry in OpenCart is a dead end with any SKU count over several hundred. Setting up import/export pipeline solves three tasks simultaneously: initial catalog population, regular price and inventory updates, synchronization with external systems (1C, MoyaSklad, ERP).

Built-in OpenCart Capabilities

Standard OpenCart contains basic CSV import via admin > Catalog > Import. Format is rigid: fixed columns without support for product variants, attributes, SEO fields, and multilingual content. Suitable only for simplest cases.

Tables affected during complete import:

Table Content
oc_product Basic fields: price, weight, model, status
oc_product_description Texts by languages
oc_product_to_category Category binding
oc_product_to_store Store binding
oc_product_attribute Attribute values
oc_product_option Options (color, size)
oc_product_option_value Option values with inventory
oc_product_image Additional images
oc_product_to_layout SEO layout

Import/Export Modules

Journal3 / QuickAdmin — built into some themes, sufficient for simple catalogs.

Spreadsheet Price Manager (SPM) — works with Google Sheets directly via API, convenient for non-technical teams.

Import/Export Pro (iSenseLabs / Opencart.com) — most complete official option. Supports XML, CSV, XLS, JSON. Column mapping via UI, cron schedule, image processing by URL.

D-Import — alternative emphasizing performance; uses bulk INSERT with disabled indexes during load.

Custom Import via Script

For maximum flexibility — CLI script using OpenCart framework directly:

<?php
// tools/import_products.php
define('DIR_APPLICATION', __DIR__ . '/../admin/');
define('DIR_SYSTEM', __DIR__ . '/../system/');
// ... rest of constants

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

$registry = new Registry();
// DB, Config, Load initialization...

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

$headers = $csv->current(); // first line — headers
$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;

    // Check existence by 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 + description + categories
        // ...
    }
}

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

Run via cron: 0 6 * * * php /var/www/opencart/tools/import_products.php >> /var/log/oc_import.log 2>&1

Source Formats

CSV from supplier — most common. Issues: encoding (windows-1251 vs UTF-8), delimiter (; vs ,), non-standard booleans (yes/no, 1/0, true/false).

Normalize before import:

# Encoding conversion
iconv -f windows-1251 -t utf-8 feed_supplier.csv > feed_utf8.csv

# Delimiter replacement
sed 's/;/,/g' feed_utf8.csv > feed_normalized.csv

XML (YML — Yandex.Market format) — standard for Russian market:

<offer id="SKU-001" available="true">
  <name>Coffee Machine 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="Power">1450 W</param>
  <param name="Tank Volume">1.8 L</param>
</offer>

Parse via SimpleXML or XMLReader (for files >50 MB).

REST API supplier — get data via HTTP with pagination:

$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) {
        // process product
    }
    $page++;
} while ($response['meta']['current_page'] < $response['meta']['last_page']);

Export for External Systems

Export to Google Merchant Center (GMC format):

// Generate RSS/Atom feed for 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>';

Image Processing

Image download by URL — bottleneck in mass import. Optimal approach: queue + parallel download via 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;
}

Validation and Logging

Each import should have report: how many created, updated, skipped, with errors. Minimal log structure:

[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

On row errors — record in separate import_errors.csv with line number and problem description.

Timeline

Setup ready module with mapping to specific supplier format: 1–2 days. Custom script with XML/API support, image download, logging: 3–5 days. Full two-way sync with 1C or ERP: 1–3 weeks depending on data mapping complexity.