Интеграция Wildberries и n8n: заказы, остатки и цены без ручных CSV ¶
Проблема: Wildberries API даёт доступ к заказам, остаткам, ценам и отчётам, но без слоя контроля workflow легко перезаливает весь каталог, продаёт больше доступного остатка или меняет цены без объяснимой причины.
Решение: Решение — обрабатывать WB как операционный канал: хранить mapping nmID/vendorCode/barcode/internal_sku, считать доступный остаток с safety stock, делать idempotent import заказов и отправлять цены только после policy-check.
Материал закрывает практический интент: интеграция Wildberries и n8n, WB API, заказы FBS, синхронизация остатков Wildberries, автоматизация маркетплейса, обновление цен через API. Внутри есть импортируемый 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 для интеграции ¶
| Нода | Роль | Что проверить |
|---|---|---|
| Schedule / Webhook | Забирает заказы, остатки или задания на обновление | магазин, endpoint, период, токен |
| Normalize WB payload | Приводит nmID/vendorCode/barcode к внутреннему SKU | mapping найден и не конфликтует |
| Policy check | Проверяет остаток, цену, склад, лимиты и safety stock | нет oversell и резкого падения цены |
| WB API request | Отправляет только изменившиеся остатки/цены или импортирует заказ | rate limit, retry, response code |
| Reconciliation | Сверяет WB и внутренний учёт | расхождения, reviewer, replay key |
Почему не стоит начинать с “синхронизировать всё”
У каждой системы есть зоны ответственности. Сначала автоматизируйте один поток: заказ, остаток, цена или уведомление. После стабильных тестов добавляйте второй поток и общую сверку. Иначе ошибки разных процессов смешаются в одном execution.
Контракт входных данных ¶
Контракт нужен для тестов, replay и передачи задачи между разработчиком, интегратором и владельцем процесса. Не завязывайтесь на текстовое название товара или клиента: используйте стабильные внешние ID, артикулы, event_id, timestamp и idempotency key.
{
"event_id": "wb-order-981244",
"event_type": "fbs_order.created",
"wb_order_id": "981244",
"rid": "wb-rid-001",
"nm_id": 123456789,
"vendor_code": "SKU-001",
"barcode": "4600000000011",
"warehouse_id": "wb-fbs-msk",
"qty": 1,
"price": 3490,
"customer_region": "Москва",
"created_at": "2026-05-30T10:00:00+03:00"
}
Нормализация и проверка данных в Code Node ¶
Code Node ниже не заменяет всю бизнес-логику, но задаёт безопасный вход: выбрасывает пустые обязательные поля, приводит идентификаторы к единому виду и формирует ключ идемпотентности. В production этот блок лучше покрыть отдельными тестовыми payload.
const src = $json.body ?? $json;
const vendorCode = String(src.vendor_code ?? src.vendorCode ?? '').trim().toUpperCase();
const nmId = Number(src.nm_id ?? src.nmID ?? 0);
const barcode = String(src.barcode ?? '').trim();
const wbOrderId = String(src.wb_order_id ?? src.orderId ?? '').trim();
if (!wbOrderId) throw new Error('No Wildberries order id');
if (!vendorCode && !barcode && !nmId) throw new Error(`No WB mapping keys for order ${wbOrderId}`);
const availableQty = Math.max(0, Number(src.stock_physical ?? src.qty ?? 0) - Number(src.reserve ?? 0) - Number(src.safety_stock ?? 1));
return [{ json: {
idempotency_key: `wildberries:fbs:${wbOrderId}`,
mapping: { vendor_code: vendorCode, nm_id: nmId, barcode },
warehouse_id: String(src.warehouse_id ?? ''),
available_qty_for_wb: availableQty,
operation: src.event_type?.includes('order') ? 'import_order' : 'sync_stock',
price_policy: { max_drop_percent: 15, require_approval: Number(src.price_change_percent ?? 0) < -15 },
audit: { event_id: src.event_id, received_at: new Date().toISOString() }
}}];
Готовый workflow JSON: скачать и импортировать ¶
Файл /assets/workflows/integration-wildberries-n8n-orders-stock-sync.json можно импортировать в n8n как основу. После импорта замените credentials, endpoint, ID склада/магазина/инфобазы и правила mapping под ваш контур.
{
"name": "Nodbot - Wildberries orders stock price sync with safeguards",
"nodes": [
{
"name": "Schedule / Webhook",
"purpose": "Забирает заказы, остатки или задания на обновление"
},
{
"name": "Normalize WB payload",
"purpose": "Приводит nmID/vendorCode/barcode к внутреннему SKU"
},
{
"name": "Policy check",
"purpose": "Проверяет остаток, цену, склад, лимиты и safety stock"
},
{
"name": "WB API request",
"purpose": "Отправляет только изменившиеся остатки/цены или импортирует заказ"
},
{
"name": "Reconciliation",
"purpose": "Сверяет WB и внутренний учёт"
}
],
"connections": "Webhook → Normalize → Idempotency → API Request → Audit/Respond"
}
Пошаговая настройка ¶
- Разделите токены: read-only для отчётов и отдельный write-token для остатков/цен.
- Создайте таблицу mapping: internal_sku, vendorCode, barcode, nmID, warehouse_id, status.
- Импортируйте workflow JSON и включите dry-run для обновления цен и остатков.
- Проверьте повторный WB order id и убедитесь, что задача на склад не создаётся дважды.
- Настройте ежедневную сверку WB заказов, внутренних заказов, остатков и последних отправленных цен.
Что проверить после импорта workflow
Откройте каждую ноду, замените credentials, включите dry-run там, где есть write-действия, и выполните тест на отдельной сущности. Не запускайте массовую синхронизацию до проверки дублей, лимитов API и rollback-плана.
Тесты перед production ¶
Минимальный smoke test:
curl -X POST "https://YOUR-N8N-DOMAIN/webhook/wildberries-orders-stock-sync" \
-H "Content-Type: application/json" \
--data @integration-wildberries-n8n-orders-stock-sync-payload.json- дубль FBS-заказа
- неизвестный barcode
- нулевой остаток при активном товаре
- резкое снижение цены
- API 429 и временный 5xx
- ручной replay за один период и один магазин
Отдельно проверьте, что retry n8n не создаёт повторную запись. Для критичных действий используйте durable storage: Postgres, custom field, audit table или другой слой с уникальным ключом.
Production-риски ¶
- Нет mapping nmID/vendorCode/barcode, поэтому остаток уходит в неправильную карточку.
- Workflow обновляет все цены без dry-run и approval.
- Остаток отправляется без safety stock и приводит к oversell.
- Повторный заказ создаёт вторую задачу на склад.
- WB API меняется, а workflow не имеет владельца и регрессионных тестов.
Полезные ссылки и смежные материалы ¶
- Wildberries API documentation
- n8n HTTP Request node
- МойСклад и n8n
- Ozon и n8n
- Retry и DLQ для HTTP Request
Критерии готовности ¶
- Каждый WB order id обрабатывается один раз.
- Для SKU есть mapping и правило unknown/review.
- Остаток считается как available qty, а не копируется напрямую.
- Изменения цены проходят policy-check и dry-run.
- Есть reconciliation-отчёт и безопасный replay.