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 SKUs, 100+ brick‑and‑mortar stores, and active sales across Shopify web stores, mobile 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.
- Объем проекта и вызовы
- 1. Начальный подход: Shopify REST API
- 2. Migration to Shopify GraphQL API
- 3. Overview of Architecture
- 4. Получение текущих запасов через GraphQL
- 5. Настройка запасов через GraphQL
- 6. Key Optimization Takeaways
- 7. Сравнение производительности
- 8. Технологии и инструменты
- 9. Преимущества для Wellcare и Raf Pharmacy
- 10. Frequently Asked Questions
Объем проекта & Проблемы
- Клиенты: 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. Обзор архитектуры
- ERP → Промежуточное ПО
- INNSOF ERP отправляет полезную нагрузку JSON через HTTP POST на наш
StockController.
- INNSOF ERP отправляет полезную нагрузку JSON через HTTP POST на наш
- Обогащение и журналирование
- Мы разбираем, проверяем и записываем запрос в локальную БД (
api_request_log). - Мы обогащаем каждый SKU с помощью
location_idиinventory_item_id(из кэшированных таблиц).
- Мы разбираем, проверяем и записываем запрос в локальную БД (
- Получить текущие запасы
- Получить существующие уровни запасов через GraphQL (по местоположению и SKU).
- Вычислить дельты
- Сравните запасы ERP с запасами Shopify, чтобы определить
дельту.
- Сравните запасы ERP с запасами Shopify, чтобы определить
- Настроить инвентарь
- Отправляйте одну мутацию GraphQL за раз (до 100 SKU).
- Обработка ответов
- Записывайте успехи/неудачи и отправляйте статус обновления обратно в ERP.
- Повторы и резервное копирование
- Автоматические задания 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 API | GraphQL API |
|---|---|---|
| Поддержка пакетного обновления | ||
| Среднее время на 100 SKU | ~60 с | ~5 с |
| Ошибки ограничения скорости (под нагрузкой) | Частый | Редкий |
| Точность в реальном времени | Умеренный | Высокий |
| Интеграция обратной связи ERP | Частичный | Полный, зарегистрированный |
8. Технологии и инструменты
- Shopify GraphQL Admin API
- PHP (StockController) с
ShopifyService,LogManager,DBOps,ApiService - MySQL для локального кэширования и логов
- INNSOF ERP вебхуки
- Задачи Cron для повторных попыток и обратных вызовов ERP
9. Преимущества для Wellcare & Raf Pharmacy
Точность акций в реальном времени в более чем 100 магазинах и каналах
Никаких перепродаж и безупречный клиентский опыт
Высокая пропускная способность: тысячи обновлений SKU в час
Подробный аудит для соблюдения норм и отладки
Улучшенная SEO и UX на веб- и мобильных витринах
10. Часто задаваемые вопросы
- Почему нужно получать текущий запас перед обновлением?
Это гарантирует, что мы рассчитываем правильный дельта, предотвращая случайные перезаписи или дублирующие корректировки. - Сколько SKU может обработать GraphQL за раз?
До 100 SKU за мутацию и 60 за запрос, настраиваемо в зависимости от плана магазина. - Могу ли я смешивать REST и GraphQL?
Да. Мы сохраняем REST в качестве резервного варианта для критических обновлений, когда GraphQL ограничивает. - Работает ли многоместный инвентарь?
Абсолютно. Мы запрашиваем и обновляем уровни по местоположениям, используяlocationId. - Подходит ли этот подход для других ERP?
Да. Наша модульная конструкция может интегрироваться с Odoo, SAP, Oracle 6i и другими.
Почему стоит выбрать решения Seamedia для электронной коммерции?
В Seamedia мы объединяем глубокую экспертизу в Shopify с надежными знаниями интеграции ERP, чтобы предоставить индивидуальные, высокопроизводительные решения, которые приносят реальные бизнес-результаты. Наша команда, возглавляемая опытными консультантами, такими как Prajosh VM, понимает сложности многоместного учета запасов, высокие объемы SKU и омниканальную розницу. Мы разрабатываем масштабируемые, управляемые API рабочие процессы, которые поддерживают точность ваших запасов, удовлетворенность ваших клиентов и бесперебойную работу ваших операций. Независимо от того, являетесь ли вы быстрорастущей сетью аптек, национальным ритейлером или производственной компанией, Seamedia предлагает комплексную разработку, бесшовную связь с ERP и круглосуточную поддержку.
Готовы оптимизировать свой инвентарь и увеличить продажи?
Свяжитесь с нами сегодня по адресу hello@seamedia.in или посетите www.seamedia.in для обсуждения того, как мы можем создать индивидуальное решение для синхронизации запасов в реальном времени для вашего бизнеса.