Интеграция 1C и n8n через HTTP: заказы, остатки и защита от дублей ¶
Проблема: 1C часто остаётся системой учёта, а сайт, CRM и маркетплейсы живут своими событиями. Если обмен делать через ручные CSV или прямые записи без договора данных, появляются дубли документов, расхождение остатков и неясно, кто отвечает за ошибку.
Решение: Надёжная интеграция 1C и n8n начинается с договора обмена: external_id, source of truth, формат JSON/XML, idempotency key, статусы, ошибки и ручная очередь. n8n выступает orchestration layer, а не заменяет бизнес-логику 1C.
Материал закрывает практический интент: интеграция 1C и n8n, HTTP сервисы 1C, обмен заказами через API, OData 1C, JSON обмен 1C, идемпотентность документов. Внутри есть импортируемый workflow JSON, тестовый payload, Code Node, таблица архитектуры, Schema.org HowTo, LLM-разметка, визуальная схема и production-чеклист.
Проблема и решение: почему простой webhook ломает учёт ¶
В n8n легко собрать happy path: принять webhook, сделать HTTP Request и получить зелёный execution. Но backoffice-интеграции ломаются не на первом успешном запросе, а на повторной доставке, неполном payload, изменении схемы API, ручной правке в учётной системе и частичном сбое после write-операции.
Поэтому эта страница описывает не абстрактную связку сервисов, а готовую production-модель. Сначала фиксируется контракт данных, затем проверяются ключи, потом включается idempotency, и только после этого workflow меняет заказ, остаток, цену или документ. Такой подход снижает количество дублей, делает replay безопасным и помогает поддержке объяснить каждое изменение.
Архитектура workflow для интеграции ¶
| Нода | Роль | Что проверить |
|---|---|---|
| Webhook from shop/CRM | Принимает заказ, оплату или изменение статуса | event_id, external_order_id, signature |
| Validate contract | Проверяет товары, суммы, клиента и обязательные поля | нет неполного документа |
| Idempotency storage | Фиксирует ключ до write-операции или атомарно вместе с результатом | уникальный external_order_id |
| HTTP Request to 1C | Передаёт JSON/XML в HTTP-сервис или OData endpoint | auth, timeout, response format |
| Review / Alert | Отправляет понятную ошибку владельцу процесса | SKU, причина, действие, ссылка на execution |
Почему не стоит начинать с “синхронизировать всё”
У каждой системы есть зоны ответственности. Сначала автоматизируйте один поток: заказ, остаток, цена или уведомление. После стабильных тестов добавляйте второй поток и общую сверку. Иначе ошибки разных процессов смешаются в одном execution.
Контракт входных данных ¶
Контракт нужен для тестов, replay и передачи задачи между разработчиком, интегратором и владельцем процесса. Не завязывайтесь на текстовое название товара или клиента: используйте стабильные внешние ID, артикулы, event_id, timestamp и idempotency key.
{
"event_id": "shop-order-10492-create",
"event_type": "order.create",
"external_order_id": "shop-10492",
"customer": {
"name": "Анна Иванова",
"phone": "+7 999 000-11-22",
"inn": ""
},
"items": [
{
"sku": "N8N-001",
"qty": 2,
"price": 1490
}
],
"payment_status": "paid",
"delivery": {
"city": "Москва",
"address": "ул. Примерная, 1"
},
"idempotency_key": "shop:order:10492:create",
"created_at": "2026-05-30T10:00:00+03:00"
}
Нормализация и проверка данных в Code Node ¶
Code Node ниже не заменяет всю бизнес-логику, но задаёт безопасный вход: выбрасывает пустые обязательные поля, приводит идентификаторы к единому виду и формирует ключ идемпотентности. В production этот блок лучше покрыть отдельными тестовыми payload.
const src = $json.body ?? $json;
const externalOrderId = String(src.external_order_id ?? '').trim();
if (!externalOrderId) throw new Error('No external_order_id for 1C exchange');
const items = Array.isArray(src.items) ? src.items : [];
if (!items.length) throw new Error(`Order ${externalOrderId} has no items`);
const payloadFor1c = {
НомерВнешний: externalOrderId,
Идемпотентность: src.idempotency_key ?? `shop:order:${externalOrderId}:create`,
Клиент: {
Наименование: String(src.customer?.name ?? '').trim(),
Телефон: String(src.customer?.phone ?? '').replace(/[^0-9+]/g, ''),
ИНН: String(src.customer?.inn ?? '').replace(/\D/g, '')
},
Товары: items.map(i => ({ Артикул: String(i.sku).trim(), Количество: Number(i.qty), Цена: Number(i.price) })),
Оплата: src.payment_status ?? 'unknown',
Доставка: src.delivery ?? {},
ДатаПолучения: new Date().toISOString()
};
return [{ json: { idempotency_key: payloadFor1c.Идемпотентность, endpoint: '/hs/n8n/orders', payload_for_1c: payloadFor1c } }];
Готовый workflow JSON: скачать и импортировать ¶
Файл /assets/workflows/integration-1c-n8n-http-order-exchange.json можно импортировать в n8n как основу. После импорта замените credentials, endpoint, ID склада/магазина/инфобазы и правила mapping под ваш контур.
{
"name": "Nodbot - 1C HTTP order exchange with idempotency",
"nodes": [
{
"name": "Webhook from shop/CRM",
"purpose": "Принимает заказ, оплату или изменение статуса"
},
{
"name": "Validate contract",
"purpose": "Проверяет товары, суммы, клиента и обязательные поля"
},
{
"name": "Idempotency storage",
"purpose": "Фиксирует ключ до write-операции или атомарно вместе с результатом"
},
{
"name": "HTTP Request to 1C",
"purpose": "Передаёт JSON/XML в HTTP-сервис или OData endpoint"
},
{
"name": "Review / Alert",
"purpose": "Отправляет понятную ошибку владельцу процесса"
}
],
"connections": "Webhook → Normalize → Idempotency → API Request → Audit/Respond"
}
Пошаговая настройка ¶
- Согласуйте договор обмена с владельцем 1C: сущности, source of truth, ключи, статусы и ошибки.
- Опубликуйте HTTP-сервис 1C или OData endpoint за HTTPS/VPN/IP allowlist.
- Импортируйте workflow JSON, замените endpoint, auth и mapping полей под вашу конфигурацию.
- Проверьте повторный заказ и частичный сбой: дубль документа в 1C появляться не должен.
- Настройте DLQ и human-readable сообщения для бухгалтера, склада или поддержки.
Что проверить после импорта workflow
Откройте каждую ноду, замените credentials, включите dry-run там, где есть write-действия, и выполните тест на отдельной сущности. Не запускайте массовую синхронизацию до проверки дублей, лимитов API и rollback-плана.
Тесты перед production ¶
Минимальный smoke test:
curl -X POST "https://YOUR-N8N-DOMAIN/webhook/1c-http-order-exchange" \
-H "Content-Type: application/json" \
--data @integration-1c-n8n-http-order-exchange-payload.json- повторный external_order_id
- неизвестный SKU
- неполный контрагент
- таймаут 1C после записи документа
- ошибка прав 401/403
- отмена или возврат заказа
Отдельно проверьте, что retry n8n не создаёт повторную запись. Для критичных действий используйте durable storage: Postgres, custom field, audit table или другой слой с уникальным ключом.
Production-риски ¶
- 1C endpoint открыт наружу без IP allowlist, VPN или отдельного технического пользователя.
- n8n пытается заменить бизнес-логику 1C и создаёт документы без проверок.
- Идемпотентность хранится только в execution data и теряется после очистки.
- Ошибки приходят в виде stack trace, который не помогает бухгалтерии исправить заказ.
- Остатки и оплаты меняются без approval и rollback-плана.
Полезные ссылки и смежные материалы ¶
- 1C:Enterprise HTTP services
- n8n HTTP Request node
- 1C HTTP exchange workflow
- МойСклад и n8n
- Idempotency keys в n8n
Критерии готовности ¶
- Есть договор обмена и владелец каждого поля.
- Повторный заказ не создаёт второй документ в 1C.
- HTTP-сервис защищён, а credentials имеют минимальные права.
- Ошибки разделены на retry, review, incident и idempotent skip.
- Есть журнал exchange_id, request, response, onec_ref и replay policy.