Keeping inventory accurate and up‑to‑date is paramount for any high‑volume retailer. For Wellcare and Raf Pharmacy—two leading pharmacy chains in Qatar with over 10,000 SKUs100+ brick‑and‑mortar stores, and active sales across Shopify web storesmobile apps, and POS systems—we built a robust, real‑time ERP‑to‑Shopify stock update solution. Below, we share our end‑to‑end architecture, code snippets, and performance results.

Объем проекта & Проблемы

  • Клиенты: Wellcare Pharmacy и Raf Pharmacy, Катар
  • Размер каталога: 10,000+ SKU
  • Каналы продаж: магазин Shopify, безголовые мобильные приложения, более 100 физических местоположений
  • ERP: INNSOF ERP обновление запасов
  • Требования:
    • Синхронизация в реальном времени для предотвращения перепродаж
    • Масштабируемость для большого объема обновлений
    • Минимальная задержка API и ошибки
    • Точное управление запасами на нескольких локациях

1. Начальный подход: Shopify REST API

Сначала мы использовали конечную точку REST Admin API Shopify /admin/api/2024‑01/inventory_levels/set.json для отправки обновлений запасов.

// Sample REST payload
$payload = [
  'location_id'      => $locationId,
  'inventory_item_id'=> $inventoryItemId,
  'available'        => $newStock
];
$response = $this->shopifyService->restRequest('POST', "/inventory_levels/set.json", $payload);

Ограничения REST API

  • Нет пакетных обновлений: Один SKU на запрос
  • Строгие лимиты на запросы: ~2 вызова/сек на магазин → узкое место для тысяч SKU
  • Высокая задержка: 50–100 мс на запрос, накапливающиеся задержки
  • Ошибки: Частые ошибки ограничения скорости под нагрузкой

2. Переход на Shopify GraphQL API

Чтобы преодолеть ограничения REST, мы перешли на GraphQL Admin API Shopify, открыв:

  • Пакетные обновления с inventoryAdjustQuantities мутацией
  • Троттлинг на основе стоимости (более гибкий, чем REST)
  • Снижение сетевых затрат путем запроса только необходимых полей
  • Корректировки на основе Delta (обновлять только при фактическом изменении акций)

3. Обзор архитектуры

  1. ERP → Промежуточное ПО
    • INNSOF ERP отправляет полезную нагрузку JSON через HTTP POST на наш StockController.
  2. Обогащение и журналирование
    • Мы разбираем, проверяем и записываем запрос в локальную БД (api_request_log).
    • Мы обогащаем каждый SKU с помощью location_id и inventory_item_id (из кэшированных таблиц).
  3. Получить текущие запасы
    • Получить существующие уровни запасов через GraphQL (по местоположению и SKU).
  4. Вычислить дельты
    • Сравните запасы ERP с запасами Shopify, чтобы определить дельту.
  5. Настроить инвентарь
    • Отправляйте одну мутацию GraphQL за раз (до 100 SKU).
  6. Обработка ответов
    • Записывайте успехи/неудачи и отправляйте статус обновления обратно в ERP.
  7. Повторы и резервное копирование
    • Автоматические задания cron повторяют неудачные партии; резервное копирование на REST при необходимости.

4. Получение текущих запасов через GraphQL

Точная калькуляция дельты начинается с получения существующих количеств. Мы обрабатываем до 60 предметов за запрос:

query inventoryItems {
  item1: inventoryItem(id: "gid://shopify/InventoryItem/123456789") {
    id
    tracked
    sku
    inventoryLevels(first: 10) {
      edges {
        node {
          location { id name }
          quantities(names: "available") {
            quantity
          }
        }
      }
    }
  }
  # item2, item3… up to 60
}

Наш метод PHP собирает их в массив:

private function getCurrentStock(array $products): array {
    $batches = array_chunk($products, 60);
    $results = [];
    foreach ($batches as $batch) {
        // Build GraphQL query dynamically…
        $response = $this->shopifyService->executeGraphQl($query, []);
        // Parse `$response['data']` into $results[]
    }
    return $results;  // [ ['inventory_item_id'=>…, 'location_id'=>…, 'quantity'=>…], … ]
}

5. Настройка запасов через GraphQL

Как только мы узнаем текущее количество акций, мы подготавливаем delta обновление полезной нагрузки:

Шаблон мутации

mutation AdjustMultipleInventoryQuantities($input: InventoryAdjustQuantitiesInput!) {
  inventoryAdjustQuantities(input: $input) {
    inventoryAdjustmentGroup {
      createdAt
      changes { name delta }
    }
    userErrors { field message }
  }
}

Формат переменных PHP

$changes = [];
foreach ($updatedProducts as $p) {
    $changes[] = [
      'inventoryItemId'=> "gid://shopify/InventoryItem/{$p['inventory_item_id']}",
      'locationId'     => "gid://shopify/Location/{$p['location_id']}",
      'delta'          => $p['erp_stock'] - $p['current_stock']
    ];
}

$variables = [
  'input' => [
    'reason'               => 'correction',
    'name'                 => 'available',
    'referenceDocumentUri' => 'logistics://erp/batch-2025-07-29',
    'changes'              => $changes
  ]
];

$response = $this->shopifyService->executeGraphQl($mutation, $variables);

Этот единственный вызов обновляет до 100 SKU за раз, значительно уменьшая сетевой шум.

6. Основные моменты оптимизации

  • Пакетирование и Чанкование: 60 элементов/запрос для чтения; 100 элементов/мутации для записи.
  • Локальное кэширование: Сохраните inventory_item_id & location_id в MySQL, чтобы избежать повторных запросов.
  • Delta Logic: Обновляйте только те SKU, чьи текущие запасы отличаются от запасов в ERP.
  • Осведомленность о лимитах частоты: Вставьте sleep()/usleep() стратегически и используйте REST для срочных повторных попыток.
  • Надежное ведение журнала: Каждый запрос и ответ записываются в api_request_log и stock_update_log таблицы.

7. Сравнение производительности

МетрикаREST APIGraphQL API
Поддержка пакетного обновления❌✅
Среднее время на 100 SKU~60 с~5 с
Ошибки ограничения скорости (под нагрузкой)ЧастыйРедкий
Точность в реальном времениУмеренныйВысокий
Интеграция обратной связи ERPЧастичныйПолный, зарегистрированный

8. Технологии и инструменты

  • Shopify GraphQL Admin API
  • PHP (StockController) с ShopifyServiceLogManagerDBOpsApiService
  • MySQL для локального кэширования и логов
  • INNSOF ERP вебхуки
  • Задачи Cron для повторных попыток и обратных вызовов ERP

9. Преимущества для Wellcare & Raf Pharmacy

  • 🔄 Точность акций в реальном времени в более чем 100 магазинах и каналах
  • 🚫 Никаких перепродаж и безупречный клиентский опыт
  • ⚡ Высокая пропускная способность: тысячи обновлений SKU в час
  • 🔍 Подробный аудит для соблюдения норм и отладки
  • 📈 Улучшенная SEO и UX на веб- и мобильных витринах

10. Часто задаваемые вопросы

  1. Почему нужно получать текущий запас перед обновлением?
    Это гарантирует, что мы рассчитываем правильный дельта, предотвращая случайные перезаписи или дублирующие корректировки.
  2. Сколько SKU может обработать GraphQL за раз?
    До 100 SKU за мутацию и 60 за запрос, настраиваемо в зависимости от плана магазина.
  3. Могу ли я смешивать REST и GraphQL?
    Да. Мы сохраняем REST в качестве резервного варианта для критических обновлений, когда GraphQL ограничивает.
  4. Работает ли многоместный инвентарь?
    Абсолютно. Мы запрашиваем и обновляем уровни по местоположениям, используя locationId.
  5. Подходит ли этот подход для других ERP?
    Да. Наша модульная конструкция может интегрироваться с Odoo, SAP, Oracle 6i и другими.

Почему стоит выбрать решения Seamedia для электронной коммерции?
В Seamedia мы объединяем глубокую экспертизу в Shopify с надежными знаниями интеграции ERP, чтобы предоставить индивидуальные, высокопроизводительные решения, которые приносят реальные бизнес-результаты. Наша команда, возглавляемая опытными консультантами, такими как Prajosh VM, понимает сложности многоместного учета запасов, высокие объемы SKU и омниканальную розницу. Мы разрабатываем масштабируемые, управляемые API рабочие процессы, которые поддерживают точность ваших запасов, удовлетворенность ваших клиентов и бесперебойную работу ваших операций. Независимо от того, являетесь ли вы быстрорастущей сетью аптек, национальным ритейлером или производственной компанией, Seamedia предлагает комплексную разработку, бесшовную связь с ERP и круглосуточную поддержку.

Готовы оптимизировать свой инвентарь и увеличить продажи?
Свяжитесь с нами сегодня по адресу hello@seamedia.in или посетите www.seamedia.in для обсуждения того, как мы можем создать индивидуальное решение для синхронизации запасов в реальном времени для вашего бизнеса.