Het nauwkeurig en up-to-date houden van de voorraad is van groot belang voor elke retailer met een hoog volume. Voor Wellcare en Raf Pharmacy—twee toonaangevende apotheekketens in Qatar met meer dan 10.000 SKU's100+ fysieke winkels, en actieve verkopen via Shopify-webwinkelsmobiele apps, en POS-systemen—hebben we een robuuste, real-time ERP-naar-Shopify voorraadupdateoplossing gebouwd. Hieronder delen we onze end-to-end architectuur, codefragmenten en prestatie-resultaten.

Projectomvang & Uitdagingen

  • Klanten: Wellcare Pharmacy en Raf Pharmacy, Qatar
  • Catalogusgrootte: 10.000+ SKU's
  • Verkoopkanalen: Shopify-winkel, headless mobiele apps, 100+ fysieke locaties
  • ERP: INNSOF ERP voor het doorvoeren van voorraadupdates
  • Vereisten:
    • Realtime synchronisatie om oververkoop te voorkomen
    • Schaling voor hoge updatevolumes
    • Minimale API-latentie en fouten
    • Nauwkeurige voorraadafhandeling op meerdere locaties

1. Initiële Benadering: Shopify REST API

We gebruikten eerst Shopify's REST Admin API-eindpunt /admin/api/2024‑01/inventory_levels/set.json om voorraadupdates door te voeren.

// 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 Beperkingen

  • Geen batchupdates: Één SKU per verzoek
  • Strikte snelheidslimieten: ~2 oproepen/sec per winkel → knelpunt voor duizenden SKU's
  • Hoge latentie: 50–100 ms per verzoek, accumulerende vertragingen
  • Foutgevoelig: Frequent rate-limit fouten onder belasting

2. Migreren naar de Shopify GraphQL API

Om de beperkingen van REST te overwinnen, zijn we overgestapt op Shopify’s GraphQL Admin API, waarmee we het volgende ontgrendelden:

  • Batchupdates met inventoryAdjustQuantities mutation
  • Kosten-gebaseerde throttling (flexibeler dan REST)
  • Lagere netwerkbelasting door alleen de benodigde velden op te vragen
  • Delta-gebaseerde aanpassingen (alleen bijwerken wanneer de voorraad daadwerkelijk verandert)

3. Architectuuroverzicht

  1. ERP → Middleware
    • INNSOF ERP verzendt een JSON-payload via HTTP POST naar onze StockController.
  2. Verrijking & Logging
    • We parseren, valideren en loggen de aanvraag in een lokale DB (api_request_log).
    • We verrijken elke SKU met location_id en inventory_item_id (uit gecachte tabellen).
  3. Huidige Voorraad Ophalen
    • Haal bestaande voorraadniveaus op via GraphQL (per locatie & SKU).
  4. Bereken Deltas
    • Vergelijk ERP-aandelen met Shopify-aandelen om delta te bepalen.
  5. Voorraad Aanpassen
    • Stuur een enkele GraphQL-mutatie per batch (tot 100 SKU's).
  6. Reactieafhandeling
    • Log successen/fouten en duw de update-status terug naar ERP.
  7. Herhalingen & Terugval
    • Geautomatiseerde cron-taken proberen mislukte batches opnieuw; terugval naar REST indien nodig.

4. Huidige Aandelen Ophalen via GraphQL

Nauwkeurige delta-berekening begint met het ophalen van bestaande hoeveelheden. We batchen tot 60 items per query:

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
}

Onze PHP-methode verzamelt deze in een 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. Voorraad aanpassen via GraphQL

Zodra we de huidige voorraad kennen, bereiden we de delta update payload voor:

Mutatie Sjabloon

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

PHP Variabelen Formaat

$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);

Deze enkele oproep werkt tot 100 SKU's tegelijk bij, waardoor het netwerkverkeer aanzienlijk wordt verminderd.

6. Optimalisatie Hoogtepunten

  • Batching & Chunking: 60 items/query voor lezen; 100 items/mutatie voor schrijven.
  • Lokale Caching: Bewaar inventory_item_id & location_id in MySQL om repetitieve opzoekingen te vermijden.
  • Delta Logic: Werk alleen SKU's bij waarvan de huidige voorraad verschilt van de ERP-voorraad.
  • Bewustzijn van rate-limiting: Plaats sleep()/usleep() strategisch en val terug op REST voor dringende herhalingen.
  • Robuuste Logging: Elke aanvraag en reactie wordt gelogd in de api_request_log en stock_update_log tabellen.

7. Prestatievergelijking

MetrischREST APIGraphQL API
Batch-update ondersteuning❌✅
Gemiddelde tijd per 100 SKU's~60 s~5 s
Rate-limietfouten (onder belasting)FrequentZeldzaam
Realtime nauwkeurigheidGemiddeldHoog
ERP feedbackintegratieDeelmatigVolledig, ingelogd

8. Technologieën & Hulpmiddelen

  • Shopify GraphQL Admin API
  • PHP (StockController) met ShopifyServiceLogManagerDBOpsApiService
  • MySQL voor lokale caching en logs
  • INNSOF ERP webhooks
  • Cron Jobs voor herhalingen en ERP terugroepen

9. Voordelen voor Wellcare & Raf Pharmacy

  • 🔄 Realtime voorraadnauwkeurigheid over 100+ winkels en kanalen
  • 🚫 Geen overselling en naadloze klantervaring
  • ⚡ Hoge doorvoer: duizenden SKU-updates per uur
  • 🔍 Gedetailleerde audit trail voor naleving en foutopsporing
  • 📈 Verbeterde SEO & UX op web- en mobiele winkels

10. Veelgestelde vragen

  1. Waarom de huidige voorraad ophalen voordat je bijwerkt?
    Zorgt ervoor dat we de juiste delta berekenen, waardoor onbedoelde overschrijvingen of dubbele aanpassingen worden voorkomen.
  2. Hoeveel SKU's kan GraphQL in een batch verwerken?
    Tot 100 SKU's per mutatie en 60 per query, configureerbaar op basis van het winkelplan.
  3. Kan ik REST en GraphQL combineren?
    Ja. We houden REST als een back-up voor kritieke updates wanneer GraphQL wordt beperkt.
  4. Werkt voorraad op meerdere locaties?
    Absoluut. We vragen per-locatie niveaus op en werken deze bij met locationId.
  5. Is deze aanpak aanpasbaar aan andere ERP's?
    Ja. Ons modulaire ontwerp kan integreren met Odoo, SAP, Oracle 6i, en meer.

Waarom kiezen voor Seamedia E‑commerce Oplossingen?
Bij Seamedia combineren we diepgaande Shopify-expertise met robuuste ERP-integratiekennis om op maat gemaakte, hoogpresterende oplossingen te leveren die echte bedrijfsresultaten opleveren. Ons team—geleid door ervaren consultants zoals Prajosh VM—begrijpt de complexiteit van multi-locatie voorraad, hoge SKU-volumes en omnichannel retail. We ontwerpen schaalbare, API-gestuurde workflows die uw voorraad nauwkeurig houden, uw klanten tevreden en uw operaties soepel laten verlopen. Of u nu een snelgroeiende apotheekketen, een nationale retailer of een ondernemingsfabrikant bent, Seamedia biedt end-to-end ontwikkeling, naadloze ERP-connectiviteit en 24/7 ondersteuning.

Klaar om uw voorraad te stroomlijnen en uw verkoop een boost te geven?
Neem vandaag nog contact met ons op via hello@seamedia.in of bezoek www.seamedia.in om te bespreken hoe we een op maat gemaakte real-time voorraad synchronisatieoplossing voor uw bedrijf kunnen bouwen.