Shopify Functions — server-side logica zonder apps
Terug naar blog

Shopify Functions — server-side logica zonder apps

AuthorRuthger Idema
13 april 202610 min leestijd

Kortingsregels die geen bestaande app dekt. Leveringsopties op basis van postcode. Betaalmethoden die afhangen van klantgroep. Shopify Functions laat je dit bouwen in je eigen code, uitgevoerd op Shopify's infra.

Shopify Functions — server-side logica zonder apps

Kortingslogica die geen enkele app biedt. Leveringsregels op basis van postcode, ordertotaal en klantsegment tegelijk. Betaalmethoden die verdwijnen voor bepaalde productcombinaties. Dit zijn use cases die jarenlang alleen mogelijk waren met een custom checkout of Shopify Plus scripts.

Shopify Functions bestaat sinds 2023 als stabiele API. Het laat je server-side logica uitvoeren in de Shopify-infra, als onderdeel van een custom app. Geen externe server. Geen latency-overhead. Uitgevoerd in WebAssembly.

Wat je leert in dit artikel

  • Wat Shopify Functions zijn en hoe ze technisch werken
  • Welke functietypes beschikbaar zijn
  • Hoe je een discount function bouwt in JavaScript
  • Wat de beperkingen zijn en hoe je ze omzeilt
  • Wanneer Functions de verkeerde oplossing zijn

Hoe Shopify Functions werken

Een Shopify Function is een stuk code dat draait op Shopify's edge-infrastructuur op het moment dat een specifieke gebeurtenis plaatsvindt — bijv. het berekenen van kortingen, het filteren van leveringsopties of het verbergen van betaalmethoden.

De code wordt gecompileerd naar WebAssembly (Wasm). Shopify voert het uit in een sandbox met strenge limieten:

  • Maximale uitvoertijd: 5 milliseconden
  • Maximaal geheugen: 10 MB
  • Geen netwerkverzoeken vanuit de function zelf
  • Input via JSON — Shopify stuurt de cart-state als input
  • Output via JSON — jouw function retourneert operaties

Het Wasm-model is de reden waarom Functions zo snel zijn. Ze voegen geen perceptibele latency toe aan de checkout.

Checkout request
       ↓
Shopify checkout engine
       ↓
Function input (JSON: cart, klant, producten)
       ↓
Jouw Wasm binary (< 5ms)
       ↓
Function output (JSON: operaties)
       ↓
Shopify past output toe op checkout

Beschikbare functietypes

FunctietypeWat het doet
product_discountsKorting op specifieke producten of varianten
order_discountsKorting op het ordertotaal
shipping_discountsKorting op verzendkosten
delivery_customizationLeveringsopties verbergen, hernoemen of sorteren
payment_customizationBetaalmethoden verbergen of sorteren
cart_transformCart-items samenvoegen, opdelen of bundelen
fulfillment_constraintsFulfillment-locaties toewijzen op basis van regels

Elke functietype heeft een eigen input/output-schema. Shopify publiceert de schemas in de documentatie.

Discount function bouwen: stap voor stap

We bouwen een kortingsfunctie die 15% geeft op alle producten in collectie b2b-bulk als de klant minimaal 10 stuks bestelt.

Stap 1: App opzetten

Functions leven in een custom app. Gebruik de Shopify CLI:

bash
# Nieuwe app aanmaken
npm init @shopify/app@latest mijn-kortingen-app

cd mijn-kortingen-app

# Function toevoegen
shopify app generate extension --template product_discounts --name bulk-korting

Dit genereert de structuur:

extensions/
  bulk-korting/
    src/
      index.js          # Function logica
    shopify.extension.toml  # Configuratie

Stap 2: Input begrijpen

Shopify stuurt de function-input als JSON. Voor product_discounts ziet dat er zo uit:

json
{
  "cart": {
    "lines": [
      {
        "id": "gid://shopify/CartLine/1",
        "quantity": 12,
        "merchandise": {
          "id": "gid://shopify/ProductVariant/123",
          "product": {
            "id": "gid://shopify/Product/456",
            "inAnyCollection": true,
            "collections": {
              "nodes": [
                { "id": "gid://shopify/Collection/789" }
              ]
            }
          }
        }
      }
    ]
  },
  "discountNode": {
    "metafield": {
      "value": "{\"collectie_id\": \"gid://shopify/Collection/789\", \"min_quantity\": 10, \"percentage\": 15}"
    }
  }
}

De configuratie (collectie-ID, minimale hoeveelheid, percentage) sla je op in een metafield op de discount-node. Zo is de function generiek en configureer je de parameters in de Admin UI.

Stap 3: Function schrijven

javascript
// extensions/bulk-korting/src/index.js

// Shopify stuurt de input als JSON via stdin
const input = JSON.parse(read_all_stdin());

// Configuratie uit metafield lezen
const config = JSON.parse(
  input.discountNode?.metafield?.value ?? '{}'
);

const {
  collectie_id: doelCollectieId,
  min_quantity: minHoeveelheid = 10,
  percentage = 15,
} = config;

// Verwerk elke cart line
const targets = [];

for (const line of input.cart.lines) {
  const product = line.merchandise?.product;
  if (!product) continue;

  // Controleer of product in de doelcollectie zit
  const inDoelCollectie = product.collections?.nodes?.some(
    (col) => col.id === doelCollectieId
  );

  if (!inDoelCollectie) continue;

  // Controleer minimale hoeveelheid
  if (line.quantity < minHoeveelheid) continue;

  // Voeg toe als korting-target
  targets.push({
    productVariant: { id: line.merchandise.id },
  });
}

// Output samenstellen
const output = {
  discounts: targets.length > 0
    ? [
        {
          targets,
          value: {
            percentage: { value: String(percentage) },
          },
          message: `Bulkkorting ${percentage}%`,
        },
      ]
    : [],
  discountApplicationStrategy: 'FIRST',
};

// Output schrijven naar stdout
write_all_stdout(JSON.stringify(output));

Stap 4: shopify.extension.toml configureren

toml
api_version = "2024-01"

[[extensions]]
type = "function"
name = "Bulk korting op collectie"
handle = "bulk-korting"
description = "Geeft percentage korting bij minimale hoeveelheid in collectie"

[extensions.build]
command = "npm run build"
path = "dist/index.wasm"

[[extensions.ui.paths]]
page = "/"

[extensions.input]
[extensions.input.variables]
query = """
query RunInput($collectie_id: ID!) {
  cart {
    lines {
      id
      quantity
      merchandise {
        ... on ProductVariant {
          id
          product {
            id
            collections(first: 10) {
              nodes {
                id
              }
            }
          }
        }
      }
    }
  }
  discountNode {
    metafield(namespace: "bulk_korting", key: "config") {
      value
    }
  }
}
"""

De GraphQL-query in input.variables bepaalt welke data Shopify naar je function stuurt. Vraag alleen op wat je nodig hebt — de 5ms tijdslimiet begint pas als de function output terugstuurt, maar kleinere input maakt de function wel makkelijker te lezen.

Stap 5: deployen en activeren

bash
# Deployen naar Shopify
shopify app deploy

# Of in development
shopify app dev

Na deployment activeer je de function via Shopify Admin → Discounts → Manage → Add discount. De function verschijnt als beschikbaar kortingstype.

Delivery customization: leveringsopties filteren

Een veelgevraagde use case: verberg "Ophalen in winkel" als het ordertotaal onder de €50 is.

javascript
// extensions/levering-filter/src/index.js
const input = JSON.parse(read_all_stdin());

const cartTotaal = parseFloat(
  input.cart.cost.totalAmount.amount
);

const minimumVoorOphalen = 50.0;

// Bouw de operations array op
const operations = input.deliveryGroups.flatMap((groep) =>
  groep.deliveryOptions.map((optie) => {
    const isOphalen = optie.handle?.includes('pickup');

    // Verberg ophaaloptie onder minimumdrempel
    if (isOphalen && cartTotaal < minimumVoorOphalen) {
      return {
        hide: { deliveryOptionHandle: optie.handle },
      };
    }

    // Overige opties ongewijzigd laten
    return {
      rename: {
        deliveryOptionHandle: optie.handle,
        title: optie.title,
      },
    };
  })
);

write_all_stdout(JSON.stringify({ operations }));

Beperkingen om te kennen

Geen netwerkverzoeken. Je function kan geen externe API aanroepen. Data die je nodig hebt, moet je meesturen via metafields of via de input-query. Dit is een bewuste keuze voor performance — externe calls zijn onbetrouwbaar binnen 5ms. 5 milliseconden uitvoertijd. Dit is extreem weinig. Geen zware berekeningen, geen loops over duizenden items. Shopify geeft een timeout-error als je overschrijdt. Beperkte input-data. Je haalt alleen op wat je expliciet opvraagt via de GraphQL-query in de TOML. Vergeten een veld te querien betekent null in je function. Alleen Shopify Plus voor sommige types. Payment customization en fulfillment constraints vereisen Shopify Plus. Discount- en delivery-functions werken op alle abonnementen. Geen directe Admin UI feedback. Functions loggen niet naar een dashboard. Debugging doe je via Shopify's dev-tool of door edge-cases te schrijven als unit tests.

Wanneer Functions de verkeerde oplossing zijn

Functions zijn niet de juiste keuze als:

  • Je real-time data nodig hebt van een externe bron (voorraadfeed, klantsegment uit je CRM)
  • Je complexe berekeningen uitvoert die meer dan 5ms kosten
  • Je de logica wilt aanpassen zonder een app-deployment

In die gevallen is een combinatie van Functions en metafields (voor gecachte externe data) of een custom checkout-extensie de betere aanpak.

Conclusie

Shopify Functions geven je server-side logica zonder een externe server. De tijdslimiet en het ontbreken van netwerkverzoeken zijn echte beperkingen, maar voor kortingslogica, leveringsfiltering en betaalmethode-aanpassingen zijn ze de standaardaanpak geworden.

De investering is een custom app-setup en een paar uur ontwikkelwerk. De opbrengst is een kortingssysteem dat geen app-abonnement vereist en geen externe latency toevoegt aan je checkout.

Shopify Functions worden gecompileerd naar WebAssembly voor maximale performance. Bekijk de Shopify Functions API-documentatie voor de volledige referentie.

Gerelateerde artikelen:

Meer weten over onze Shopify-diensten of neem contact op voor een vrijblijvend gesprek.

Ruthger Idema

Geschreven door Ruthger Idema

15+ jaar ervaring in e-commerce development. Gespecialiseerd in Magento, Shopify en Laravel maatwerk.

Meer over ons team →
Deel dit artikel:

Wil je jouw e-commerce naar het volgende niveau?

Plan een vrijblijvend gesprek met onze experts over Magento, Shopify of Laravel maatwerk.

Plan een Tech Check