Att hålla lagret korrekt och uppdaterat är av yttersta vikt för alla återförsäljare med hög volym. För Wellcare och Raf Pharmacy – två ledande apotekskedjor i Qatar med över 10 000 SKU:er , 100+ fysiska butiker och aktiv försäljning i Shopifys webbutiker , mobilappar och kassasystem – byggde vi en robust ERP-till-Shopify-lösning för lageruppdatering i realtid. Nedan delar vi vår heltäckande arkitektur, kodavsnitt och prestandaresultat.
- Projektets omfattning och utmaningar
- 1. Inledande tillvägagångssätt: Shopify REST API
- 2. Migrera till Shopify GraphQL API
- 3. Arkitekturöversikt
- 4. Hämta aktuellt lager via GraphQL
- 5. Justera lager via GraphQL
- 6. Optimeringshöjdpunkter
- 7. Prestandajämförelse
- 8. Tekniker och verktyg
- 9. Fördelar för Wellcare & Raf Pharmacy
- 10. Vanliga frågor
Projektets omfattning och utmaningar
- kunder: Wellcare Apotek och Raf Apotek, Qatar
- Katalogstorlek: 10,000+ SKU:er
- Försäljningskanaler: Shopify-butik, headless mobilappar, 100+ fysiska platser
- ERP: INNSOF ERP skickar aktieuppdateringar
- Krav:
- Realtidssynkronisering för att förhindra överförsäljning
- Skalbar för hög uppdateringsvolym
- Minimal API-latens och fel
- Noggrann lagerhantering på flera platser
1. Inledande tillvägagångssätt: Shopify REST API
Vi använde först Shopifys REST Admin API-slutpunkt /admin/api/2024‑01/inventory_levels/set.json för att publicera aktieuppdateringar.
// 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 gränser för avgift: ~2 samtal/sek per butik → flaskhals för tusentals SKU:er
- Hög latens: 50–100 ms per begäran, ackumulerade fördröjningar
- Felbenägen: Ofta förekommande hastighetsgränsfel under belastning
2. Migrera till Shopify GraphQL API
För att övervinna REST-begränsningarna bytte vi till Shopifys GraphQL Admin API , vilket låste upp:
- Batchuppdateringar med
inventoryAdjustQuantitiesmutation - Kostnadsbaserad strypning (mer flexibel än REST)
- Lägre nätverkskostnader genom att endast begära nödvändiga fält
- Deltabaserade justeringar (uppdateras endast när lagret faktiskt ändras)
3. Arkitekturöversikt
- ERP → Mellanprogramvara
- INNSOF ERP skickar en JSON-nyttolast via HTTP POST till vår
StockController.
- INNSOF ERP skickar en JSON-nyttolast via HTTP POST till vår
- Anrikning och avverkning
- 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 (
- Få aktuellt lager
- Hämta befintliga lagernivåer via GraphQL (per plats och SKU).
- Beräkningsdelta
- Jämför ERP-lager med Shopify-lager för att avgöra
delta.
- Jämför ERP-lager med Shopify-lager för att avgöra
- Justera lagret
- Skicka en enda GraphQL-mutation per batch (upp till 100 SKU:er).
- Svarshantering
- Logga framgångar/misslyckanden och skicka uppdateringsstatus tillbaka till ERP.
- Återförsök och reserv
- Automatiserade cron-jobb försöker om misslyckade batchar; återgå till REST om det behövs.
4. Hämta aktuellt lager via GraphQL
Noggrann deltaberäkning börjar med att hämta befintliga kvantiteter. Vi batchar 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 det aktuella lagret förbereder vi deltauppdateringens nyttolast:
Mutationsmall
mutation AdjustMultipleInventoryQuantities($input: InventoryAdjustQuantitiesInput!) {
inventoryAdjustQuantities(input: $input) {
inventoryAdjustmentGroup {
createdAt
changes { name delta }
}
userErrors { field message }
}
}
PHP-variablerformat
$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);
Det här enda anropet uppdaterar upp till 100 SKU: er samtidigt, vilket minskar nätverksstörningar avsevärt.
6. Optimeringshöjdpunkter
- Batching och Chunking: 60 objekt/fråga för läsningar; 100 objekt/mutation för skrivningar.
- Lokal cachelagring: HITTA BUTIK
inventory_item_id&location_idi MySQL för att undvika upprepade sökningar. - Deltalogik: Uppdatera endast SKU:er vars nuvarande lager skiljer sig från ERP-lagret.
- Medvetenhet om hastighetsgränser: Insert
sleep()/usleep()strategiskt och reserv till REST för brådskande återförsök. - Robust loggning: Varje förfrågan och svar loggas
api_request_logochstock_update_logtabeller.
7. Prestandajämförelse
| metrisk | REST API | GraphQL API |
|---|---|---|
| Stöd för batchuppdateringar | ❌ | ✅ |
| Genomsnittlig tid per 100 SKU:er | ~60 sekunder | ~5 sekunder |
| Hastighetsgränsfel (under belastning) | Frekvent | Sällsynta |
| Noggrannhet i realtid | Moderate | Hög |
| ERP-feedbackintegration | Partiell | Fullständig, inloggad |
8. Tekniker och verktyg
- Shopify GraphQL Admin API
- PHP (Aktiekontroller) med
ShopifyService,LogManager,DBOps,ApiService - MySQL för lokal cachning och loggar
- INNSOF ERP webhooks
- cron jobb för återförsök och ERP-återanrop
9. Fördelar för Wellcare & Raf Pharmacy
- 🔄 Lagernoggrannhet i realtid i över 100 butiker och kanaler
- ???? Noll överförsäljning och sömlös kundupplevelse
- ⚡ hög genomströmningtusentals SKU-uppdateringar per timme
- 🔍 Detaljerad revisionslogg för efterlevnad och felsökning
- 📈 Förbättrad SEO och UX på webb- och mobila butiker
10. Vanliga frågor
- Varför hämta aktuellt lager innan man uppdaterar?
Säkerställer att vi beräknar korrekt 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å butiksplan. - Kan jag blanda REST och GraphQL?
Ja. Vi behåller REST som reserv för kritiska uppdateringar när GraphQL begränsas. - Fungerar lagerhantering på flera platser?
Absolut. Vi frågar efter och uppdaterar nivåer per plats med hjälp avlocationId. - Är den här metoden anpassningsbar till andra ERP-system?
Ja. Vår modulära design kan integreras med Odoo, SAP, Oracle 6i och fler.
Varför välja Seamedias e-handelslösningar?
På Seamedia kombinerar vi djupgående Shopify-expertis med robust kunskap om ERP-integration för att leverera skräddarsydda, högpresterande lösningar som driver verkliga affärsresultat. Vårt team – lett av erfarna konsulter som Prajosh VM—förstår komplexiteten i lagerhantering på flera platser, höga SKU-volymer och omnikanalig detaljhandel. Vi utformar skalbara, API-drivna arbetsflöden som håller ditt lager korrekt, dina kunder nöjda och din verksamhet igång. Oavsett om du är en snabbväxande apotekskedja, en nationell återförsäljare eller en storföretagstillverkare, erbjuder Seamedia heltäckande utveckling, sömlös ERP-anslutning och support dygnet runt.
Redo att effektivisera ditt lager och öka 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 anpassad lösning för realtidssynkronisering av aktier för ditt företag.