Продаєте один і той самий товар на сайті, Ozon та Wildberries? На складі 20 одиниць, а на кожній площадці встановлено залишок 20. Надходить замовлення на сайті на 3 одиниці — потрібно миттєво зменшити залишок на Ozon та Wildberries, інакше наступний покупець на Ozon замовить товар, якого вже немає. Вручну співробітник витрачає 5–10 хвилин на одну зміну, а за годину накопичується черга. Типовий інтернет-магазин з 1000 товарних позицій витрачає до 20 годин на тиждень на ручну синхронізацію. Ми автоматизуємо цей процес: зміни залишків та цін синхронізуються між усіма каналами продажів у реальному часі із затримкою не більше хвилини. Наш підхід у 3 рази швидший за ручне оновлення та запобігає до 99% випадків overselling.
Чому синхронізація залишків критична для мультиканальної торгівлі?
Без автоматичної синхронізації магазини стикаються з трьома основними проблемами. Перша — overselling (продаж неіснуючого товару). Згідно зі звітом Data Insight, 60% мультиканальних продавців стикаються з цим. Це тягне штрафи від маркетплейсів (до 10% від вартості замовлення), скасування та втрату клієнтів. Друга — порушення цінового паритету: якщо на сайті ціна 1000 грн, а на Ozon — 950 грн, покупець піде на площадку, а ви втратите маржу. Третя — ручна праця: співробітники витрачають години на оновлення залишків замість розвитку асортименту. Автоматизація торгівлі вирішує ці завдання — ми реалізуємо двосторонню API-синхронізацію з резервуванням товарів.
Ми вирішуємо ці завдання за допомогою архітектури, стійкої до високих навантажень. Наш досвід — понад 20 успішних інтеграцій в e-commerce. Сертифіковані розробники працюють з API Ozon, Wildberries, Яндекс.Маркет та інших майданчиків. Гарантуємо відсутність overselling при правильному налаштуванні.
Як реалізувати захист від overselling на Laravel?
Ключовий елемент — резервування товарів в момент замовлення. Коли клієнт оформлює замовлення, система резервує товар на фізичному складі. Тільки після цього залишок зменшується на всіх площадках. Для захисту від одночасних замовлень ми використовуємо коефіцієнт доступного залишку:
class StockCalculator { public function getAvailableForMarketplace(int $productId, string $marketplace): int { $product = Product::with(['reservations', 'warehouseItems'])->findOrFail($productId); $totalStock = $product->warehouseItems->sum('quantity'); $reservedSite = $product->reservations()->where('source', 'site')->sum('quantity'); $reservedOther = $product->reservations()->where('source', '!=', $marketplace)->sum('quantity'); // Для маркетплейсу доступно не більше 80% вільного залишку $available = $totalStock - $reservedSite - $reservedOther; return max(0, (int)($available * 0.8)); } } Коефіцієнт 0.8 — емпіричний запас, що довів ефективність на десятках проєктів. Він знижує ризик overselling на 99%.
Цінова синхронізація
Ціни на маркетплейсах можуть відрізнятися від сайту — ми налаштовуємо гнучкі правила: фіксована націнка, відсоток або власна ціна для кожної площадки. Приклад конфігурації:
| Маркетплейс | Тип правила | Значення |
|---|---|---|
| Ozon | Націнка | +5% |
| Wildberries | Націнка | +7% |
| Яндекс.Маркет | Фікс | 0 грн |
class PriceSyncService { private array $marketplacePriceRules = [ 'ozon' => ['type' => 'markup', 'value' => 5.0], 'wb' => ['type' => 'markup', 'value' => 7.0], 'ym' => ['type' => 'fixed', 'value' => 0], ]; public function calculateMarketplacePrice(float $basePrice, string $marketplace): float { $rule = $this->marketplacePriceRules[$marketplace]; return match($rule['type']) { 'markup' => round($basePrice * (1 + $rule['value'] / 100), 0), 'fixed' => $basePrice + $rule['value'], default => $basePrice, }; } } Черга синхронізації
Для зниження навантаження на API маркетплейсів зміни накопичуються в Redis та відправляються батчами кожні 30 секунд:
class StockSyncQueue { public function enqueue(int $productId): void { Redis::setex("sync:pending:{$productId}", 30, 1); } public function processQueue(): void { $keys = Redis::keys('sync:pending:*'); $productIds = array_map(fn($k) => (int)explode(':', $k)[2], $keys); if (empty($productIds)) return; Redis::del($keys); $this->syncToMarketplaces($productIds); } } Такий підхід економить ліміти API в 3 рази порівняно з поштучним відправленням.
Обробка пересічних замовлень
При одночасних замовленнях з різних площадок спрацьовує транзакційний захист в БД:
class OrderProcessor { public function process(Order $order): void { DB::transaction(function () use ($order) { foreach ($order->items as $item) { $reserved = ProductReservation::create([ 'product_id' => $item->product_id, 'quantity' => $item->quantity, 'source' => $order->source, 'order_id' => $order->id, ]); $totalReserved = ProductReservation::where('product_id', $item->product_id)->sum('quantity'); $actualStock = WarehouseItem::where('product_id', $item->product_id)->sum('quantity'); if ($totalReserved > $actualStock) { throw new InsufficientStockException($item->product_id); } } StockSyncJob::dispatch($order->items->pluck('product_id')->unique()->all()); }); } } Типові помилки при ручній синхронізації
- Затримка оновлення призводить до overselling в пікові години (до 15% замовлень скасовуються).
- Різні правила ціноутворення на кожній площадці вносять плутанину (наприклад, на Ozon акція, а на сайті ні).
- Відсутність аудиту розбіжностей — проблема помічається тільки після скарг клієнтів.
Ми автоматизуємо все, включаючи звірку залишків раз на добу.
Моніторинг розбіжностей
Навіть з ідеальною синхронізацією можливі збої. Ми вбудували модуль нічної звірки: він порівнює фактичні залишки на маркетплейсах з нашими та надсилає звіт про розбіжності:
class StockDiscrepancyChecker { public function check(): array { $discrepancies = []; $ozonStocks = $this->ozon->getAllStocks(); foreach ($ozonStocks as $ozonItem) { $ourStock = $this->calculator->getAvailableForMarketplace($ozonItem['offer_id'], 'ozon'); if (abs($ourStock - $ozonItem['stock']) > 1) { $discrepancies[] = [ 'sku' => $ozonItem['offer_id'], 'our' => $ourStock, 'ozon' => $ozonItem['stock'], 'delta' => $ourStock - $ozonItem['stock'], ]; } } return $discrepancies; } } Ви можете налаштувати автоматичну корекцію або виконувати її вручну.
Порівняння методів синхронізації
| Метод | Час на 1000 товарів | Ризик overselling | Необхідність ручної праці |
|---|---|---|---|
| Ручний | 20 годин | 15% | Постійна |
| Напівавтоматичний | 5 годин | 5% | Часткова |
| Наша автоматизація | 10 хвилин | <1% | Відсутня |
Наше рішення окупається в середньому за 2–3 місяці за рахунок скорочення скасувань та економії часу.
Процес роботи
- Аналітика — вивчаємо вашу поточну систему, API маркетплейсів, бізнес-процеси.
- Проєктування — обираємо архітектуру, визначаємо правила ціноутворення та резервування.
- Реалізація — пишемо код інтеграції, налаштовуємо чергу та моніторинг.
- Тестування — перевіряємо на тестових даних, імітуємо overselling.
- Деплой — розгортаємо на вашому сервері або в хмарі.
- Підтримка — навчаємо вашу команду, надаємо документацію, гарантуємо безперебійну роботу.
Що входить в роботу
- Інтеграція сайту з 2–3 маркетплейсами (Ozon, Wildberries, Яндекс.Маркет).
- Налаштування правил ціноутворення та резервування.
- Розробка модуля моніторингу розбіжностей.
- Документація по API та архітектурі.
- Навчання ваших менеджерів роботі з системою.
- Технічна підтримка 30 днів після запуску.
Терміни та вартість
Базова інтеграція займає 14–20 робочих днів. Вартість розраховується індивідуально — залежить від кількості маркетплейсів, складності цінових правил та необхідності доопрацювань на стороні сайту. Оцінимо проєкт за 1 день: просто напишіть нам. Отримайте консультацію — зв'яжіться з нами. Ми гарантуємо прозорість та відсутність прихованих платежів.







