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
| Functietype | Wat het doet |
|---|---|
product_discounts | Korting op specifieke producten of varianten |
order_discounts | Korting op het ordertotaal |
shipping_discounts | Korting op verzendkosten |
delivery_customization | Leveringsopties verbergen, hernoemen of sorteren |
payment_customization | Betaalmethoden verbergen of sorteren |
cart_transform | Cart-items samenvoegen, opdelen of bundelen |
fulfillment_constraints | Fulfillment-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:
# 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:
{
"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
// 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
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
# 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.
// 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 betekentnull 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:- Shopify Checkout Extensibility — de bredere checkout-uitbreiding
- Shopify metafields en metaobjects — configuratiedata voor je functions
- Shopify API rate limits — betrouwbare integraties bouwen
Meer weten over onze Shopify-diensten of neem contact op voor een vrijblijvend gesprek.

Geschreven door Ruthger Idema
15+ jaar ervaring in e-commerce development. Gespecialiseerd in Magento, Shopify en Laravel maatwerk.
Meer over ons team →