Ручне оновлення залишків на маркетплейсах — джерело постійних проблем. Продавець виставляє 10 одиниць, а на складі залишилося 3. Замовлення оформлюється, але не відвантажується — маркетплейс штрафує, рейтинг картки падає. Співробітники витрачають години на звірку цифр, але людський фактор неминучий: забули оновити, помилилися в кількості, не врахували резерв. Наш досвід — 5+ років і 50+ успішних проектів з інтеграції облікових систем з маркетплейсами. Порівняно з ручним оновленням, автоматичний бот скорочує час управління стоком у 10 разів і знижує кількість скасованих замовлень на 70%. Типова економія на штрафах — рассчитывается индивидуально.
Чому автоматизація вигідніша за ручне оновлення?
Ручне введення через особистий кабінет забирає 1–2 години щодня для магазину з 5000 позицій. Помилка в одній цифрі призводить до каскаду проблем: скасування замовлень, негативний рейтинг, втрата позицій у видачі. Наш бот обробляє зміни за секунди, виключаючи помилки. Він бере дані безпосередньо з облікової системи — жодних описок. У результаті рейтинг карток зростає, а кількість скасованих замовлень знижується на 70%.
Кейс з практики: Для клієнта з каталогом 15 000 SKU ручне оновлення займало 4 години щодня. Після впровадження бота час скоротився до 10 хвилин, а кількість скасованих замовлень впала на 70%. Штрафи за невірний сток були виключені повністю. Порівняно з використанням універсальних ERP-модулів, наш бот дає більш гнучке налаштування буфера та алептів.
Згідно з офіційною документацією Ozon API, PUT /v2/products/stocks дозволяє оновлювати до 100 товарів за запит.
Як ми інтегруємося з джерелами даних?
Джерел декілька, їх потрібно агрегувати. Основне — ваша складська система (1С, МійСклад, Odoo). Додатково підключаємо постачальників (через імпорт) і зчитуємо резерв маркетплейсів. Також враховуємо віртуальний резерв з власного сайту — відкриті кошики.
| Облікова система | Метод інтеграції | Складність |
|---|---|---|
| 1С | HTTP-сервіс (REST) або вебхук | Середня |
| МійСклад | REST API | Низька |
| Odoo | XML-RPC / JSON-RPC | Середня |
Схема даних будується на таблицях stock_levels, marketplace_stocks та stock_sync_log. Перша зберігає загальні залишки та резерв, друга — актуальні для кожного маркетплейсу, третя — історію синхронізацій для дебагу.
CREATE TABLE stock_levels ( id BIGSERIAL PRIMARY KEY, product_id BIGINT REFERENCES products(id), warehouse_id INT REFERENCES warehouses(id), quantity INT NOT NULL DEFAULT 0, reserved INT NOT NULL DEFAULT 0, available INT GENERATED ALWAYS AS (quantity - reserved) STORED, updated_at TIMESTAMP DEFAULT NOW() ); CREATE TABLE marketplace_stocks ( id BIGSERIAL PRIMARY KEY, product_id BIGINT REFERENCES products(id), marketplace VARCHAR(50) NOT NULL, warehouse_code VARCHAR(100), synced_quantity INT, last_synced_at TIMESTAMP, sync_status VARCHAR(20) DEFAULT 'ok', error_message TEXT, UNIQUE(product_id, marketplace, warehouse_code) ); CREATE TABLE stock_sync_log ( id BIGSERIAL PRIMARY KEY, product_id BIGINT, marketplace VARCHAR(50), old_qty INT, new_qty INT, source VARCHAR(50), synced_at TIMESTAMP DEFAULT NOW() ); Інтеграція з Ozon API
Оновлення залишків виконується через ендпоінт PUT /v2/products/stocks. Ми надсилаємо батчі по 100 товарів, щоб не перевищити ліміт.
class OzonStockSyncer { public function syncStocks(array $items): SyncResult { $result = new SyncResult(); $batches = array_chunk($items, 100); foreach ($batches as $batch) { $payload = array_map(fn($item) => [ 'offer_id' => $item['sku'], 'stock' => $item['qty'], 'warehouse_id' => $item['warehouse_id'], ], $batch); $response = Http::withHeaders([ 'Client-Id' => $this->clientId, 'Api-Key' => $this->apiKey, ])->post('https://api-seller.ozon.ru/v2/products/stocks', [ 'stocks' => $payload, ]); if (!$response->successful()) { $result->errors[] = $response->json('message', 'Unknown error'); continue; } foreach ($response->json('result', []) as $item) { if ($item['updated']) { $result->updated++; } else { $result->errors[] = "SKU {$item['offer_id']}: " . ($item['errors'][0]['message'] ?? 'error'); } } } return $result; } } Інтеграція з Wildberries
Wildberries використовує PUT-запит до /api/v3/warehouses/{warehouseId}/stocks. Код аналогічний, але з урахуванням особливостей — токен у заголовку, мапінг через barcode.
class WildberriesStockSyncer { public function syncStocks(array $items, int $warehouseId): SyncResult { $payload = array_map(fn($item) => [ 'sku' => $item['wb_barcode'], 'amount' => max(0, $item['qty']), ], $items); $response = Http::withToken($this->apiKey) ->put("https://marketplace-api.wildberries.ru/api/v3/warehouses/{$warehouseId}/stocks", [ 'stocks' => $payload, ]); if (!$response->successful()) { throw new WildberriesApiException($response->json('title', 'API Error')); } return new SyncResult(updated: count($items)); } } Як налаштувати буферний сток та алепти?
Часто потрібно тримати буфер — не вивантажувати весь залишок на маркетплейс, щоб резервувати для інших каналів. Ми реалізуємо гнучку логіку: абсолютний або відсотковий буфер, верхній ліміт по товару. Наприклад, для товару із залишком 50 одиниць можна встановити буфер 5 шт. або 10%. Тоді на маркетплейс піде лише 45 шт.
class StockCalculator { public function calculateMarketplaceQty(Product $product, string $marketplace): int { $available = $product->available_stock; $buffer = $product->stock_buffer ?? config("marketplaces.{$marketplace}.default_buffer", 2); $pctBuffer = (int) ceil($available * config("marketplaces.{$marketplace}.buffer_pct", 0) / 100); $reserved = max($buffer, $pctBuffer); $qty = max(0, $available - $reserved); $maxQty = $product->max_marketplace_stock ?? PHP_INT_MAX; return min($qty, $maxQty); } } Налаштовуємо алепти — якщо залишок на сайті більше нуля, а на маркетплейсі нуль вже 2 години, ви отримуєте повідомлення. Це страхує від розсинхронізації. Сценарії алептів:
| Ситуація | Повідомлення | Дія |
|---|---|---|
| Розсинхронізація > 1 години | Telegram / Email | Автоматична повторна синхронізація |
| Помилка API маркетплейсу | Telegram | Ручна перевірка логів |
| Вичерпання буфера | Поповнення складу |
Докладніше про порівняння API маркетплейсів
| Маркетплейс | Особливості API | Ліміт запитів | Швидкість оновлення |
|---|---|---|---|
| Ozon | PUT /v2/products/stocks | 100 товарів за запит | До 1 хвилини |
| Wildberries | PUT /api/v3/warehouses/{id}/stocks | 50 запитів/сек | До 2 хвилин |
Що входить в роботу?
| Складова | Опис |
|---|---|
| Документація | Архітектура, схема даних, інструкція з експлуатації |
| Доступи | Налаштування API-ключів, прав доступу до облікової системи та маркетплейсів |
| Навчання | Демонстрація роботи бота, розбір логів та алептів для вашої команди |
| Підтримка | Гарантійне обслуговування протягом місяця, потім — за договором |
Типові помилки при інтеграції
- Невірний артикул — різниця у форматах SKU між обліковою системою та маркетплейсом. Вирішується єдиною системою мапінгу.
- Перевищення ліміту запитів — занадто часті оновлення. Збільшуємо інтервал або використовуємо батчі.
- Помилка авторизації — прострочений токен. Налаштовуємо автоматичне оновлення ключів.
- Розбіжність залишків — відсутність обліку резервів. Впроваджуємо буферний сток.
Процес роботи
- Аналітика — вивчаємо вашу облікову систему, поточні API, обсяг каталогу.
- Проектування — схема даних, логіка буфера, інтеграційні модулі.
- Розробка — пишемо код синхронізації, алептів, логування.
- Тестування — на тестовому контурі перевіряємо всі сценарії (включно з помилками).
- Деплой — розгортання на вашому сервері або хмарі, налаштування моніторингу.
- Супровід — гарантійний період, навчання команди.
Строки реалізації
- Базова версія (Ozon + WB + 1С): 4–5 робочих днів.
- Складні буферні схеми та додаткові маркетплейси: +1–2 дні.
Отримайте консультацію — оцінимо ваш проект за один день. Замовте розробку бота, щоб позбутися штрафів та заощадити час співробітників.







