Как настроить обмен данными между 1С и самописным сайтом: эмуляция протокола CommerceML

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При настройке стандартного обмена с сайтом в среде 1С разработчики часто сталкиваются с тем, что система по умолчанию оптимизирована для работы с платформой «1С-Битрикс». Но что делать, если ваш сайт написан на другой CMS (например, WordPress, OpenCart, Laravel) или является полностью самописным? Покупать дорогостоящую лицензию только ради обмена данными не имеет смысла.

В этой статье мы подробно разберем, по какому принципу работает выгрузка данных из 1С, что происходит в системе при нажатии кнопки «Проверить соединение», и как написать собственный скрипт-обработчик на стороне сайта, который заставит 1С поверить, что она работает со стандартным Битриксом.

Общий принцип взаимодействия по протоколу CommerceML

Обмен данными между 1С и сайтом происходит по стандартному протоколу HTTP (или защищенному HTTPS). Инициатором всех запросов всегда выступает 1С. Сайт в данном случае выполняет пассивную роль — он ожидает запросы от учетной системы, обрабатывает их и возвращает строго регламентированные текстовые ответы.

Проанализируем ситуацию: когда вы указываете в настройках узла обмена адрес сайта вида http://mysite.ru/1c_exchange.php, логин и пароль, 1С начинает отправлять на этот скрипт GET- и POST-запросы с различными параметрами в URL. Весь цикл обмена делится на несколько последовательных этапов. Рассмотрим каждый из них подробно.

Шаг 1. Авторизация на сайте (mode=checkauth)

Когда мы нажимаем кнопку «Проверить соединение» или запускаем сеанс обмена, 1С выполняет первый проверочный запрос. Программа отправляет GET-запрос следующего вида:

http://mysite.ru/1c_exchange.php?type=catalog&mode=checkauth

При этом 1С использует стандартную HTTP Basic-авторизацию. Данные пользователя (логин и пароль) передаются в заголовке запроса Authorization в зашифрованном виде (Base64). На стороне вашего скрипта необходимо принять эти заголовки, проверить подлинность пользователя и выдать ответ.

Важный нюанс: на многих хостингах в режиме работы PHP как CGI или FastCGI заголовки авторизации могут вырезаться веб-сервером. Чтобы обойти эту проблему, в файл .htaccess вашего сайта необходимо добавить следующие строки:


RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

Теперь разберем, как должен выглядеть PHP-скрипт авторизации. Результатом успешной авторизации должен быть текстовый ответ, состоящий строго из четырех строк, разделенных символом перевода строки \n. Любые лишние пробелы, пустые строки или HTML-теги приведут к ошибке разбора в 1С.

Посмотрим на пример реализации авторизации:


// Настройка сессии
session_start();

// Получение данных авторизации
$login = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : '';
$password = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';

// Проверяем пользователя (в реальном проекте сверяем с базой данных)
if ($login === 'admin1c' && $password === 'supersecretpassword') {
    // Возвращаем строго структурированный ответ
    echo "success\n";              // Строка 1: признак успеха
    echo "PHPSESSID\n";            // Строка 2: имя cookie сессии
    echo session_id() . "\n";      // Строка 3: значение cookie сессии
    echo "timestamp=" . time() . "\n"; // Строка 4: метка времени сервера (необязательно, но желательно)
    exit;
} else {
    header('HTTP/1.0 401 Unauthorized');
    echo "failure\nНеверный логин или пароль.";
    exit;
}

После получения ответа success 1С сохраняет имя и значение cookie (в нашем примере PHPSESSID) и будет автоматически прикреплять их ко всем последующим запросам текущей сессии для подтверждения авторизации.

Шаг 2. Инициализация параметров обмена (mode=init)

После успешной авторизации 1С запрашивает параметры окружения и технические лимиты сервера. Программа отправляет следующий GET-запрос:

http://mysite.ru/1c_exchange.php?type=catalog&mode=init&version=3.1

Здесь параметр version указывает на версию CommerceML, которую поддерживает 1С. В ответ ваш скрипт должен сообщить, поддерживает ли сервер архивацию файлов (ZIP) и какой максимальный размер файла в байтах он готов принять за один POST-запрос.

Рассмотрим структуру ответа сервера на этом этапе:


// Проверяем авторизацию по кукам сессии
if (session_status() == PHP_SESSION_NONE) {
    session_start();
}

// Проверяем, авторизован ли пользователь
if (!isset($_SESSION['authorized'])) {
    echo "failure\nСессия не найдена или устарела.";
    exit;
}

echo "zip=yes\n";              // Разрешаем передачу данных в архивах zip
echo "file_limit=2048000\n";   // Задаем лимит на размер одного файла (например, 2 МБ)
echo "sessid=" . session_id() . "\n";
echo "version=3.1\n";
exit;

Если вы укажете параметр zip=yes, 1С автоматически сожмет все выгружаемые файлы (XML и изображения товаров) в ZIP-архив перед отправкой, что существенно сэкономит трафик и ускорит процесс выгрузки.

Шаг 3. Передача файлов на сайт (mode=file)

На этом шаге 1С начинает физически закачивать файлы данных на ваш сервер. Запрос отправляется методом POST на адрес:

http://mysite.ru/1c_exchange.php?type=catalog&mode=file&filename=import.xml

Критически важный момент: 1С отправляет файлы не в виде стандартной формы multipart/form-data. Это означает, что глобальный массив PHP $_FILES окажется абсолютно пустым! Данные передаются в теле POST-запроса в виде сырого бинарного потока (Raw POST Data).

Для корректного сохранения переданного файла нам необходимо прочитать поток ввода php://input и сохранить его на сервере. Если размер файла превышает лимит file_limit, заданный на шаге инициализации, 1С будет присылать его частями (чанками). Наш скрипт должен уметь дописывать данные в конец файла.

Разберем по шагам реализацию сохранения файла:


$filename = isset($_GET['filename']) ? basename($_GET['filename']) : '';

if (empty($filename)) {
    echo "failure\nНе указано имя файла.";
    exit;
}

$upload_dir = __DIR__ . '/1c_temp/';
if (!is_dir($upload_dir)) {
    mkdir($upload_dir, 0777, true);
}

$target_file = $upload_dir . $filename;

// Открываем поток на чтение входящих данных и файл на запись (в режиме добавления 'a')
$input = fopen("php://input", "r");
$file = fopen($target_file, "a");

if ($input && $file) {
    while ($data = fread($input, 8192)) {
        fwrite($file, $data);
    }
    fclose($input);
    fclose($file);
    echo "success\n";
} else {
    echo "failure\nОшибка при записи файла на сервере.";
}
exit;

После того как файл или все его части будут успешно сохранены на сервере, 1С получит ответ success и перейдет к следующей фазе.

Шаг 4. Пошаговый импорт данных (mode=import)

Когда все необходимые файлы (обычно это ZIP-архив, содержащий файлы описания каталога import.xml и товарных предложений offers.xml) загружены на сервер, 1С посылает запрос на запуск процесса интеграции:

http://mysite.ru/1c_exchange.php?type=catalog&mode=import&filename=import.xml

На данном этапе ваш скрипт должен выполнить следующие действия:

  1. Если файл был архивирован (имеет расширение .zip), распаковать его во временную директорию.
  2. Распарсить XML-структуру файлов CommerceML.
  3. Записать или обновить данные о категориях, товарах, свойствах, ценах и остатках в базе данных вашего сайта.

Поскольку процесс парсинга большого каталога товаров может занять длительное время и превысить лимит выполнения PHP-скрипта (max_execution_time), стандарт CommerceML предусматривает пошаговость.

Если скрипт понимает, что объем данных велик, он может обработать только часть файла (например, первые 100 товаров), сохранить текущую позицию разбора и вернуть в 1С ответ вида:

progress\nОбработано 100 товаров из 5000.

Получив такой ответ, 1С не прерывает соединение, а немедленно отправляет точно такой же запрос mode=import повторно. Скрипт возобновляет работу с сохраненной позиции. Этот цикл повторяется до тех пор, пока скрипт не обработает весь файл целиком и не вернет финальный статус:

success\nИмпорт успешно завершен.

Шаг 5. Синхронизация заказов (type=sale)

Если в настройках узла обмена 1С включена выгрузка документов (заказов), то после работы с каталогом товаров запускается аналогичный процесс, но уже с параметром type=sale.

Алгоритм работы с заказами состоит из следующих шагов:

  1. Запрос заказов с сайта (mode=query): 1С запрашивает новые заказы, оформленные на сайте. Ваш скрипт должен выбрать из базы данных сайта новые заказы, сформировать XML-файл в формате CommerceML и отдать его прямо в тело HTTP-ответа.
  2. Подтверждение загрузки (mode=success): Получив заказы и успешно проведя их в своей базе данных, 1С отправляет запрос на сайт с параметром mode=success. Это сигнал для вашего сайта о том, что данные успешно приняты, и отправленные заказы нужно пометить флагом «Выгружен в 1С», чтобы не передавать их повторно при следующем обмене.
  3. Обратная загрузка изменений (mode=file и mode=import): Если в самой 1С менеджер изменил статус заказа (например, «Оплачен» или «Отгружен»), 1С формирует XML-файл с изменениями и закачивает его на сайт по схеме, аналогичной импорту каталога товаров. Сайт должен распарсить этот файл и обновить статусы заказов в своей базе.

Использование готовых библиотек

Разрабатывать парсер XML-файлов CommerceML с нуля — задача трудоемкая, так как структура файлов import.xml и offers.xml содержит множество вложенных связей, уникальных идентификаторов (GUID), характеристик и типов цен.

Для облегчения задачи рекомендуется использовать готовые open-source библиотеки на PHP (их можно легко найти на GitHub по запросу «CommerceML parser»). Они берут на себя рутинную работу по разбору XML и предоставляют удобный объектно-ориентированный интерфейс для работы с номенклатурой 1С.

Мы пошагово разобрали технические аспекты взаимодействия 1С с веб-сервером. Эмулируя описанные текстовые ответы на каждом этапе обмена, вы сможете легко подружить вашу учетную систему 1С с абсолютно любым веб-ресурсом без использования сторонних коммерческих модулей.

← На главную