Att hålla inventeringen korrekt och uppdaterad är avgörande för alla högvolymåterförsäljare. För Wellcare och Raf Pharmacy—två ledande apotekskedjor i Qatar med över 10 000 SKU:er, 100+ fysiska butiker, och aktiva försäljningar över Shopify-webbbutiker, mobilappar, och POS-system—byggde vi en robust, realtidslösning för ERP-till-Shopify lageruppdatering. Nedan delar vi vår end-to-end-arkitektur, kodsnuttar och prestandaresultat.
- Projektets omfattning & utmaningar
- 1. Inledande tillvägagångssätt: Shopify REST API
- 2. Migrera till Shopify GraphQL API
- 3. Architecture Overview
- 4. Hämta nuvarande lager via GraphQL
- 5. Justera lager via GraphQL
- 6. Optimeringshöjdpunkter
- 7. Prestandajämförelse
- 8. Tekniker & Verktyg
- 9. Fördelar för Wellcare & Raf Pharmacy
- 10. Frequently Asked Questions
Projektets omfattning & utmaningar
- Kunder: Wellcare Pharmacy och Raf Pharmacy, Qatar
- Katalogstorlek: 10 000+ SKU:er
- Försäljningskanaler: Shopify-butik, headless mobilappar, 100+ fysiska platser
- ERP: INNSOF ERP trycker lageruppdateringar
- Krav:
- Synkronisering i realtid för att förhindra överförsäljning
- Skalbar för hög uppdateringsvolym
- Minimal API-latens och fel
- Noggrann lagerhantering för flera platser
1. Inledande tillvägagångssätt: Shopify REST API
Vi använde först Shopifys REST Admin API-endpoint /admin/api/2024‑01/inventory_levels/set.json för att skicka lageruppdateringar.
// 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-begränsningar
- Inga batchuppdateringar: En SKU per begäran
- Strikta hastighetsgränser: ~2 anrop/sek per butik → flaskhals för tusentals SKU:er
- Hög latens: 50–100 ms per begäran, ackumulerande fördröjningar
- Felbenägen: Frekventa hastighetsbegränsningsfel under belastning
2. Migrera till Shopify GraphQL API
För att övervinna REST-begränsningarna bytte vi till Shopifys GraphQL Admin API, vilket låser upp:
- Batchuppdateringar med
inventoryAdjustQuantitiesmutation - Kostnadsbaserad dämpning (mer flexibel än REST)
- Minska nätverksöverhead genom att begära endast nödvändiga fält
- Delta‑baserade justeringar (uppdatera endast när lagret faktiskt ändras)
3. Arkitekturöversikt
- ERP → Middleware
- INNSOF ERP skickar en JSON-payload via HTTP POST till vår
StockController.
- INNSOF ERP skickar en JSON-payload via HTTP POST till vår
- Berikning & Loggning
- Vi analyserar, validerar och loggar begäran i en lokal databas (
api_request_log). - Vi berikar varje SKU med
location_idochinventory_item_id(från cachade tabeller).
- Vi analyserar, validerar och loggar begäran i en lokal databas (
- Hämta Aktuell Lagerstatus
- Hämta befintliga lager nivåer via GraphQL (per plats & SKU).
- Beräkna Deltas
- Jämför ERP-lager vs. Shopify-lager för att bestämma
delta.
- Jämför ERP-lager vs. Shopify-lager för att bestämma
- Justera lager
- Skicka en enda GraphQL-mutation per batch (upp till 100 SKU:er).
- Responsshantering
- Logga framgångar/misslyckanden och skicka tillbaka uppdateringsstatus till ERP.
- Försök & Återställning
- Automatiserade cron-jobb försöker igen misslyckade batchar; återställning till REST om nödvändigt.
4. Hämta aktuell lagerstatus via GraphQL
Noggrann delta-beräkning börjar med att hämta befintliga kvantiteter. Vi grupperar upp till 60 artiklar per fråga:
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
}
Vår PHP-metod samlar dessa i en array:
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. Justera lager via GraphQL
När vi vet den aktuella lagret förbereder vi delta uppdateringspayloaden:
Mutationmall
mutation AdjustMultipleInventoryQuantities($input: InventoryAdjustQuantitiesInput!) {
inventoryAdjustQuantities(input: $input) {
inventoryAdjustmentGroup {
createdAt
changes { name delta }
}
userErrors { field message }
}
}
PHP Variabler Format
$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);
Detta enda samtal uppdaterar upp till 100 SKU:er på en gång, vilket avsevärt minskar nätverkskommunikationen.
6. Optimeringshöjdpunkter
- Batching & Chunking: 60 objekt/förfrågan för läsningar; 100 objekt/mutation för skrivningar.
- Lokalt Caching: Lagra
inventory_item_idochlocation_idi MySQL för att undvika upprepade sökningar. - Delta Logic: Uppdatera endast SKU:er vars nuvarande lager skiljer sig från ERP-lager.
- Medvetenhet om hastighetsbegränsning: Infoga
sleep()/usleep()strategiskt och återgå till REST för brådskande omförsök. - Robust Logging: Varje begäran och svar loggas i
api_request_logochstock_update_logtabeller.
7. Prestandajämförelse
| Metrisk | REST API | GraphQL API |
|---|---|---|
| Batchuppdateringsstöd | ||
| Genomsnittlig tid per 100 SKU:er | ~60 s | ~5 s |
| Rate‑limit fel (under belastning) | Frekvent | Sällsynt |
| Realtidsnoggrannhet | Måttlig | Hög |
| ERP feedbackintegration | Delvis | Full, inloggad |
8. Tekniker & Verktyg
- Shopify GraphQL Admin API
- PHP (StockController) med
ShopifyService,LogManager,DBOps,ApiService - MySQL för lokal caching och loggar
- INNSOF ERP webhooks
- Cron-jobbar för omförsök och ERP-återkopplingar
9. Fördelar för Wellcare & Raf Pharmacy
Realtidsaktualitet för aktier över 100+ butiker och kanaler
Inga översäljningar och sömlös kundupplevelse
Hög genomströmning: tusentals SKU-uppdateringar per timme
Detaljerad revisionsspår för efterlevnad och felsökning
Förbättrad SEO & UX på webb- och mobilbutiker
10. Vanliga frågor
- Varför hämta aktuell lagerstatus innan uppdatering?
Det säkerställer att vi beräknar rätt delta, vilket förhindrar oavsiktliga överskrivningar eller dubbla justeringar. - Hur många SKU:er kan GraphQL hantera i en batch?
Upp till 100 SKU:er per mutation och 60 per fråga, konfigurerbart baserat på butikens plan. - Kan jag blanda REST och GraphQL?
Ja. Vi behåller REST som en fallback för kritiska uppdateringar när GraphQL begränsar. - Fungerar lager på flera platser?
Absolut. Vi frågar och uppdaterar nivåer per plats med hjälp avlocationId. - Är denna metod anpassningsbar till andra ERP-system?
Ja. Vår modulära design kan integreras med Odoo, SAP, Oracle 6i och mer.
Varför Välja Seamedia E‑commerce Solutions?
På Seamedia kombinerar vi djup Shopify-expertis med robust ERP-integrationskunskap för att leverera skräddarsydda, högpresterande lösningar som ger verkliga affärsresultat. Vårt team – lett av erfarna konsulter som Prajosh VM – förstår komplexiteten i flerplatslager, hög SKU-volym och omnichannel-handel. Vi utformar skalbara, API-drivna arbetsflöden som håller ditt lager exakt, dina kunder nöjda och dina operationer i gång. Oavsett om du är en snabbt växande apotekskedja, en nationell återförsäljare eller en företagsproducent, erbjuder Seamedia end-to-end utveckling, sömlös ERP-anslutning och support dygnet runt.
Redo att effektivisera din lagerhantering och turbo-ladda din försäljning?
Kontakta oss idag på hello@seamedia.in eller besök www.seamedia.in för att diskutera hur vi kan bygga en skräddarsydd lösning för realtidslager-synkronisering för ditt företag.