Перейти к содержанию

Интеграция Ozon Seller API и n8n: заказы, остатки и отчёты без ручной выгрузки

Обновлено: 2026-05-30

AI summary: Problem/Solution-гайд по Ozon Seller API и n8n: как автоматизировать получение заказов, обновление остатков и отчёты без ручных выгрузок из кабинета продавца.
Готовый blueprint для внедрения

Импортируйте JSON в n8n, замените credentials, URL API, project/list IDs, поля и лимиты под вашу инфраструктуру.

Проблема: Маркетплейс Ozon генерирует заказы, остатки и отчёты, но ручная выгрузка из кабинета продавца не подходит для ежедневной операционной работы.

Решение: Надёжная интеграция Ozon Seller API и n8n строится на расписании, cursor/since-параметрах, нормализации posting_number/SKU, журнале обработанных заказов и безопасном обновлении CRM, склада или таблицы.

Схема интеграции Ozon Seller API и n8n для заказов, остатков и отчётов
Схема показывает polling Ozon Seller API с нормализацией и безопасной записью в CRM, склад или таблицу.

Проблема: почему простая интеграция создаёт дубли и ручной хаос

Ozon-интеграция отличается от классического webhook-сценария. Часто нужен не один входящий POST, а регулярный polling: забрать новые отправления, обновить статусы, сверить остатки, выгрузить отчёт и отправить расхождения в Telegram или CRM.

Главный риск — повторно обработать один и тот же posting_number или потерять заказ между окнами выгрузки. Поэтому workflow должен хранить last_success_at, использовать overlap-окно, дедуплицировать по posting_number и SKU, а также логировать ответы Seller API.

Архитектура workflow для n8n

БлокЗадачаProduction-проверка
Schedule Triggerзапускает polling Ozon Seller APIчастота не превышает лимиты
Build request windowсобирает since/to с overlaplast_success_at хранится durable
Fetch postings/stocksзапрашивает заказы, остатки или отчётыClient-Id и API-Key в credentials
Normalize Ozon dataготовит posting_number, sku, offer_id и statusнет пустых SKU и статусов
Upsert downstreamобновляет CRM, склад или Google Sheetsключ posting_number+sku
Alert and cursorсохраняет cursor и шлёт alert по ошибкамне терять окно при падении

Для Ozon важно не только получить ответ API, но и правильно вести состояние синхронизации. Cursor или last_success_at должны обновляться только после успешной записи downstream.

Контракт входных данных

{
  "mode": "poll_postings",
  "date_from": "2026-05-30T00:00:00Z",
  "date_to": "2026-05-30T23:59:59Z",
  "posting_number": "12345-0001-1",
  "status": "awaiting_packaging",
  "products": [
    {
      "sku": 123456789,
      "offer_id": "N8N-SETUP",
      "name": "Услуга настройки n8n",
      "quantity": 1,
      "price": "12900.00"
    }
  ],
  "analytics_data": {
    "region": "Москва"
  },
  "financial_data": {
    "products": [
      {
        "commission_amount": "650.00"
      }
    ]
  }
}

Payload в статье имитирует нормализованный объект после API-запроса. В production исходный ответ Ozon лучше сохранять отдельно, а в downstream передавать только стабильный контракт.

Code Node: нормализация, mapping и guard-условия

const src = $json.body ?? $json;
const posting = src.posting ?? src;
const postingNumber = String(posting.posting_number ?? posting.order_number ?? '').trim();
if (!postingNumber) throw new Error('No Ozon posting_number');
const products = Array.isArray(posting.products) ? posting.products.map(p => ({
  sku: String(p.sku ?? '').trim(),
  offer_id: String(p.offer_id ?? '').trim(),
  name: String(p.name ?? '').trim(),
  quantity: Number(p.quantity ?? 0),
  price: Number(p.price ?? 0)
})) : [];
if (!products.length) throw new Error(`No Ozon products for posting ${postingNumber}`);
return products.map(product => ({ json: {
  action: 'upsert_ozon_posting_line',
  idempotency_key: `ozon:${postingNumber}:${product.sku || product.offer_id}`,
  posting_number: postingNumber,
  status: String(posting.status ?? '').trim(),
  sku: product.sku,
  offer_id: product.offer_id,
  product_name: product.name,
  quantity: product.quantity,
  price: product.price,
  region: String(posting.analytics_data?.region ?? '').trim(),
  synced_at: new Date().toISOString()
}}));
Почему polling нужен с overlap-окном

Если брать данные строго с момента последнего успешного запуска, можно потерять отправление из-за задержки индексации или ошибки времени. Небольшой overlap и дедупликация по posting_number позволяют безопасно перечитывать последние минуты.

Готовый workflow JSON: скачать и импортировать

Скачать готовый workflow JSON Скачать тестовый payload

{
  "name": "Nodbot - Ozon Seller API postings and stock sync",
  "nodes": [
    {
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.webhook",
      "purpose": "Запускать polling"
    },
    {
      "name": "Build Ozon request window",
      "type": "n8n-nodes-base.code",
      "purpose": "Собрать date_from/date_to"
    },
    {
      "name": "Fetch Ozon Seller API",
      "type": "n8n-nodes-base.httpRequest",
      "purpose": "Получить postings/stocks"
    },
    {
      "name": "Normalize Ozon data",
      "type": "n8n-nodes-base.code",
      "purpose": "Собрать стабильный контракт"
    },
    {
      "name": "Upsert CRM or warehouse",
      "type": "n8n-nodes-base.httpRequest",
      "purpose": "Обновить downstream"
    },
    {
      "name": "Alert and save cursor",
      "type": "n8n-nodes-base.httpRequest",
      "purpose": "Зафиксировать состояние"
    }
  ],
  "connections": "Schedule Trigger → Build Ozon request window → Fetch Ozon Seller API → Normalize Ozon data → Upsert CRM or warehouse → Alert and save cursor"
}

Пошаговая настройка связки

  1. Создайте отдельные Ozon Client-Id и API-Key для интеграции.
  2. Определите сценарий: postings, stocks, prices или reports.
  3. Импортируйте workflow JSON и задайте расписание с overlap-окном.
  4. Сохраните last_success_at в Postgres, static data или другой durable storage.
  5. Проверьте повторный запуск на том же окне: записи не должны дублироваться.

Тесты перед production

curl -X POST "https://YOUR-N8N-DOMAIN/webhook/integration-ozon-seller-api-n8n-stock-orders" \
  -H "Content-Type: application/json" \
  --data @integration-ozon-seller-api-n8n-stock-orders-payload.json
  1. Повторный payload не создаёт дубль и возвращает тот же output key.
  2. Некорректный mapping останавливается до запроса к внешнему API.
  3. Пустые необязательные поля не ломают workflow.
  4. Ошибка API уходит в alert или DLQ с безопасным payload.
  5. Execution data не содержит секретов, токенов и лишних персональных данных.

Production-риски

  • Cursor обновляется до записи. При падении downstream заказ будет потерян.
  • Нет overlap-окна. Поздние изменения Ozon не попадут в sync.
  • posting_number не является ключом строк товаров. Для line items нужен posting_number+sku или offer_id.
  • API-Key хранится в Code Node. Секрет попадёт в экспорт workflow.
  • Лимиты API игнорируются. Частый polling создаст 429 и пропуски в синхронизации.
Карточка результата Ozon sync с posting number, SKU и статусом
Пример результата: отправление Ozon разложено по строкам товаров и обновлено без дублей.

Критерии готовности

  1. Client-Id и API-Key хранятся в credentials или ENV.
  2. Polling использует overlap и durable last_success_at.
  3. posting_number+sku защищает строки товаров от дублей.
  4. Cursor обновляется только после успешного downstream-sync.
  5. Ошибки Seller API, 401/403/429 и пустые ответы уходят в alert.
Нужно автоматизировать Ozon без ручных выгрузок?

Nodbot настроит Ozon Seller API + n8n: polling заказов, остатки, отчёты, cursor, дедупликацию, alert, retry и передачу в CRM, склад или Google Sheets.

Обсудить Ozon-интеграцию