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:er100+ fysiska butiker, och aktiva försäljningar över Shopify-webbbutikermobilappar, 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

  • 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 inventoryAdjustQuantities mutation
  • 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

  1. ERP → Middleware
    • INNSOF ERP skickar en JSON-payload via HTTP POST till vår StockController.
  2. Berikning & Loggning
    • Vi analyserar, validerar och loggar begäran i en lokal databas (api_request_log).
    • Vi berikar varje SKU med location_id och inventory_item_id (från cachade tabeller).
  3. Hämta Aktuell Lagerstatus
    • Hämta befintliga lager nivåer via GraphQL (per plats & SKU).
  4. Beräkna Deltas
    • Jämför ERP-lager vs. Shopify-lager för att bestämma delta.
  5. Justera lager
    • Skicka en enda GraphQL-mutation per batch (upp till 100 SKU:er).
  6. Responsshantering
    • Logga framgångar/misslyckanden och skicka tillbaka uppdateringsstatus till ERP.
  7. 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_id och location_id i 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_log och stock_update_log tabeller.

7. Prestandajämförelse

MetriskREST APIGraphQL API
Batchuppdateringsstöd❌✅
Genomsnittlig tid per 100 SKU:er~60 s~5 s
Rate‑limit fel (under belastning)FrekventSällsynt
RealtidsnoggrannhetMåttligHög
ERP feedbackintegrationDelvisFull, inloggad

8. Tekniker & Verktyg

  • Shopify GraphQL Admin API
  • PHP (StockController) med ShopifyServiceLogManagerDBOpsApiService
  • 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

  1. 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.
  2. 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.
  3. Kan jag blanda REST och GraphQL?
    Ja. Vi behåller REST som en fallback för kritiska uppdateringar när GraphQL begränsar.
  4. Fungerar lager på flera platser?
    Absolut. Vi frågar och uppdaterar nivåer per plats med hjälp av locationId.
  5. Ä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.