Интеграция Ozon Seller API и n8n: заказы, остатки и отчёты без ручной выгрузки ¶
Обновлено: 2026-05-30
Импортируйте JSON в n8n, замените credentials, URL API, project/list IDs, поля и лимиты под вашу инфраструктуру.
Проблема: Маркетплейс Ozon генерирует заказы, остатки и отчёты, но ручная выгрузка из кабинета продавца не подходит для ежедневной операционной работы.
Решение: Надёжная интеграция Ozon Seller API и n8n строится на расписании, cursor/since-параметрах, нормализации posting_number/SKU, журнале обработанных заказов и безопасном обновлении 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 с overlap | last_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"
}
Пошаговая настройка связки ¶
- Создайте отдельные Ozon Client-Id и API-Key для интеграции.
- Определите сценарий: postings, stocks, prices или reports.
- Импортируйте workflow JSON и задайте расписание с overlap-окном.
- Сохраните last_success_at в Postgres, static data или другой durable storage.
- Проверьте повторный запуск на том же окне: записи не должны дублироваться.
Тесты перед 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- Повторный payload не создаёт дубль и возвращает тот же output key.
- Некорректный mapping останавливается до запроса к внешнему API.
- Пустые необязательные поля не ломают workflow.
- Ошибка API уходит в alert или DLQ с безопасным payload.
- 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 Seller API introduction
- Ozon API documentation
- МойСклад и n8n
- МойСклад stock alert
- Wildberries и n8n
- Google Sheets и n8n
Критерии готовности ¶
- Client-Id и API-Key хранятся в credentials или ENV.
- Polling использует overlap и durable last_success_at.
- posting_number+sku защищает строки товаров от дублей.
- Cursor обновляется только после успешного downstream-sync.
- Ошибки Seller API, 401/403/429 и пустые ответы уходят в alert.
Nodbot настроит Ozon Seller API + n8n: polling заказов, остатки, отчёты, cursor, дедупликацию, alert, retry и передачу в CRM, склад или Google Sheets.
Обсудить Ozon-интеграцию