Если 1С уже выгружает остатки в CSV, а в WooCommerce они не обновляются или обновляются с ошибками, проблема обычно не в самом файле, а в сопоставлении SKU, формате чисел и способе импорта. В этой статье — рабочая схема, которая подходит для регулярной синхронизации без написания отдельной интеграции.
Когда CSV-импорт действительно подходит
Этот вариант имеет смысл, если у вас уже есть регулярная выгрузка из 1С, а задача сводится к обновлению цены, остатка и статуса наличия. Для небольших и средних каталогов CSV часто проще, чем поддерживать отдельный обмен через API: меньше точек отказа, проще проверить руками и быстрее найти ошибку в конкретной строке.
Но CSV не решает всё. Если нужны сложные правила по складам, нескольким валютам, пакетная передача характеристик и история обмена на уровне документов, лучше смотреть в сторону штатного обмена 1С или отдельного интеграционного слоя. CSV — это практичный компромисс, а не универсальная замена.
Диагностика проблемы: что ломается чаще всего
Перед настройкой импорта проверьте не WordPress, а исходные данные. В 80% случаев сбой связан с одним из типовых несоответствий:
- в WooCommerce у товара нет совпадающего
SKU, а импорт ищет товар именно по артикулу; - в CSV остаток записан как текст с запятой, пробелами или лишними символами;
- кодировка файла не UTF-8 и кириллица в названиях «плывёт»;
- в файле есть дубли SKU;
- импорт обновляет не тот столбец: например, цену вместо остатка;
- товары-вариации не сопоставлены отдельно, хотя у них свои артикулы.
Быстрая проверка: откройте CSV в текстовом редакторе, а не в таблицах, и убедитесь, что разделитель один и тот же по всему файлу. Если файл выглядит нормально в Excel, это ещё не значит, что он корректен для импорта.
Пошаговая схема: как сделать импорт без дублей и ручной правки
1. Приведите каталог к единому идентификатору
Для синхронизации остатков используйте SKU как основной ключ. В WooCommerce это стандартное поле товара и вариации. Если артикулы в 1С и магазине отличаются, сначала договоритесь о едином формате: это дешевле, чем потом ловить расхождения в каждом импорте.
Если у товара нет артикула, импорт по нему лучше не запускать. Иначе вы получите либо новые дубли, либо массовое обновление не тех позиций.
2. Подготовьте CSV в предсказуемом формате
Минимальный набор колонок для обновления остатков обычно такой: sku, stock_quantity, stock_status. Названия могут быть любыми, если вы сами пишете обработчик, но логика должна быть однозначной.
sku,stock_quantity,stock_status
ABC-001,12,instock
ABC-002,0,outofstock
ABC-003,5,instockЕсли 1С отдаёт остаток в виде 12,000 или 12 шт., перед импортом нормализуйте значение. WooCommerce ожидает число, а не человекочитаемую подпись.
3. Настройте импорт через WP-Cron или ручной запуск
Если файл лежит на сервере, можно запускать обработку по расписанию. Для этого удобнее написать небольшой обработчик, который читает CSV и обновляет товары по SKU. Ниже пример упрощённой функции: она не зависит от стороннего плагина и показывает сам принцип.
<?php
function wpdirect_import_stock_from_csv( $file_path ) {
if ( ! file_exists( $file_path ) || ! is_readable( $file_path ) ) {
return new WP_Error( 'csv_not_found', 'CSV-файл недоступен' );
}
$handle = fopen( $file_path, 'r' );
if ( ! $handle ) {
return new WP_Error( 'csv_open_failed', 'Не удалось открыть CSV' );
}
$header = fgetcsv( $handle, 0, ',' );
if ( ! $header ) {
fclose( $handle );
return new WP_Error( 'csv_empty', 'CSV пустой' );
}
$map = array_flip( $header );
while ( ( $row = fgetcsv( $handle, 0, ',' ) ) !== false ) {
$sku = isset( $row[ $map['sku'] ] ) ? trim( $row[ $map['sku'] ] ) : '';
$qty = isset( $row[ $map['stock_quantity'] ] ) ? (int) $row[ $map['stock_quantity'] ] : 0;
$status = isset( $row[ $map['stock_status'] ] ) ? trim( $row[ $map['stock_status'] ] ) : 'outofstock';
if ( $sku === '' ) {
continue;
}
$product_id = wc_get_product_id_by_sku( $sku );
if ( ! $product_id ) {
continue;
}
$product = wc_get_product( $product_id );
if ( ! $product ) {
continue;
}
$product->set_manage_stock( true );
$product->set_stock_quantity( $qty );
$product->set_stock_status( $status === 'instock' ? 'instock' : 'outofstock' );
$product->save();
}
fclose( $handle );
return true;
}Такой код удобно запускать не на каждом хите, а по cron-задаче или вручную из админки. Если файл большой, не гоняйте импорт через обычный запрос браузера — упрётесь в таймауты и память.
4. Обрабатывайте вариации отдельно
Если у вариативного товара свои артикулы на каждую вариацию, импортируйте именно вариации, а не родительский товар. В WooCommerce родитель может быть «в наличии», даже если конкретные размеры закончились. Для этого в CSV храните SKU вариации и обновляйте их как отдельные записи.
Пример более надёжной обработки CSV
Когда файл приходит в нестабильном формате, полезно сначала проверить заголовки и логировать пропущенные строки. Это помогает быстро понять, где сломалась выгрузка из 1С.
<?php
function wpdirect_normalize_stock_value( $value ) {
$value = trim( (string) $value );
$value = str_replace( array( ' ', ' ' ), '', $value );
$value = str_replace( ',', '.', $value );
return (int) floor( (float) $value );
}
function wpdirect_import_stock_row( array $row, array $map ) {
$sku = isset( $row[ $map['sku'] ] ) ? sanitize_text_field( $row[ $map['sku'] ] ) : '';
$qty = isset( $row[ $map['stock_quantity'] ] ) ? wpdirect_normalize_stock_value( $row[ $map['stock_quantity'] ] ) : 0;
if ( $sku === '' ) {
return new WP_Error( 'empty_sku', 'Пустой SKU' );
}
$product_id = wc_get_product_id_by_sku( $sku );
if ( ! $product_id ) {
return new WP_Error( 'product_not_found', 'Товар не найден: ' . $sku );
}
$product = wc_get_product( $product_id );
$product->set_manage_stock( true );
$product->set_stock_quantity( $qty );
$product->set_stock_status( $qty > 0 ? 'instock' : 'outofstock' );
$product->save();
return true;
}Здесь важен не сам стиль кода, а принцип: сначала нормализация входных данных, потом поиск товара, затем обновление. Если поменять порядок, отладка станет заметно сложнее.
Сравнение подходов: плагин, код или ручной импорт
| Подход | Когда подходит | Плюсы | Минусы |
|---|---|---|---|
| Плагин импорта | Нужен быстрый запуск без разработки | Есть интерфейс, логирование, маппинг полей | Дополнительная нагрузка, зависимость от плагина |
| Собственный код | Формат CSV стабилен и нужен контроль логики | Гибкость, меньше лишнего кода в админке | Нужно поддерживать и тестировать |
| Ручной импорт | Редкие обновления и небольшой каталог | Просто начать, не требует автоматизации | Ошибки из-за человеческого фактора |
Если у вас уже есть регулярные выгрузки и нужен минимум ручной работы, кодовый импорт обычно выигрывает. Если же формат CSV меняется вместе с настройками 1С, удобнее использовать интерфейсный импорт с маппингом колонок.
Как проверить, что синхронизация сработала
После первого запуска не ограничивайтесь просмотром пары товаров в админке. Проверьте цепочку целиком:
- товар найден по SKU и не создан дубль;
- изменилось именно поле остатка, а не только статус;
- на витрине товар исчезает из наличия при
0; - вариации обновляются отдельно, если у них свои артикулы;
- в логах нет строк с пустым SKU и нераспознанными значениями.
Практический тест: возьмите один товар, поменяйте остаток в CSV на 0, запустите импорт и откройте карточку товара в админке. Если WooCommerce показывает outofstock, а на витрине товар скрывается или помечается как отсутствующий — базовая логика работает.
Частые ошибки и как их исправить
Товар не находится по SKU
Причина обычно в том, что артикул в WooCommerce пустой, отличается по регистру или содержит лишние пробелы. Сначала проверьте карточку товара, потом CSV. Если артикулы генерируются автоматически, убедитесь, что они одинаково формируются и в 1С, и в магазине.
Остаток обновился, но статус не поменялся
Так бывает, если импорт меняет только количество, а статус наличия WooCommerce рассчитывает отдельно. В коде нужно явно задавать и set_stock_quantity(), и set_stock_status(). Иначе товар может остаться «в наличии» при нулевом остатке.
После импорта появились дубли
Это почти всегда признак импорта не по SKU, а по названию или ID из внешней системы. Для WooCommerce внешний ID из 1С не имеет смысла, если вы его отдельно не храните. Используйте один устойчивый ключ и не смешивайте несколько идентификаторов в одном процессе.
Импорт падает на больших файлах
Причина — обработка всего CSV за один запрос. Разбейте импорт на пачки, запускайте через cron и логируйте прогресс. Если файл приходит очень большой, лучше сначала выгружать его на сервер, а потом обрабатывать построчно.
Безопасность и производительность
Если CSV лежит в публичной директории, не оставляйте его доступным без ограничений. Файл с остатками и ценами — это уже чувствительные данные. Храните выгрузку вне web-root или закрывайте доступ на уровне сервера.
Для производительности важно не обновлять товар без необходимости. Перед save() сравнивайте старый и новый остаток: если значение не изменилось, лишняя запись в базу не нужна. На каталоге с большим количеством товаров это заметно снижает нагрузку.
Если вам нужен не только импорт, но и чистка лишних дублей, служебных мета-данных и мусора после тестов, имеет смысл посмотреть в сторону Clearfy Pro. Он не решает обмен с 1С, но помогает держать сайт в более чистом состоянии, когда интеграции уже обросли служебными данными.
Что делать, если нужен следующий шаг
Если CSV-обмен уже работает, следующий полезный этап — добавить журналирование: кто запустил импорт, какой файл был обработан, сколько строк обновилось и сколько было пропущено. Это сильно упрощает разбор инцидентов, когда 1С выгрузила не тот формат или менеджер случайно загрузил старый файл.
Для стабильной схемы обычно достаточно трёх вещей: единый SKU, предсказуемый CSV и проверка результата после каждого запуска. Всё остальное — уже вопрос удобства и масштаба каталога.