So migrieren Sie Shopify Scripts zu Functions: Das vollständige Code-Tutorial (Ausgabe 2026)
So migrieren Sie Shopify Scripts zu Functions: Das vollständige Code-Tutorial (Ausgabe 2026)
So migrieren Sie Shopify Scripts zu Functions: Das vollständige Code-Tutorial (Ausgabe 2026)

Es ist der 16. April 2026. Gestern — der 15. April — war der Tag, an dem Shopify den Script Editor endgültig gesperrt hat. Du kannst keinen neuen Script mehr erstellen oder veröffentlichen. Die Abschaltung der Ausführung erfolgt in 75 Tagen, am 30. Juni 2026.
Wenn du Shopify-Plus-Entwickler bist — oder die Agentur, die einen Plus-Store betreut — und diese Migration in den letzten zwölf Monaten immer wieder auf den „nächsten Sprint“ verschoben hast, hast du ein Problem. Kein „wäre nett zu beheben“-Problem. Ein „dein Checkout bricht am 1. Juli um Mitternacht zusammen“-Problem. Die meisten Plus-Stores haben über die Jahre 5 bis 20 Scripts angesammelt, die unauffällig eine Rabattregel, das Ausblenden von Versandarten oder eine Zahlungsblockade antreiben, an die sich niemand mehr erinnert.
Dieser Leitfaden ist das technische Migrationshandbuch, das wir uns im Januar gewünscht hätten. Er behandelt den tatsächlichen Code — nicht nur die Strategie. Wenn du fertig gelesen hast, weißt du, wie du mit der Shopify CLI eine Function scaffoldest, die Rust- oder JavaScript-Logik für Rabatte, Lieferanpassungen und Zahlungsanpassungen schreibst, sie sicher gegen eine markierte Teilmenge deiner Kunden testest und sie ohne Beeinträchtigung deines bestehenden Checkouts in die Produktion bringst.
Lass uns die Scripts aus deinem Shop entfernen und die Functions darin aktivieren.

Kurzantwort: Scripts → Functions in 60 Sekunden
Die Migration in einem Absatz: Shopify Scripts (Ruby-Code im Script Editor, nur Plus) werden durch Shopify Functions ersetzt (WebAssembly-Module, geschrieben in Rust oder JavaScript, für alle Pläne verfügbar). Du scaffoldest eine Function mit
shopify app generate extension, schreibst einerun.graphql-Abfrage, die die benötigten Warenkorbdaten lädt, schreibst einerun.rs- oderrun.js-Datei, die Operationen zurückgibt (Rabatte, ausgeblendete Versandarten usw.), stellst dann mitshopify app deploybereit und aktivierst sie über den Admin oder eine GraphQL-Mutation. Functions laufen als kompiliertes WASM mit Latenzen unter 5 ms, funktionieren in allen Plänen und sind der einzige Anpassungsweg, den Shopify künftig unterstützt.
Was sich am 30. Juni tatsächlich ändert
Bevor wir irgendeinen Code anfassen, klären wir die Daten. Es gibt zwei davon, und beide sind wichtig.
Datum | Was passiert | Deine Maßnahme |
|---|---|---|
15. April 2026 (vergangen) | Script Editor nur noch lesbar. Keine neuen Scripts. Keine Bearbeitung bestehender Scripts. | Bestehende Scripts laufen weiter. Migriere jetzt oder friere deine Logik ein. |
30. Juni 2026 | Alle Shopify Scripts hören auf zu laufen. Punkt. | Dein Function-Ersatz muss vor diesem Datum live sein. |
Die Migration ist binär. Entweder ist deine Function bis zum 30. Juni bereitgestellt und dein Checkout funktioniert weiter, oder sie ist es nicht — und jeder betroffene Warenkorb fällt unauffällig auf Standardpreise, Standardversandtarife und alle aktivierten Zahlungsmethoden zurück. Es gibt keine Teilpunkte. Der Script läuft entweder oder er läuft nicht, und nach dem 30. Juni läuft er nicht mehr.
Tipp: Öffne in deinem Shopify-Admin
Einstellungen → Checkout → Anpassungsbericht. Dort sind alle aktiven Scripts in deinem Shop aufgelistet, was sie tun und welcher Function-Typ als Ersatz empfohlen wird. Fang dort an.
Functions vs. Scripts: Was sich tatsächlich geändert hat
Dimension | Shopify Scripts (veraltet) | Shopify Functions (Ersatz) |
|---|---|---|
Sprache | Ruby DSL (Shopify-spezifisch) | Rust, JavaScript, TypeScript |
Runtime | Sandboxed Ruby auf Shopify-Infrastruktur | WebAssembly (WASM) — Ausführung unter 5 ms |
Plan-Verfügbarkeit | Nur Plus | Alle Pläne (Custom Apps erfordern Plus; Public Apps sind offen) |
Editor | Script Editor im Admin | Lokale IDE + Shopify CLI |
Versionierung | Keine — Live-Bearbeitungen | Git-freundlich — vollständige Versionskontrolle |
Testen | Manuell im Checkout | Lokale Entwicklung mit |
Bereitstellung | Im Admin auf „Save“ klicken |
|
Ziele | Positionen, Versand, Zahlungen | Rabatte, Cart Transform, Validation, Delivery Customization, Payment Customization, Order Routing, Fulfillment Constraints, mehr |
Der architektonische Wandel ist wichtig. Scripts waren „Ruby in einem Textfeld anpassen“. Functions sind „eine echte App schreiben, sie per Versionskontrolle verwalten, lokal testen und über eine echte CI-Pipeline bereitstellen“. Das ist eine steilere Lernkurve. Es ist auch die letzte Migration, die du in absehbarer Zeit für Checkout-Logik machen wirst — Functions sind Shopifys langfristige Zusage, nicht wie sich Scripts als Zwischenlösung herausgestellt haben.
Deine Scripts dem richtigen Function-Typ zuordnen
Jeder Script, den du heute hast, passt genau zu einer Function-API. Hier ist die Lookup-Tabelle, die du an deinen Monitor heften solltest.
Alter Script-Typ | Was er tat | Neue Function-API | Function-Ziel |
|---|---|---|---|
Line Item Script | Rabatte auf bestimmte Produkte / Kunden / Warenkorbbedingungen anwenden | Cart & Checkout Discounts API |
|
Shipping Script (Rabatt) | Kostenloser / vergünstigter Versand basierend auf Warenkorbregeln | Cart & Checkout Discounts API |
|
Shipping Script (ausblenden / umbenennen / neu sortieren) | Eine Versandart über $X ausblenden, „Standard“ in „Gratis ab 50 $“ umbenennen | Delivery Customization API |
|
Payment Script | PayPal für B2B ausblenden, Nachnahme über 500 $ ausblenden, Methoden neu sortieren | Payment Customization API |
|
Cart-modifying Script (selten) | Produkte bündeln, Positionen austauschen | Cart Transform API |
|
Checkout blockierender Script | Warenkorb ablehnen, wenn die SKU-Mischung ungültig ist | Cart & Checkout Validation API |
|
Wenn du zehn Scripts hast, wirst du wahrscheinlich drei bis fünf Functions bauen — mehrere Scripts lassen sich oft zu einer Function mit saubererer Verzweigungslogik zusammenfassen.

Voraussetzung: Richte deine lokale Entwicklungsumgebung ein
Bevor du irgendeine Function scaffoldest, brauchst du lokal drei Dinge installiert. Führe diese Prüfungen in deinem Terminal aus.
1. Node.js 18+
node --version # Must be >= 18.0.0
node --version # Must be >= 18.0.0
Falls älter, installiere es über nvm oder lade es von nodejs.org herunter.
2. Shopify CLI 3+
npm install -g @shopify/cli@latest shopify version # Should output 3.x or higher
npm install -g @shopify/cli@latest shopify version # Should output 3.x or higher
3. Rust-Toolchain (nur wenn du Functions in Rust schreiben wirst)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh rustup target add wasm32-wasip1 cargo --version
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh rustup target add wasm32-wasip1 cargo --version
JavaScript-Functions brauchen kein Rust. Wähle eine Sprache für dein Team und bleib dabei — beides zu mischen erhöht den Wartungsaufwand.
4. Ein Development Store
Melde dich entweder im Partner-Dashboard an und erstelle einen neuen Development Store oder verwende einen bestehenden. Du stellst Functions zuerst in diesem Store bereit, bevor du sie in die Produktion überführst.
Deine erste Function scaffolden
Die CLI erledigt den größten Teil des Boilerplates. In einem beliebigen Verzeichnis:
# Create a new Shopify app (skip if you already have one) shopify app init my-checkout-functions cd my-checkout-functions # Generate a Function extension shopify app generate extension
# Create a new Shopify app (skip if you already have one) shopify app init my-checkout-functions cd my-checkout-functions # Generate a Function extension shopify app generate extension
Die CLI führt dich durch die Eingaben. Für eine Discount-Function würdest du wählen:
Typ: Function
Vorlage:
discount(odercart_checkout_validation,delivery_customization,payment_customizationusw.)Sprache: Rust oder JavaScript
Name: etwas wie
volume-discount-fn
Dadurch wird extensions/volume-discount-fn/ mit Folgendem erstellt:
extensions/volume-discount-fn/ ├── shopify.extension.toml # Function config — targets, build, version ├── src/ │ ├── cart_lines_discounts_generate_run.graphql # Input query │ └── cart_lines_discounts_generate_run.rs # Function logic ├── Cargo.toml # Rust dependencies (Rust only) └── README.md
extensions/volume-discount-fn/ ├── shopify.extension.toml # Function config — targets, build, version ├── src/ │ ├── cart_lines_discounts_generate_run.graphql # Input query │ └── cart_lines_discounts_generate_run.rs # Function logic ├── Cargo.toml # Rust dependencies (Rust only) └── README.md
Die drei Dateien, die du ständig bearbeiten wirst, sind die .toml (Konfiguration), die .graphql (Input) und die .rs / .js (Logik). Das ist alles.
Tutorial 1: Einen Line Item Script ersetzen (Mengenrabatt)
Angenommen, dein alter Script gewährte 10 % Rabatt auf die Bestellsumme, wenn der Warenkorb 5+ Einheiten aus einer bestimmten Kollektion enthielt. Hier ist das entsprechende Function-Pendant.
Schritt 1.1: Die Konfiguration (shopify.extension.toml)
api_version = "2026-01" [[extensions]] name = "volume-discount-fn" handle = "volume-discount-fn" type = "function" [[extensions.targeting]] target = "cart.lines.discounts.generate.run" input_query = "src/cart_lines_discounts_generate_run.graphql" export = "cart_lines_discounts_generate_run" [extensions.build] command = "cargo build --target=wasm32-wasip1 --release" path = "target/wasm32-wasip1/release/volume-discount-fn.wasm" watch = ["src/**/*.rs"]
api_version = "2026-01" [[extensions]] name = "volume-discount-fn" handle = "volume-discount-fn" type = "function" [[extensions.targeting]] target = "cart.lines.discounts.generate.run" input_query = "src/cart_lines_discounts_generate_run.graphql" export = "cart_lines_discounts_generate_run" [extensions.build] command = "cargo build --target=wasm32-wasip1 --release" path = "target/wasm32-wasip1/release/volume-discount-fn.wasm" watch = ["src/**/*.rs"]
Schritt 1.2: Die Input-Abfrage (src/cart_lines_discounts_generate_run.graphql)
query Input { cart { lines { id quantity cost { subtotalAmount { amount } } merchandise { ... on ProductVariant { product { inAnyCollection(ids: ["gid://shopify/Collection/123456789"]) } } } } } discount { discountClasses } }
query Input { cart { lines { id quantity cost { subtotalAmount { amount } } merchandise { ... on ProductVariant { product { inAnyCollection(ids: ["gid://shopify/Collection/123456789"]) } } } } } discount { discountClasses } }
Tipp: Functions sehen nur die Daten, die du abfragst. Halte GraphQL minimal — jedes Feld, das du weglässt, bedeutet eine schnellere und günstigere Ausführung.
Schritt 1.3: Die Logik (src/cart_lines_discounts_generate_run.rs)
use super::schema; use shopify_function::prelude::*; use shopify_function::Result; #[shopify_function] fn cart_lines_discounts_generate_run( input: schema::cart_lines_discounts_generate_run::Input, ) -> Result<schema::CartLinesDiscountsGenerateRunResult> { // Bail if discount class doesn't match let has_order_discount = input .discount() .discount_classes() .contains(&schema::DiscountClass::Order); if !has_order_discount { return Ok(schema::CartLinesDiscountsGenerateRunResult { operations: vec![] }); } // Sum quantities of items in the target collection let qualifying_qty: i64 = input .cart() .lines() .iter() .filter(|line| { if let schema::Merchandise::ProductVariant(v) = line.merchandise() { *v.product().in_any_collection() } else { false } }) .map(|line| *line.quantity()) .sum(); if qualifying_qty < 5 { return Ok(schema::CartLinesDiscountsGenerateRunResult { operations: vec![] }); } // Apply 10% off the order subtotal Ok(schema::CartLinesDiscountsGenerateRunResult { operations: vec![schema::CartOperation::OrderDiscountsAdd( schema::OrderDiscountsAddOperation { selection_strategy: schema::OrderDiscountSelectionStrategy::First, candidates: vec![schema::OrderDiscountCandidate { targets: vec![schema::OrderDiscountCandidateTarget::OrderSubtotal( schema::OrderSubtotalTarget { excluded_cart_line_ids: vec![], }, )], message: Some("Volume discount: 10% off".to_string()), value: schema::OrderDiscountCandidateValue::Percentage( schema::Percentage { value: Decimal(10.0) } ), conditions: None, associated_discount_code: None, }], }, )], }) }
use super::schema; use shopify_function::prelude::*; use shopify_function::Result; #[shopify_function] fn cart_lines_discounts_generate_run( input: schema::cart_lines_discounts_generate_run::Input, ) -> Result<schema::CartLinesDiscountsGenerateRunResult> { // Bail if discount class doesn't match let has_order_discount = input .discount() .discount_classes() .contains(&schema::DiscountClass::Order); if !has_order_discount { return Ok(schema::CartLinesDiscountsGenerateRunResult { operations: vec![] }); } // Sum quantities of items in the target collection let qualifying_qty: i64 = input .cart() .lines() .iter() .filter(|line| { if let schema::Merchandise::ProductVariant(v) = line.merchandise() { *v.product().in_any_collection() } else { false } }) .map(|line| *line.quantity()) .sum(); if qualifying_qty < 5 { return Ok(schema::CartLinesDiscountsGenerateRunResult { operations: vec![] }); } // Apply 10% off the order subtotal Ok(schema::CartLinesDiscountsGenerateRunResult { operations: vec![schema::CartOperation::OrderDiscountsAdd( schema::OrderDiscountsAddOperation { selection_strategy: schema::OrderDiscountSelectionStrategy::First, candidates: vec![schema::OrderDiscountCandidate { targets: vec![schema::OrderDiscountCandidateTarget::OrderSubtotal( schema::OrderSubtotalTarget { excluded_cart_line_ids: vec![], }, )], message: Some("Volume discount: 10% off".to_string()), value: schema::OrderDiscountCandidateValue::Percentage( schema::Percentage { value: Decimal(10.0) } ), conditions: None, associated_discount_code: None, }], }, )], }) }
Schritt 1.4: Testen, bereitstellen, aktivieren
# Local development with hot reload shopify app dev # When ready, deploy shopify app deploy # In the GraphiQL panel that opens (press `g` in the dev terminal), # create the automatic discount that uses your Function:
# Local development with hot reload shopify app dev # When ready, deploy shopify app deploy # In the GraphiQL panel that opens (press `g` in the dev terminal), # create the automatic discount that uses your Function:
mutation { discountAutomaticAppCreate( automaticAppDiscount: { title: "Volume Discount (5+ collection items)" functionHandle: "volume-discount-fn" discountClasses: [ORDER] startsAt: "2026-04-16T00:00:00Z" } ) { automaticAppDiscount { discountId } userErrors { field message } } }
mutation { discountAutomaticAppCreate( automaticAppDiscount: { title: "Volume Discount (5+ collection items)" functionHandle: "volume-discount-fn" discountClasses: [ORDER] startsAt: "2026-04-16T00:00:00Z" } ) { automaticAppDiscount { discountId } userErrors { field message } } }
Das ist alles. Die Function ist live, versioniert und ersetzt den alten Script vollständig.
Tutorial 2: Einen Shipping Script ersetzen (Methode über Warenkorbgrenze ausblenden)
Ein häufiger Script: „Expressversand ausblenden, wenn der Warenkorbwert über 500 $ liegt, um teuren Overnight-Versand bei großen Bestellungen zu verhindern.“ Hier ist die Version als Delivery Customization Function.
Schritt 2.1: Scaffold
shopify app generate extension --template delivery_customization --name hide-express-fn
shopify app generate extension --template delivery_customization --name hide-express-fn
Schritt 2.2: Input-Abfrage (src/run.graphql)
query Input { cart { cost { subtotalAmount { amount } } deliveryGroups { deliveryOptions { handle title } } } }
query Input { cart { cost { subtotalAmount { amount } } deliveryGroups { deliveryOptions { handle title } } } }
Schritt 2.3: Logik (src/run.js — JavaScript-Variante)
// @ts-check /** * @typedef {import("../generated/api").RunInput} RunInput * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult */ const NO_CHANGES = { operations: [] }; const THRESHOLD = 500.0; const HIDE_TITLES = ["Express", "Overnight"]; /** * @param {RunInput} input * @returns {FunctionRunResult} */ export function run(input) { const subtotal = parseFloat(input.cart.cost.subtotalAmount.amount); if (subtotal < THRESHOLD) return NO_CHANGES; const operations = input.cart.deliveryGroups.flatMap((group) => group.deliveryOptions .filter((opt) => HIDE_TITLES.some((t) => opt.title.includes(t))) .map((opt) => ({ hide: { deliveryOptionHandle: opt.handle }, })) ); return { operations }; }
// @ts-check /** * @typedef {import("../generated/api").RunInput} RunInput * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult */ const NO_CHANGES = { operations: [] }; const THRESHOLD = 500.0; const HIDE_TITLES = ["Express", "Overnight"]; /** * @param {RunInput} input * @returns {FunctionRunResult} */ export function run(input) { const subtotal = parseFloat(input.cart.cost.subtotalAmount.amount); if (subtotal < THRESHOLD) return NO_CHANGES; const operations = input.cart.deliveryGroups.flatMap((group) => group.deliveryOptions .filter((opt) => HIDE_TITLES.some((t) => opt.title.includes(t))) .map((opt) => ({ hide: { deliveryOptionHandle: opt.handle }, })) ); return { operations }; }
Schritt 2.4: Über den Admin aktivieren (keine GraphQL erforderlich)
Delivery Customizations haben eine integrierte Admin-Oberfläche. Nach shopify app deploy:
Gehe zu Einstellungen → Versand und Lieferung
Scrolle im unteren Bereich zum Abschnitt Anpassungen
Klicke auf Anpassung hinzufügen → wähle deine Function aus
Speichern
Die Regel zum Ausblenden ist in der Produktion live. Keine Mutation erforderlich.

Tutorial 3: Einen Payment Script ersetzen (Nachnahme für B2B ausblenden)
Alter Script: „Nachnahme für jeden Kunden mit dem Tag 'B2B' ausblenden.“ Hier ist die Payment Customization-Version.
Schritt 3.1: Scaffold
shopify app generate extension --template payment_customization --name hide-cod-b2b-fn
shopify app generate extension --template payment_customization --name hide-cod-b2b-fn
Schritt 3.2: Input-Abfrage
query Input { cart { buyerIdentity { customer { hasTags(tags: [{ tag: "B2B" }]) { tag hasTag } } } } paymentMethods { id name } }
query Input { cart { buyerIdentity { customer { hasTags(tags: [{ tag: "B2B" }]) { tag hasTag } } } } paymentMethods { id name } }
Schritt 3.3: Logik (src/run.js)
const NO_CHANGES = { operations: [] }; export function run(input) { const tagCheck = input.cart?.buyerIdentity?.customer?.hasTags?.[0]; const isB2B = tagCheck?.hasTag === true; if (!isB2B) return NO_CHANGES; const codMethod = input.paymentMethods.find((pm) => pm.name.toLowerCase().includes("cash on delivery") ); if (!codMethod) return NO_CHANGES; return { operations: [{ hide: { paymentMethodId: codMethod.id } }], }; }
const NO_CHANGES = { operations: [] }; export function run(input) { const tagCheck = input.cart?.buyerIdentity?.customer?.hasTags?.[0]; const isB2B = tagCheck?.hasTag === true; if (!isB2B) return NO_CHANGES; const codMethod = input.paymentMethods.find((pm) => pm.name.toLowerCase().includes("cash on delivery") ); if (!codMethod) return NO_CHANGES; return { operations: [{ hide: { paymentMethodId: codMethod.id } }], }; }
Schritt 3.4: Aktivieren
Payment Customizations haben ebenfalls eine Admin-Oberfläche unter Einstellungen → Zahlungen → Anpassungen. Gleicher Ablauf wie bei Delivery — Function auswählen, speichern, fertig.
Da du das hier liest — ein Wort zu Post-Purchase
Eine kurze Offenlegung, weil dies der Revize-Blog ist. Revize kümmert sich um die Dinge, die Functions nicht anfassen können — sobald eine Bestellung aufgegeben wurde, wollen Kunden einen Artikel hinzufügen, eine Größe tauschen, die Lieferadresse korrigieren oder einen vergessenen Rabatt anwenden. Functions sitzen im Checkout. Revize sitzt danach. Functions entscheiden, was im Warenkorb erlaubt ist; Revize gibt deinen Kunden und dem Support-Team die Möglichkeit, die Bestellung danach zu bearbeiten, ohne einen Rückerstattungs-und-Neuerstellungs-Zyklus. Das ist für zwei Arten von Shops wichtig: diejenigen mit so viel Bestellvolumen, dass manuelle Bearbeitung zusammenbricht (offensichtlich Plus-Betreiber, aber auch stark ausgelastete Advanced-Stores), und diejenigen, deren gesamte Marke auf Kundenerlebnis basiert — wo eine „Tut uns leid, das können wir nicht ändern“-E-Mail Wiederkäufe verhindert.
Wenn dein Migrationsplan Scripts → Functions abdeckt, du aber Post-Purchase-Bestelländerungen nie sauber gelöst hast, wirst du in etwa drei Wochen an die nächste „Warum ist das so schwer?“-Wand stoßen. Der gerade veröffentlichte Leitfaden zur Bestellverwaltung beschreibt den vollständigen Post-Checkout-Plan.
Zurück zur Migration.
Teststrategie: Das Muster mit markierten Kunden
Functions haben keinen „Draft-Modus“, den du im Admin umschalten kannst. Das professionelle Muster ist, die neue Function über ein Kunden-Tag zu begrenzen, den alten Script und die neue Function parallel laufen zu lassen, zu prüfen, dass sie für markierte Nutzer identische Ergebnisse liefern, und dann den Schalter umzulegen.
Schritt 1: Deine Testnutzer taggen
Füge in Kunden das Tag FN-TESTER zu zwei oder drei internen Konten hinzu.
Schritt 2: Die Function anhand des Vorhandenseins des Tags verzweigen
// At the top of your run function let is_tester = input .cart() .buyer_identity() .and_then(|bi| bi.customer()) .map(|c| c.has_any_tag()) .unwrap_or(&false); if !*is_tester { return Ok(default_result); // Fall through to existing Script } // New Function logic only runs for tagged users
// At the top of your run function let is_tester = input .cart() .buyer_identity() .and_then(|bi| bi.customer()) .map(|c| c.has_any_tag()) .unwrap_or(&false); if !*is_tester { return Ok(default_result); // Fall through to existing Script } // New Function logic only runs for tagged users
Schritt 3: hasAnyTag zu deiner Input-Abfrage hinzufügen
cart { buyerIdentity { customer { hasAnyTag(tags: ["FN-TESTER"]) } } }
cart { buyerIdentity { customer { hasAnyTag(tags: ["FN-TESTER"]) } } }
Schritt 4: Im Checkout verifizieren
Melde dich als markierter Nutzer an, gehe den Checkout durch und bestätige, dass die Function auslöst. Melde dich als nicht markierter Nutzer an und bestätige, dass der alte Script weiterhin läuft. Wenn die Ergebnisse einige Tage lang übereinstimmen, entferne die Tag-Prüfung und lasse die Function für alle laufen.
Schritt 5: Den alten Script unveröffentlichen
Gehe zu Apps → Script Editor → [Dein Script] → Unpublish. Sobald er unveröffentlicht ist, ist die Function die einzige Quelle der Wahrheit.
Ein Bereitstellungs-Workflow, der tatsächlich skaliert
Stelle nicht ewig von einem Entwickler-Laptop aus bereit. Sobald du ein oder zwei Scripts migriert hast, richte eine echte CI-Pipeline ein.
Der minimale praktikable Workflow
# .github/workflows/deploy-functions.yml name: Deploy Shopify Functions on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: '20' } - uses: dtolnay/rust-toolchain@stable with: { targets: wasm32-wasip1 } - run: npm install -g @shopify/cli@latest - run: shopify app deploy --force env: SHOPIFY_CLI_PARTNERS_TOKEN: ${{ secrets.SHOPIFY_CLI_PARTNERS_TOKEN }}
# .github/workflows/deploy-functions.yml name: Deploy Shopify Functions on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: '20' } - uses: dtolnay/rust-toolchain@stable with: { targets: wasm32-wasip1 } - run: npm install -g @shopify/cli@latest - run: shopify app deploy --force env: SHOPIFY_CLI_PARTNERS_TOKEN: ${{ secrets.SHOPIFY_CLI_PARTNERS_TOKEN }}
Erzeuge das Partner-Token im Partner-Dashboard unter Einstellungen → Tokens. Ab jetzt shippt jeder Merge auf main deine Functions. Keine Slack-Threads mehr mit „Hat Mike das bereitgestellt?“
Versionierung und Rollback
shopify app deploy erstellt einen versionierten Snapshot. Zum Zurückrollen:
shopify app versions list shopify app release --version <previous-version-id
shopify app versions list shopify app release --version <previous-version-id
Im Vergleich zu Scripts — bei denen Rollback bedeutete „an den alten Code denken und ihn wieder einfügen“ — ist das ein Unterschied wie Tag und Nacht.

Was die meisten Teams falsch machen
Nachdem wir Plus-Händler im letzten Jahr durch diese Migration begleitet haben, tauchen immer wieder dieselben fünf Fehler auf.
1. Functions wie einen 1:1-Script-Port behandeln. Tun sie nicht. Eine einzelne Function kann drei Scripts mit saubererer Verzweigungslogik ersetzen. Prüfe deine Scripts als System, bevor du sie neu schreibst.
2. Die Read-Scopes vergessen. Viele Functions benötigen read_customers, read_orders oder write_discounts. Füge sie in shopify.app.toml unter scopes hinzu und autorisiere die App neu, sonst gibt deine Input-Abfrage null zurück.
3. Functions für nicht markierte Kunden ohne Paritätstests ausführen. Selbst wenn dein Code richtig aussieht, werden Sonderfälle (leerer Warenkorb, Geschenkkarten, Store Credit, B2B-Entwürfe) Probleme aufzeigen. Eine markierungsbasierte Einführung kostet dich zwei Tage und erspart dir einen P1-Ausfall.
4. Den Anpassungsbericht überspringen. Er ist das beste Inventar dessen, was tatsächlich läuft. Migriere nicht aus dem Gedächtnis — migriere anhand des Berichts.
5. Collection-IDs und Kunden-Tags hart kodieren. Nutze die Function-Konfiguration über Metafields, wenn du vom Händler anpassbare Werte brauchst. Die CLI kann eine metadatenbasierte Konfiguration scaffolden — siehe Shopifys Dokumentation zur Function-Konfiguration.
Migrations-Checkliste für die nächsten 75 Tage
Ein realistischer Wochenplan, um entspannt bis zum 30. Juni zu kommen.
Woche | Maßnahme |
|---|---|
Woche 1 (diese Woche) | Den Anpassungsbericht ziehen. Jeden Script inventarisieren. Entscheiden: Function vs. Public App vs. löschen. |
Wochen 2–3 | Lokale Entwicklungsumgebung einrichten. Die erste Function scaffolden. Den einfachsten Script migrieren (meist eine Regel zum Ausblenden einer Zahlungsmethode). |
Wochen 4–6 | Discount-Scripts migrieren. Diese dauern am längsten, weil die Discounts API am umfangreichsten ist. Gründlich mit Tags testen. |
Wochen 7–8 | Shipping-/Delivery-Scripts migrieren. Delivery Customizations über den Admin aktivieren. |
Wochen 9–10 | CI-Pipeline einrichten. Alle Bereitstellungen von Entwickler-Laptops weg verlagern. |
Woche 11 (Mitte Juni) | Finale Paritätsprüfung. Alle Scripts unveröffentlichen. Den Store zwei Wochen lang nur mit Functions betreiben. |
30. Juni | Der Stichtag ist da. Nichts bricht, weil du früh fertig warst. |
Wenn du diese Woche startest, hast du Puffer. Wenn du im Juni startest, hast du keinen.

Häufig gestellte Fragen
Brauche ich Shopify Plus, um Functions zu verwenden?
Custom Functions erfordern Shopify Plus, aber Public-App-Functions funktionieren in jedem Plan. Wenn du nicht auf Plus bist, hast du zwei Wege: Installiere eine Public App aus dem Shopify App Store, die die Function für dich bereitstellt, oder upgrade auf Plus, um deine eigenen Custom Functions zu schreiben. Die meisten großen Händler, die Scripts hatten, waren ohnehin schon auf Plus, daher ändert sich in der Praxis selten etwas.
Kann ich Functions in TypeScript schreiben?
Ja — TypeScript wird vollständig unterstützt und die CLI scaffoldet es für dich. Wenn du shopify app generate extension ausführst und „JavaScript“ auswählst, enthält das generierte Projekt Typdeklarationen aus import("../generated/api"). Du kannst Dateien bei Bedarf in .ts umwandeln und eine tsconfig.json hinzufügen. Die kompilierte Ausgabe (WASM) ist unabhängig von der Quellsprache identisch.
Wie schnell sind Functions im Vergleich zu Scripts?
Functions laufen typischerweise in unter 5 ms — deutlich schneller als Ruby Scripts. Da sie in WebAssembly kompiliert werden und in einer schlanken Runtime laufen, setzt Shopify ein Ausführungsbudget von 5 ms durch. Überschreitet deine Function dieses Budget, wird die Operation verworfen und deine Function gibt keine Operationen zurück. In der Praxis benötigt eine gut geschriebene Function 1–2 ms. Die Leistungsgrenze ist wesentlich höher als bei Scripts.
Kann eine Function eine externe API aufrufen?
Nein — Functions können keine Netzwerkrequests ausführen. Sie sind reine Berechnung: Input-Warenkorbdaten → Output-Operationen. Wenn du externe Daten benötigst (ein CRM-Lookup, eine Echtzeit-Bestandsprüfung), musst du die Daten entweder vorher in Metafields speichern oder eine andere Oberfläche verwenden (App Proxy, Webhooks, Cart Transform mit Backend-Lookup). Das ist der häufigste Grund, warum Teams neu entwerfen statt nur portieren müssen.
Was ist der Unterschied zwischen Cart Transform und Discounts?
Discounts ändern Preise; Cart Transform ändert den Inhalt des Warenkorbs. Verwende die Discounts API für 10 % Rabatt, kostenlosen Versand oder BOGO. Verwende Cart Transform, um zwei Produkte zu einem Line Item zu bündeln oder eine Variante in mehrere aufzuteilen. Viele alte Scripts vermischten beide Themen — trenne sie bei der Migration in zwei Functions.
Wie teste ich eine Function lokal ohne Development Store?
Du kannst Unit-Tests mit cargo test (Rust) oder npm test (JS) ausführen, aber vollständige Integrationstests erfordern einen Development Store. Die CLI bietet shopify app function run, womit du deine Function gegen eine Beispiel-Input-Datei ausführen kannst — nützlich für schnelle Iterationen. Um das Checkout-Verhalten jedoch end-to-end zu bestätigen, brauchst du einen echten Store mit einem echten Warenkorb.
Kann ich mehrere Functions desselben Typs haben?
Ja — Shopify unterstützt mehrere Functions pro Ziel, und sie laufen in deterministischer Reihenfolge. Bei Discounts wird die Reihenfolge durch Shopify-Regeln zum Stapeln von Rabatten bestimmt. Bei Delivery- und Payment-Customizations kannst du Functions verketten, aber jede Ausgabe speist die nächste. Die meisten Teams verwenden zur Einfachheit eine Function pro Typ.
Was passiert mit meinem Script, nachdem ich die Function bereitgestellt habe?
Beide laufen parallel, bis du den Script im Apps → Script Editor unveröffentlichst. Das ist absichtlich so — es gibt dir das Testfenster für parallelen Betrieb. Nachdem du geprüft hast, dass die Function funktioniert, veröffentliche den Script manuell nicht mehr. Nach dem 30. Juni 2026 stoppen alle Scripts die Ausführung, unabhängig davon, ob du sie unveröffentlicht hast oder nicht.
Beeinflusst die Migration mein SEO oder Theme?
Nein — Functions laufen serverseitig im Checkout und berühren weder dein Theme noch Produktseiten. Sie ändern nur Rabatte, Versandoptionen und Zahlungsmethoden im Checkout. Dein Storefront, deine Produktvorlagen und dein SEO bleiben vollständig unberührt.
Wie migriere ich einen Script, der Input.line_items mit benutzerdefinierten Eigenschaften verwendet?
Benutzerdefinierte Eigenschaften sind über das attribute-Feld auf Warenkorbpositionen im GraphQL-Input zugänglich. Füge attribute(key: "your-key") { value } innerhalb der lines-Auswahl hinzu. Die Function liest sie identisch zu Scripts, die Line-Item-Properties lesen — nur über GraphQL statt über Ruby-Methodenaufrufe.
Und was ist mit Analytics und Bestell-Tags? Können Functions Daten schreiben?
Functions können keine Bestell-Tags schreiben oder selbst Webhooks auslösen — sie geben nur Operationen auf dem aktuellen Warenkorb zurück. Für Tagging oder nachgelagerte Workflows verwende Shopify Flow, ausgelöst durch das Ereignis der Bestellerstellung. Viele Händler kombinieren eine Function (für den Rabatt) mit einem Flow (um „VOLUME-DISCOUNT-APPLIED“ auf der Bestellung zu taggen).
Gibt es eine Public App, die ich installieren kann, statt eine Custom Function zu bauen?
Ja — im Shopify App Store gibt es Dutzende Apps, die Functions für gängige Anwendungsfälle verpacken. Suche nach „discount function“, „delivery customization“ oder „payment customization“. Für einfache Anwendungsfälle (Mengenrabatte, Zahlungsmethoden nach Tag ausblenden, kostenloser Versand ab X) kann dir eine bestehende App Tage an Entwicklungsarbeit sparen. Hebe dir Custom Functions für Logik auf, die wirklich einzigartig für dein Geschäft ist.
Was passiert, wenn ich die Frist am 30. Juni verpasse?
Der Script stoppt die Ausführung — es gibt keinen Fallback, keine Schonfrist und keine Verlängerung. Was auch immer der Script getan hat (der Rabatt, der ausgeblendete Versandtarif, die blockierte Zahlungsmethode) kehrt um Mitternacht UTC am 1. Juli zum Standardverhalten zurück. Wenn dein Geschäft von dieser Logik abhängt, plane, lange vor diesem Datum live zu sein. Die Migration dauert länger, als die meisten Teams schätzen, besonders mit Paritätstests.
Kann ich die Script Editor-App komplett löschen?
Du kannst sie nach dem 30. Juni 2026 deinstallieren, aber Shopify wird sie wahrscheinlich automatisch entfernen. Sobald Scripts nicht mehr ausgeführt werden, hat der Editor keinen Zweck mehr. Du kannst auch jetzt alle Scripts unveröffentlichen und die App sofort deinstallieren, wenn du die Migration abgeschlossen hast — deine Functions sind unabhängig.
Was du diese Woche tun solltest
Lies diesen Artikel nicht nur und schließe den Tab. Tue in den nächsten sieben Tagen diese vier Dinge.
1. Den Anpassungsbericht ziehen. Gehe zu Einstellungen → Checkout → Anpassungsbericht. Exportiere ihn. Das ist dein Migrations-Backlog.
2. Richte deine Entwicklungsumgebung ein. Installiere Node 18+, Shopify CLI und Rust (falls zutreffend). Bestätige, dass shopify version funktioniert. Gesamtzeit: 30 Minuten.
3. Scaffold und shippe eine winzige Function in einen Development Store. Wähle den einfachsten Script, den du hast — meist eine Regel zum Ausblenden einer Zahlungsmethode. Migriere ihn vollständig. Selbst wenn er nie in Produktion geht, hast du die Toolchain validiert.
4. Blockiere Kalenderzeit für die nächsten acht Wochen. Migrationen passieren nicht in freien Momenten zwischen Sprints. Reserviere einen wiederkehrenden Slot — zum Beispiel jeden Dienstag- und Donnerstagnachmittag — und behandle ihn wie ein Release.
Bei den Teams, die wir migrieren gesehen haben, ist das Muster immer gleich: zwei Wochen Stillstand, drei Wochen echte Arbeit, eine Woche Aufräumen. Das sind sechs Wochen. Du hast zehn. Der Puffer ist da — verbrauche ihn für Code-Review und QA, nicht dafür, den Start immer weiter aufzuschieben.
Und wenn deine Checkout-Logik einmal sortiert ist, ist der nächste große Themenblock für die meisten Teams Post-Purchase — Adressänderungen durch Kunden, Umtausche, Rabattergänzungen nach der Bestellung. Wenn das auf deiner Roadmap steht (und das sollte es, egal ob du ein hochvolumiger Plus-Betreiber oder ein CX-orientierter Advanced-Store bist), Revize ist im Shopify App Store verfügbar und funktioniert neben jeder Function, die du hier bauen wirst.
Ressourcen
Verwandte Artikel
Es ist der 16. April 2026. Gestern — der 15. April — war der Tag, an dem Shopify den Script Editor endgültig gesperrt hat. Du kannst keinen neuen Script mehr erstellen oder veröffentlichen. Die Abschaltung der Ausführung erfolgt in 75 Tagen, am 30. Juni 2026.
Wenn du Shopify-Plus-Entwickler bist — oder die Agentur, die einen Plus-Store betreut — und diese Migration in den letzten zwölf Monaten immer wieder auf den „nächsten Sprint“ verschoben hast, hast du ein Problem. Kein „wäre nett zu beheben“-Problem. Ein „dein Checkout bricht am 1. Juli um Mitternacht zusammen“-Problem. Die meisten Plus-Stores haben über die Jahre 5 bis 20 Scripts angesammelt, die unauffällig eine Rabattregel, das Ausblenden von Versandarten oder eine Zahlungsblockade antreiben, an die sich niemand mehr erinnert.
Dieser Leitfaden ist das technische Migrationshandbuch, das wir uns im Januar gewünscht hätten. Er behandelt den tatsächlichen Code — nicht nur die Strategie. Wenn du fertig gelesen hast, weißt du, wie du mit der Shopify CLI eine Function scaffoldest, die Rust- oder JavaScript-Logik für Rabatte, Lieferanpassungen und Zahlungsanpassungen schreibst, sie sicher gegen eine markierte Teilmenge deiner Kunden testest und sie ohne Beeinträchtigung deines bestehenden Checkouts in die Produktion bringst.
Lass uns die Scripts aus deinem Shop entfernen und die Functions darin aktivieren.

Kurzantwort: Scripts → Functions in 60 Sekunden
Die Migration in einem Absatz: Shopify Scripts (Ruby-Code im Script Editor, nur Plus) werden durch Shopify Functions ersetzt (WebAssembly-Module, geschrieben in Rust oder JavaScript, für alle Pläne verfügbar). Du scaffoldest eine Function mit
shopify app generate extension, schreibst einerun.graphql-Abfrage, die die benötigten Warenkorbdaten lädt, schreibst einerun.rs- oderrun.js-Datei, die Operationen zurückgibt (Rabatte, ausgeblendete Versandarten usw.), stellst dann mitshopify app deploybereit und aktivierst sie über den Admin oder eine GraphQL-Mutation. Functions laufen als kompiliertes WASM mit Latenzen unter 5 ms, funktionieren in allen Plänen und sind der einzige Anpassungsweg, den Shopify künftig unterstützt.
Was sich am 30. Juni tatsächlich ändert
Bevor wir irgendeinen Code anfassen, klären wir die Daten. Es gibt zwei davon, und beide sind wichtig.
Datum | Was passiert | Deine Maßnahme |
|---|---|---|
15. April 2026 (vergangen) | Script Editor nur noch lesbar. Keine neuen Scripts. Keine Bearbeitung bestehender Scripts. | Bestehende Scripts laufen weiter. Migriere jetzt oder friere deine Logik ein. |
30. Juni 2026 | Alle Shopify Scripts hören auf zu laufen. Punkt. | Dein Function-Ersatz muss vor diesem Datum live sein. |
Die Migration ist binär. Entweder ist deine Function bis zum 30. Juni bereitgestellt und dein Checkout funktioniert weiter, oder sie ist es nicht — und jeder betroffene Warenkorb fällt unauffällig auf Standardpreise, Standardversandtarife und alle aktivierten Zahlungsmethoden zurück. Es gibt keine Teilpunkte. Der Script läuft entweder oder er läuft nicht, und nach dem 30. Juni läuft er nicht mehr.
Tipp: Öffne in deinem Shopify-Admin
Einstellungen → Checkout → Anpassungsbericht. Dort sind alle aktiven Scripts in deinem Shop aufgelistet, was sie tun und welcher Function-Typ als Ersatz empfohlen wird. Fang dort an.
Functions vs. Scripts: Was sich tatsächlich geändert hat
Dimension | Shopify Scripts (veraltet) | Shopify Functions (Ersatz) |
|---|---|---|
Sprache | Ruby DSL (Shopify-spezifisch) | Rust, JavaScript, TypeScript |
Runtime | Sandboxed Ruby auf Shopify-Infrastruktur | WebAssembly (WASM) — Ausführung unter 5 ms |
Plan-Verfügbarkeit | Nur Plus | Alle Pläne (Custom Apps erfordern Plus; Public Apps sind offen) |
Editor | Script Editor im Admin | Lokale IDE + Shopify CLI |
Versionierung | Keine — Live-Bearbeitungen | Git-freundlich — vollständige Versionskontrolle |
Testen | Manuell im Checkout | Lokale Entwicklung mit |
Bereitstellung | Im Admin auf „Save“ klicken |
|
Ziele | Positionen, Versand, Zahlungen | Rabatte, Cart Transform, Validation, Delivery Customization, Payment Customization, Order Routing, Fulfillment Constraints, mehr |
Der architektonische Wandel ist wichtig. Scripts waren „Ruby in einem Textfeld anpassen“. Functions sind „eine echte App schreiben, sie per Versionskontrolle verwalten, lokal testen und über eine echte CI-Pipeline bereitstellen“. Das ist eine steilere Lernkurve. Es ist auch die letzte Migration, die du in absehbarer Zeit für Checkout-Logik machen wirst — Functions sind Shopifys langfristige Zusage, nicht wie sich Scripts als Zwischenlösung herausgestellt haben.
Deine Scripts dem richtigen Function-Typ zuordnen
Jeder Script, den du heute hast, passt genau zu einer Function-API. Hier ist die Lookup-Tabelle, die du an deinen Monitor heften solltest.
Alter Script-Typ | Was er tat | Neue Function-API | Function-Ziel |
|---|---|---|---|
Line Item Script | Rabatte auf bestimmte Produkte / Kunden / Warenkorbbedingungen anwenden | Cart & Checkout Discounts API |
|
Shipping Script (Rabatt) | Kostenloser / vergünstigter Versand basierend auf Warenkorbregeln | Cart & Checkout Discounts API |
|
Shipping Script (ausblenden / umbenennen / neu sortieren) | Eine Versandart über $X ausblenden, „Standard“ in „Gratis ab 50 $“ umbenennen | Delivery Customization API |
|
Payment Script | PayPal für B2B ausblenden, Nachnahme über 500 $ ausblenden, Methoden neu sortieren | Payment Customization API |
|
Cart-modifying Script (selten) | Produkte bündeln, Positionen austauschen | Cart Transform API |
|
Checkout blockierender Script | Warenkorb ablehnen, wenn die SKU-Mischung ungültig ist | Cart & Checkout Validation API |
|
Wenn du zehn Scripts hast, wirst du wahrscheinlich drei bis fünf Functions bauen — mehrere Scripts lassen sich oft zu einer Function mit saubererer Verzweigungslogik zusammenfassen.

Voraussetzung: Richte deine lokale Entwicklungsumgebung ein
Bevor du irgendeine Function scaffoldest, brauchst du lokal drei Dinge installiert. Führe diese Prüfungen in deinem Terminal aus.
1. Node.js 18+
node --version # Must be >= 18.0.0
Falls älter, installiere es über nvm oder lade es von nodejs.org herunter.
2. Shopify CLI 3+
npm install -g @shopify/cli@latest shopify version # Should output 3.x or higher
3. Rust-Toolchain (nur wenn du Functions in Rust schreiben wirst)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh rustup target add wasm32-wasip1 cargo --version
JavaScript-Functions brauchen kein Rust. Wähle eine Sprache für dein Team und bleib dabei — beides zu mischen erhöht den Wartungsaufwand.
4. Ein Development Store
Melde dich entweder im Partner-Dashboard an und erstelle einen neuen Development Store oder verwende einen bestehenden. Du stellst Functions zuerst in diesem Store bereit, bevor du sie in die Produktion überführst.
Deine erste Function scaffolden
Die CLI erledigt den größten Teil des Boilerplates. In einem beliebigen Verzeichnis:
# Create a new Shopify app (skip if you already have one) shopify app init my-checkout-functions cd my-checkout-functions # Generate a Function extension shopify app generate extension
Die CLI führt dich durch die Eingaben. Für eine Discount-Function würdest du wählen:
Typ: Function
Vorlage:
discount(odercart_checkout_validation,delivery_customization,payment_customizationusw.)Sprache: Rust oder JavaScript
Name: etwas wie
volume-discount-fn
Dadurch wird extensions/volume-discount-fn/ mit Folgendem erstellt:
extensions/volume-discount-fn/ ├── shopify.extension.toml # Function config — targets, build, version ├── src/ │ ├── cart_lines_discounts_generate_run.graphql # Input query │ └── cart_lines_discounts_generate_run.rs # Function logic ├── Cargo.toml # Rust dependencies (Rust only) └── README.md
Die drei Dateien, die du ständig bearbeiten wirst, sind die .toml (Konfiguration), die .graphql (Input) und die .rs / .js (Logik). Das ist alles.
Tutorial 1: Einen Line Item Script ersetzen (Mengenrabatt)
Angenommen, dein alter Script gewährte 10 % Rabatt auf die Bestellsumme, wenn der Warenkorb 5+ Einheiten aus einer bestimmten Kollektion enthielt. Hier ist das entsprechende Function-Pendant.
Schritt 1.1: Die Konfiguration (shopify.extension.toml)
api_version = "2026-01" [[extensions]] name = "volume-discount-fn" handle = "volume-discount-fn" type = "function" [[extensions.targeting]] target = "cart.lines.discounts.generate.run" input_query = "src/cart_lines_discounts_generate_run.graphql" export = "cart_lines_discounts_generate_run" [extensions.build] command = "cargo build --target=wasm32-wasip1 --release" path = "target/wasm32-wasip1/release/volume-discount-fn.wasm" watch = ["src/**/*.rs"]
Schritt 1.2: Die Input-Abfrage (src/cart_lines_discounts_generate_run.graphql)
query Input { cart { lines { id quantity cost { subtotalAmount { amount } } merchandise { ... on ProductVariant { product { inAnyCollection(ids: ["gid://shopify/Collection/123456789"]) } } } } } discount { discountClasses } }
Tipp: Functions sehen nur die Daten, die du abfragst. Halte GraphQL minimal — jedes Feld, das du weglässt, bedeutet eine schnellere und günstigere Ausführung.
Schritt 1.3: Die Logik (src/cart_lines_discounts_generate_run.rs)
use super::schema; use shopify_function::prelude::*; use shopify_function::Result; #[shopify_function] fn cart_lines_discounts_generate_run( input: schema::cart_lines_discounts_generate_run::Input, ) -> Result<schema::CartLinesDiscountsGenerateRunResult> { // Bail if discount class doesn't match let has_order_discount = input .discount() .discount_classes() .contains(&schema::DiscountClass::Order); if !has_order_discount { return Ok(schema::CartLinesDiscountsGenerateRunResult { operations: vec![] }); } // Sum quantities of items in the target collection let qualifying_qty: i64 = input .cart() .lines() .iter() .filter(|line| { if let schema::Merchandise::ProductVariant(v) = line.merchandise() { *v.product().in_any_collection() } else { false } }) .map(|line| *line.quantity()) .sum(); if qualifying_qty < 5 { return Ok(schema::CartLinesDiscountsGenerateRunResult { operations: vec![] }); } // Apply 10% off the order subtotal Ok(schema::CartLinesDiscountsGenerateRunResult { operations: vec![schema::CartOperation::OrderDiscountsAdd( schema::OrderDiscountsAddOperation { selection_strategy: schema::OrderDiscountSelectionStrategy::First, candidates: vec![schema::OrderDiscountCandidate { targets: vec![schema::OrderDiscountCandidateTarget::OrderSubtotal( schema::OrderSubtotalTarget { excluded_cart_line_ids: vec![], }, )], message: Some("Volume discount: 10% off".to_string()), value: schema::OrderDiscountCandidateValue::Percentage( schema::Percentage { value: Decimal(10.0) } ), conditions: None, associated_discount_code: None, }], }, )], }) }
Schritt 1.4: Testen, bereitstellen, aktivieren
# Local development with hot reload shopify app dev # When ready, deploy shopify app deploy # In the GraphiQL panel that opens (press `g` in the dev terminal), # create the automatic discount that uses your Function:
mutation { discountAutomaticAppCreate( automaticAppDiscount: { title: "Volume Discount (5+ collection items)" functionHandle: "volume-discount-fn" discountClasses: [ORDER] startsAt: "2026-04-16T00:00:00Z" } ) { automaticAppDiscount { discountId } userErrors { field message } } }
Das ist alles. Die Function ist live, versioniert und ersetzt den alten Script vollständig.
Tutorial 2: Einen Shipping Script ersetzen (Methode über Warenkorbgrenze ausblenden)
Ein häufiger Script: „Expressversand ausblenden, wenn der Warenkorbwert über 500 $ liegt, um teuren Overnight-Versand bei großen Bestellungen zu verhindern.“ Hier ist die Version als Delivery Customization Function.
Schritt 2.1: Scaffold
shopify app generate extension --template delivery_customization --name hide-express-fn
Schritt 2.2: Input-Abfrage (src/run.graphql)
query Input { cart { cost { subtotalAmount { amount } } deliveryGroups { deliveryOptions { handle title } } } }
Schritt 2.3: Logik (src/run.js — JavaScript-Variante)
// @ts-check /** * @typedef {import("../generated/api").RunInput} RunInput * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult */ const NO_CHANGES = { operations: [] }; const THRESHOLD = 500.0; const HIDE_TITLES = ["Express", "Overnight"]; /** * @param {RunInput} input * @returns {FunctionRunResult} */ export function run(input) { const subtotal = parseFloat(input.cart.cost.subtotalAmount.amount); if (subtotal < THRESHOLD) return NO_CHANGES; const operations = input.cart.deliveryGroups.flatMap((group) => group.deliveryOptions .filter((opt) => HIDE_TITLES.some((t) => opt.title.includes(t))) .map((opt) => ({ hide: { deliveryOptionHandle: opt.handle }, })) ); return { operations }; }
Schritt 2.4: Über den Admin aktivieren (keine GraphQL erforderlich)
Delivery Customizations haben eine integrierte Admin-Oberfläche. Nach shopify app deploy:
Gehe zu Einstellungen → Versand und Lieferung
Scrolle im unteren Bereich zum Abschnitt Anpassungen
Klicke auf Anpassung hinzufügen → wähle deine Function aus
Speichern
Die Regel zum Ausblenden ist in der Produktion live. Keine Mutation erforderlich.

Tutorial 3: Einen Payment Script ersetzen (Nachnahme für B2B ausblenden)
Alter Script: „Nachnahme für jeden Kunden mit dem Tag 'B2B' ausblenden.“ Hier ist die Payment Customization-Version.
Schritt 3.1: Scaffold
shopify app generate extension --template payment_customization --name hide-cod-b2b-fn
Schritt 3.2: Input-Abfrage
query Input { cart { buyerIdentity { customer { hasTags(tags: [{ tag: "B2B" }]) { tag hasTag } } } } paymentMethods { id name } }
Schritt 3.3: Logik (src/run.js)
const NO_CHANGES = { operations: [] }; export function run(input) { const tagCheck = input.cart?.buyerIdentity?.customer?.hasTags?.[0]; const isB2B = tagCheck?.hasTag === true; if (!isB2B) return NO_CHANGES; const codMethod = input.paymentMethods.find((pm) => pm.name.toLowerCase().includes("cash on delivery") ); if (!codMethod) return NO_CHANGES; return { operations: [{ hide: { paymentMethodId: codMethod.id } }], }; }
Schritt 3.4: Aktivieren
Payment Customizations haben ebenfalls eine Admin-Oberfläche unter Einstellungen → Zahlungen → Anpassungen. Gleicher Ablauf wie bei Delivery — Function auswählen, speichern, fertig.
Da du das hier liest — ein Wort zu Post-Purchase
Eine kurze Offenlegung, weil dies der Revize-Blog ist. Revize kümmert sich um die Dinge, die Functions nicht anfassen können — sobald eine Bestellung aufgegeben wurde, wollen Kunden einen Artikel hinzufügen, eine Größe tauschen, die Lieferadresse korrigieren oder einen vergessenen Rabatt anwenden. Functions sitzen im Checkout. Revize sitzt danach. Functions entscheiden, was im Warenkorb erlaubt ist; Revize gibt deinen Kunden und dem Support-Team die Möglichkeit, die Bestellung danach zu bearbeiten, ohne einen Rückerstattungs-und-Neuerstellungs-Zyklus. Das ist für zwei Arten von Shops wichtig: diejenigen mit so viel Bestellvolumen, dass manuelle Bearbeitung zusammenbricht (offensichtlich Plus-Betreiber, aber auch stark ausgelastete Advanced-Stores), und diejenigen, deren gesamte Marke auf Kundenerlebnis basiert — wo eine „Tut uns leid, das können wir nicht ändern“-E-Mail Wiederkäufe verhindert.
Wenn dein Migrationsplan Scripts → Functions abdeckt, du aber Post-Purchase-Bestelländerungen nie sauber gelöst hast, wirst du in etwa drei Wochen an die nächste „Warum ist das so schwer?“-Wand stoßen. Der gerade veröffentlichte Leitfaden zur Bestellverwaltung beschreibt den vollständigen Post-Checkout-Plan.
Zurück zur Migration.
Teststrategie: Das Muster mit markierten Kunden
Functions haben keinen „Draft-Modus“, den du im Admin umschalten kannst. Das professionelle Muster ist, die neue Function über ein Kunden-Tag zu begrenzen, den alten Script und die neue Function parallel laufen zu lassen, zu prüfen, dass sie für markierte Nutzer identische Ergebnisse liefern, und dann den Schalter umzulegen.
Schritt 1: Deine Testnutzer taggen
Füge in Kunden das Tag FN-TESTER zu zwei oder drei internen Konten hinzu.
Schritt 2: Die Function anhand des Vorhandenseins des Tags verzweigen
// At the top of your run function let is_tester = input .cart() .buyer_identity() .and_then(|bi| bi.customer()) .map(|c| c.has_any_tag()) .unwrap_or(&false); if !*is_tester { return Ok(default_result); // Fall through to existing Script } // New Function logic only runs for tagged users
Schritt 3: hasAnyTag zu deiner Input-Abfrage hinzufügen
cart { buyerIdentity { customer { hasAnyTag(tags: ["FN-TESTER"]) } } }
Schritt 4: Im Checkout verifizieren
Melde dich als markierter Nutzer an, gehe den Checkout durch und bestätige, dass die Function auslöst. Melde dich als nicht markierter Nutzer an und bestätige, dass der alte Script weiterhin läuft. Wenn die Ergebnisse einige Tage lang übereinstimmen, entferne die Tag-Prüfung und lasse die Function für alle laufen.
Schritt 5: Den alten Script unveröffentlichen
Gehe zu Apps → Script Editor → [Dein Script] → Unpublish. Sobald er unveröffentlicht ist, ist die Function die einzige Quelle der Wahrheit.
Ein Bereitstellungs-Workflow, der tatsächlich skaliert
Stelle nicht ewig von einem Entwickler-Laptop aus bereit. Sobald du ein oder zwei Scripts migriert hast, richte eine echte CI-Pipeline ein.
Der minimale praktikable Workflow
# .github/workflows/deploy-functions.yml name: Deploy Shopify Functions on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: '20' } - uses: dtolnay/rust-toolchain@stable with: { targets: wasm32-wasip1 } - run: npm install -g @shopify/cli@latest - run: shopify app deploy --force env: SHOPIFY_CLI_PARTNERS_TOKEN: ${{ secrets.SHOPIFY_CLI_PARTNERS_TOKEN }}
Erzeuge das Partner-Token im Partner-Dashboard unter Einstellungen → Tokens. Ab jetzt shippt jeder Merge auf main deine Functions. Keine Slack-Threads mehr mit „Hat Mike das bereitgestellt?“
Versionierung und Rollback
shopify app deploy erstellt einen versionierten Snapshot. Zum Zurückrollen:
shopify app versions list shopify app release --version <previous-version-id
Im Vergleich zu Scripts — bei denen Rollback bedeutete „an den alten Code denken und ihn wieder einfügen“ — ist das ein Unterschied wie Tag und Nacht.

Was die meisten Teams falsch machen
Nachdem wir Plus-Händler im letzten Jahr durch diese Migration begleitet haben, tauchen immer wieder dieselben fünf Fehler auf.
1. Functions wie einen 1:1-Script-Port behandeln. Tun sie nicht. Eine einzelne Function kann drei Scripts mit saubererer Verzweigungslogik ersetzen. Prüfe deine Scripts als System, bevor du sie neu schreibst.
2. Die Read-Scopes vergessen. Viele Functions benötigen read_customers, read_orders oder write_discounts. Füge sie in shopify.app.toml unter scopes hinzu und autorisiere die App neu, sonst gibt deine Input-Abfrage null zurück.
3. Functions für nicht markierte Kunden ohne Paritätstests ausführen. Selbst wenn dein Code richtig aussieht, werden Sonderfälle (leerer Warenkorb, Geschenkkarten, Store Credit, B2B-Entwürfe) Probleme aufzeigen. Eine markierungsbasierte Einführung kostet dich zwei Tage und erspart dir einen P1-Ausfall.
4. Den Anpassungsbericht überspringen. Er ist das beste Inventar dessen, was tatsächlich läuft. Migriere nicht aus dem Gedächtnis — migriere anhand des Berichts.
5. Collection-IDs und Kunden-Tags hart kodieren. Nutze die Function-Konfiguration über Metafields, wenn du vom Händler anpassbare Werte brauchst. Die CLI kann eine metadatenbasierte Konfiguration scaffolden — siehe Shopifys Dokumentation zur Function-Konfiguration.
Migrations-Checkliste für die nächsten 75 Tage
Ein realistischer Wochenplan, um entspannt bis zum 30. Juni zu kommen.
Woche | Maßnahme |
|---|---|
Woche 1 (diese Woche) | Den Anpassungsbericht ziehen. Jeden Script inventarisieren. Entscheiden: Function vs. Public App vs. löschen. |
Wochen 2–3 | Lokale Entwicklungsumgebung einrichten. Die erste Function scaffolden. Den einfachsten Script migrieren (meist eine Regel zum Ausblenden einer Zahlungsmethode). |
Wochen 4–6 | Discount-Scripts migrieren. Diese dauern am längsten, weil die Discounts API am umfangreichsten ist. Gründlich mit Tags testen. |
Wochen 7–8 | Shipping-/Delivery-Scripts migrieren. Delivery Customizations über den Admin aktivieren. |
Wochen 9–10 | CI-Pipeline einrichten. Alle Bereitstellungen von Entwickler-Laptops weg verlagern. |
Woche 11 (Mitte Juni) | Finale Paritätsprüfung. Alle Scripts unveröffentlichen. Den Store zwei Wochen lang nur mit Functions betreiben. |
30. Juni | Der Stichtag ist da. Nichts bricht, weil du früh fertig warst. |
Wenn du diese Woche startest, hast du Puffer. Wenn du im Juni startest, hast du keinen.

Häufig gestellte Fragen
Brauche ich Shopify Plus, um Functions zu verwenden?
Custom Functions erfordern Shopify Plus, aber Public-App-Functions funktionieren in jedem Plan. Wenn du nicht auf Plus bist, hast du zwei Wege: Installiere eine Public App aus dem Shopify App Store, die die Function für dich bereitstellt, oder upgrade auf Plus, um deine eigenen Custom Functions zu schreiben. Die meisten großen Händler, die Scripts hatten, waren ohnehin schon auf Plus, daher ändert sich in der Praxis selten etwas.
Kann ich Functions in TypeScript schreiben?
Ja — TypeScript wird vollständig unterstützt und die CLI scaffoldet es für dich. Wenn du shopify app generate extension ausführst und „JavaScript“ auswählst, enthält das generierte Projekt Typdeklarationen aus import("../generated/api"). Du kannst Dateien bei Bedarf in .ts umwandeln und eine tsconfig.json hinzufügen. Die kompilierte Ausgabe (WASM) ist unabhängig von der Quellsprache identisch.
Wie schnell sind Functions im Vergleich zu Scripts?
Functions laufen typischerweise in unter 5 ms — deutlich schneller als Ruby Scripts. Da sie in WebAssembly kompiliert werden und in einer schlanken Runtime laufen, setzt Shopify ein Ausführungsbudget von 5 ms durch. Überschreitet deine Function dieses Budget, wird die Operation verworfen und deine Function gibt keine Operationen zurück. In der Praxis benötigt eine gut geschriebene Function 1–2 ms. Die Leistungsgrenze ist wesentlich höher als bei Scripts.
Kann eine Function eine externe API aufrufen?
Nein — Functions können keine Netzwerkrequests ausführen. Sie sind reine Berechnung: Input-Warenkorbdaten → Output-Operationen. Wenn du externe Daten benötigst (ein CRM-Lookup, eine Echtzeit-Bestandsprüfung), musst du die Daten entweder vorher in Metafields speichern oder eine andere Oberfläche verwenden (App Proxy, Webhooks, Cart Transform mit Backend-Lookup). Das ist der häufigste Grund, warum Teams neu entwerfen statt nur portieren müssen.
Was ist der Unterschied zwischen Cart Transform und Discounts?
Discounts ändern Preise; Cart Transform ändert den Inhalt des Warenkorbs. Verwende die Discounts API für 10 % Rabatt, kostenlosen Versand oder BOGO. Verwende Cart Transform, um zwei Produkte zu einem Line Item zu bündeln oder eine Variante in mehrere aufzuteilen. Viele alte Scripts vermischten beide Themen — trenne sie bei der Migration in zwei Functions.
Wie teste ich eine Function lokal ohne Development Store?
Du kannst Unit-Tests mit cargo test (Rust) oder npm test (JS) ausführen, aber vollständige Integrationstests erfordern einen Development Store. Die CLI bietet shopify app function run, womit du deine Function gegen eine Beispiel-Input-Datei ausführen kannst — nützlich für schnelle Iterationen. Um das Checkout-Verhalten jedoch end-to-end zu bestätigen, brauchst du einen echten Store mit einem echten Warenkorb.
Kann ich mehrere Functions desselben Typs haben?
Ja — Shopify unterstützt mehrere Functions pro Ziel, und sie laufen in deterministischer Reihenfolge. Bei Discounts wird die Reihenfolge durch Shopify-Regeln zum Stapeln von Rabatten bestimmt. Bei Delivery- und Payment-Customizations kannst du Functions verketten, aber jede Ausgabe speist die nächste. Die meisten Teams verwenden zur Einfachheit eine Function pro Typ.
Was passiert mit meinem Script, nachdem ich die Function bereitgestellt habe?
Beide laufen parallel, bis du den Script im Apps → Script Editor unveröffentlichst. Das ist absichtlich so — es gibt dir das Testfenster für parallelen Betrieb. Nachdem du geprüft hast, dass die Function funktioniert, veröffentliche den Script manuell nicht mehr. Nach dem 30. Juni 2026 stoppen alle Scripts die Ausführung, unabhängig davon, ob du sie unveröffentlicht hast oder nicht.
Beeinflusst die Migration mein SEO oder Theme?
Nein — Functions laufen serverseitig im Checkout und berühren weder dein Theme noch Produktseiten. Sie ändern nur Rabatte, Versandoptionen und Zahlungsmethoden im Checkout. Dein Storefront, deine Produktvorlagen und dein SEO bleiben vollständig unberührt.
Wie migriere ich einen Script, der Input.line_items mit benutzerdefinierten Eigenschaften verwendet?
Benutzerdefinierte Eigenschaften sind über das attribute-Feld auf Warenkorbpositionen im GraphQL-Input zugänglich. Füge attribute(key: "your-key") { value } innerhalb der lines-Auswahl hinzu. Die Function liest sie identisch zu Scripts, die Line-Item-Properties lesen — nur über GraphQL statt über Ruby-Methodenaufrufe.
Und was ist mit Analytics und Bestell-Tags? Können Functions Daten schreiben?
Functions können keine Bestell-Tags schreiben oder selbst Webhooks auslösen — sie geben nur Operationen auf dem aktuellen Warenkorb zurück. Für Tagging oder nachgelagerte Workflows verwende Shopify Flow, ausgelöst durch das Ereignis der Bestellerstellung. Viele Händler kombinieren eine Function (für den Rabatt) mit einem Flow (um „VOLUME-DISCOUNT-APPLIED“ auf der Bestellung zu taggen).
Gibt es eine Public App, die ich installieren kann, statt eine Custom Function zu bauen?
Ja — im Shopify App Store gibt es Dutzende Apps, die Functions für gängige Anwendungsfälle verpacken. Suche nach „discount function“, „delivery customization“ oder „payment customization“. Für einfache Anwendungsfälle (Mengenrabatte, Zahlungsmethoden nach Tag ausblenden, kostenloser Versand ab X) kann dir eine bestehende App Tage an Entwicklungsarbeit sparen. Hebe dir Custom Functions für Logik auf, die wirklich einzigartig für dein Geschäft ist.
Was passiert, wenn ich die Frist am 30. Juni verpasse?
Der Script stoppt die Ausführung — es gibt keinen Fallback, keine Schonfrist und keine Verlängerung. Was auch immer der Script getan hat (der Rabatt, der ausgeblendete Versandtarif, die blockierte Zahlungsmethode) kehrt um Mitternacht UTC am 1. Juli zum Standardverhalten zurück. Wenn dein Geschäft von dieser Logik abhängt, plane, lange vor diesem Datum live zu sein. Die Migration dauert länger, als die meisten Teams schätzen, besonders mit Paritätstests.
Kann ich die Script Editor-App komplett löschen?
Du kannst sie nach dem 30. Juni 2026 deinstallieren, aber Shopify wird sie wahrscheinlich automatisch entfernen. Sobald Scripts nicht mehr ausgeführt werden, hat der Editor keinen Zweck mehr. Du kannst auch jetzt alle Scripts unveröffentlichen und die App sofort deinstallieren, wenn du die Migration abgeschlossen hast — deine Functions sind unabhängig.
Was du diese Woche tun solltest
Lies diesen Artikel nicht nur und schließe den Tab. Tue in den nächsten sieben Tagen diese vier Dinge.
1. Den Anpassungsbericht ziehen. Gehe zu Einstellungen → Checkout → Anpassungsbericht. Exportiere ihn. Das ist dein Migrations-Backlog.
2. Richte deine Entwicklungsumgebung ein. Installiere Node 18+, Shopify CLI und Rust (falls zutreffend). Bestätige, dass shopify version funktioniert. Gesamtzeit: 30 Minuten.
3. Scaffold und shippe eine winzige Function in einen Development Store. Wähle den einfachsten Script, den du hast — meist eine Regel zum Ausblenden einer Zahlungsmethode. Migriere ihn vollständig. Selbst wenn er nie in Produktion geht, hast du die Toolchain validiert.
4. Blockiere Kalenderzeit für die nächsten acht Wochen. Migrationen passieren nicht in freien Momenten zwischen Sprints. Reserviere einen wiederkehrenden Slot — zum Beispiel jeden Dienstag- und Donnerstagnachmittag — und behandle ihn wie ein Release.
Bei den Teams, die wir migrieren gesehen haben, ist das Muster immer gleich: zwei Wochen Stillstand, drei Wochen echte Arbeit, eine Woche Aufräumen. Das sind sechs Wochen. Du hast zehn. Der Puffer ist da — verbrauche ihn für Code-Review und QA, nicht dafür, den Start immer weiter aufzuschieben.
Und wenn deine Checkout-Logik einmal sortiert ist, ist der nächste große Themenblock für die meisten Teams Post-Purchase — Adressänderungen durch Kunden, Umtausche, Rabattergänzungen nach der Bestellung. Wenn das auf deiner Roadmap steht (und das sollte es, egal ob du ein hochvolumiger Plus-Betreiber oder ein CX-orientierter Advanced-Store bist), Revize ist im Shopify App Store verfügbar und funktioniert neben jeder Function, die du hier bauen wirst.
Ressourcen
Verwandte Artikel
Es ist der 16. April 2026. Gestern — der 15. April — war der Tag, an dem Shopify den Script Editor endgültig gesperrt hat. Du kannst keinen neuen Script mehr erstellen oder veröffentlichen. Die Abschaltung der Ausführung erfolgt in 75 Tagen, am 30. Juni 2026.
Wenn du Shopify-Plus-Entwickler bist — oder die Agentur, die einen Plus-Store betreut — und diese Migration in den letzten zwölf Monaten immer wieder auf den „nächsten Sprint“ verschoben hast, hast du ein Problem. Kein „wäre nett zu beheben“-Problem. Ein „dein Checkout bricht am 1. Juli um Mitternacht zusammen“-Problem. Die meisten Plus-Stores haben über die Jahre 5 bis 20 Scripts angesammelt, die unauffällig eine Rabattregel, das Ausblenden von Versandarten oder eine Zahlungsblockade antreiben, an die sich niemand mehr erinnert.
Dieser Leitfaden ist das technische Migrationshandbuch, das wir uns im Januar gewünscht hätten. Er behandelt den tatsächlichen Code — nicht nur die Strategie. Wenn du fertig gelesen hast, weißt du, wie du mit der Shopify CLI eine Function scaffoldest, die Rust- oder JavaScript-Logik für Rabatte, Lieferanpassungen und Zahlungsanpassungen schreibst, sie sicher gegen eine markierte Teilmenge deiner Kunden testest und sie ohne Beeinträchtigung deines bestehenden Checkouts in die Produktion bringst.
Lass uns die Scripts aus deinem Shop entfernen und die Functions darin aktivieren.

Kurzantwort: Scripts → Functions in 60 Sekunden
Die Migration in einem Absatz: Shopify Scripts (Ruby-Code im Script Editor, nur Plus) werden durch Shopify Functions ersetzt (WebAssembly-Module, geschrieben in Rust oder JavaScript, für alle Pläne verfügbar). Du scaffoldest eine Function mit
shopify app generate extension, schreibst einerun.graphql-Abfrage, die die benötigten Warenkorbdaten lädt, schreibst einerun.rs- oderrun.js-Datei, die Operationen zurückgibt (Rabatte, ausgeblendete Versandarten usw.), stellst dann mitshopify app deploybereit und aktivierst sie über den Admin oder eine GraphQL-Mutation. Functions laufen als kompiliertes WASM mit Latenzen unter 5 ms, funktionieren in allen Plänen und sind der einzige Anpassungsweg, den Shopify künftig unterstützt.
Was sich am 30. Juni tatsächlich ändert
Bevor wir irgendeinen Code anfassen, klären wir die Daten. Es gibt zwei davon, und beide sind wichtig.
Datum | Was passiert | Deine Maßnahme |
|---|---|---|
15. April 2026 (vergangen) | Script Editor nur noch lesbar. Keine neuen Scripts. Keine Bearbeitung bestehender Scripts. | Bestehende Scripts laufen weiter. Migriere jetzt oder friere deine Logik ein. |
30. Juni 2026 | Alle Shopify Scripts hören auf zu laufen. Punkt. | Dein Function-Ersatz muss vor diesem Datum live sein. |
Die Migration ist binär. Entweder ist deine Function bis zum 30. Juni bereitgestellt und dein Checkout funktioniert weiter, oder sie ist es nicht — und jeder betroffene Warenkorb fällt unauffällig auf Standardpreise, Standardversandtarife und alle aktivierten Zahlungsmethoden zurück. Es gibt keine Teilpunkte. Der Script läuft entweder oder er läuft nicht, und nach dem 30. Juni läuft er nicht mehr.
Tipp: Öffne in deinem Shopify-Admin
Einstellungen → Checkout → Anpassungsbericht. Dort sind alle aktiven Scripts in deinem Shop aufgelistet, was sie tun und welcher Function-Typ als Ersatz empfohlen wird. Fang dort an.
Functions vs. Scripts: Was sich tatsächlich geändert hat
Dimension | Shopify Scripts (veraltet) | Shopify Functions (Ersatz) |
|---|---|---|
Sprache | Ruby DSL (Shopify-spezifisch) | Rust, JavaScript, TypeScript |
Runtime | Sandboxed Ruby auf Shopify-Infrastruktur | WebAssembly (WASM) — Ausführung unter 5 ms |
Plan-Verfügbarkeit | Nur Plus | Alle Pläne (Custom Apps erfordern Plus; Public Apps sind offen) |
Editor | Script Editor im Admin | Lokale IDE + Shopify CLI |
Versionierung | Keine — Live-Bearbeitungen | Git-freundlich — vollständige Versionskontrolle |
Testen | Manuell im Checkout | Lokale Entwicklung mit |
Bereitstellung | Im Admin auf „Save“ klicken |
|
Ziele | Positionen, Versand, Zahlungen | Rabatte, Cart Transform, Validation, Delivery Customization, Payment Customization, Order Routing, Fulfillment Constraints, mehr |
Der architektonische Wandel ist wichtig. Scripts waren „Ruby in einem Textfeld anpassen“. Functions sind „eine echte App schreiben, sie per Versionskontrolle verwalten, lokal testen und über eine echte CI-Pipeline bereitstellen“. Das ist eine steilere Lernkurve. Es ist auch die letzte Migration, die du in absehbarer Zeit für Checkout-Logik machen wirst — Functions sind Shopifys langfristige Zusage, nicht wie sich Scripts als Zwischenlösung herausgestellt haben.
Deine Scripts dem richtigen Function-Typ zuordnen
Jeder Script, den du heute hast, passt genau zu einer Function-API. Hier ist die Lookup-Tabelle, die du an deinen Monitor heften solltest.
Alter Script-Typ | Was er tat | Neue Function-API | Function-Ziel |
|---|---|---|---|
Line Item Script | Rabatte auf bestimmte Produkte / Kunden / Warenkorbbedingungen anwenden | Cart & Checkout Discounts API |
|
Shipping Script (Rabatt) | Kostenloser / vergünstigter Versand basierend auf Warenkorbregeln | Cart & Checkout Discounts API |
|
Shipping Script (ausblenden / umbenennen / neu sortieren) | Eine Versandart über $X ausblenden, „Standard“ in „Gratis ab 50 $“ umbenennen | Delivery Customization API |
|
Payment Script | PayPal für B2B ausblenden, Nachnahme über 500 $ ausblenden, Methoden neu sortieren | Payment Customization API |
|
Cart-modifying Script (selten) | Produkte bündeln, Positionen austauschen | Cart Transform API |
|
Checkout blockierender Script | Warenkorb ablehnen, wenn die SKU-Mischung ungültig ist | Cart & Checkout Validation API |
|
Wenn du zehn Scripts hast, wirst du wahrscheinlich drei bis fünf Functions bauen — mehrere Scripts lassen sich oft zu einer Function mit saubererer Verzweigungslogik zusammenfassen.

Voraussetzung: Richte deine lokale Entwicklungsumgebung ein
Bevor du irgendeine Function scaffoldest, brauchst du lokal drei Dinge installiert. Führe diese Prüfungen in deinem Terminal aus.
1. Node.js 18+
node --version # Must be >= 18.0.0
Falls älter, installiere es über nvm oder lade es von nodejs.org herunter.
2. Shopify CLI 3+
npm install -g @shopify/cli@latest shopify version # Should output 3.x or higher
3. Rust-Toolchain (nur wenn du Functions in Rust schreiben wirst)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh rustup target add wasm32-wasip1 cargo --version
JavaScript-Functions brauchen kein Rust. Wähle eine Sprache für dein Team und bleib dabei — beides zu mischen erhöht den Wartungsaufwand.
4. Ein Development Store
Melde dich entweder im Partner-Dashboard an und erstelle einen neuen Development Store oder verwende einen bestehenden. Du stellst Functions zuerst in diesem Store bereit, bevor du sie in die Produktion überführst.
Deine erste Function scaffolden
Die CLI erledigt den größten Teil des Boilerplates. In einem beliebigen Verzeichnis:
# Create a new Shopify app (skip if you already have one) shopify app init my-checkout-functions cd my-checkout-functions # Generate a Function extension shopify app generate extension
Die CLI führt dich durch die Eingaben. Für eine Discount-Function würdest du wählen:
Typ: Function
Vorlage:
discount(odercart_checkout_validation,delivery_customization,payment_customizationusw.)Sprache: Rust oder JavaScript
Name: etwas wie
volume-discount-fn
Dadurch wird extensions/volume-discount-fn/ mit Folgendem erstellt:
extensions/volume-discount-fn/ ├── shopify.extension.toml # Function config — targets, build, version ├── src/ │ ├── cart_lines_discounts_generate_run.graphql # Input query │ └── cart_lines_discounts_generate_run.rs # Function logic ├── Cargo.toml # Rust dependencies (Rust only) └── README.md
Die drei Dateien, die du ständig bearbeiten wirst, sind die .toml (Konfiguration), die .graphql (Input) und die .rs / .js (Logik). Das ist alles.
Tutorial 1: Einen Line Item Script ersetzen (Mengenrabatt)
Angenommen, dein alter Script gewährte 10 % Rabatt auf die Bestellsumme, wenn der Warenkorb 5+ Einheiten aus einer bestimmten Kollektion enthielt. Hier ist das entsprechende Function-Pendant.
Schritt 1.1: Die Konfiguration (shopify.extension.toml)
api_version = "2026-01" [[extensions]] name = "volume-discount-fn" handle = "volume-discount-fn" type = "function" [[extensions.targeting]] target = "cart.lines.discounts.generate.run" input_query = "src/cart_lines_discounts_generate_run.graphql" export = "cart_lines_discounts_generate_run" [extensions.build] command = "cargo build --target=wasm32-wasip1 --release" path = "target/wasm32-wasip1/release/volume-discount-fn.wasm" watch = ["src/**/*.rs"]
Schritt 1.2: Die Input-Abfrage (src/cart_lines_discounts_generate_run.graphql)
query Input { cart { lines { id quantity cost { subtotalAmount { amount } } merchandise { ... on ProductVariant { product { inAnyCollection(ids: ["gid://shopify/Collection/123456789"]) } } } } } discount { discountClasses } }
Tipp: Functions sehen nur die Daten, die du abfragst. Halte GraphQL minimal — jedes Feld, das du weglässt, bedeutet eine schnellere und günstigere Ausführung.
Schritt 1.3: Die Logik (src/cart_lines_discounts_generate_run.rs)
use super::schema; use shopify_function::prelude::*; use shopify_function::Result; #[shopify_function] fn cart_lines_discounts_generate_run( input: schema::cart_lines_discounts_generate_run::Input, ) -> Result<schema::CartLinesDiscountsGenerateRunResult> { // Bail if discount class doesn't match let has_order_discount = input .discount() .discount_classes() .contains(&schema::DiscountClass::Order); if !has_order_discount { return Ok(schema::CartLinesDiscountsGenerateRunResult { operations: vec![] }); } // Sum quantities of items in the target collection let qualifying_qty: i64 = input .cart() .lines() .iter() .filter(|line| { if let schema::Merchandise::ProductVariant(v) = line.merchandise() { *v.product().in_any_collection() } else { false } }) .map(|line| *line.quantity()) .sum(); if qualifying_qty < 5 { return Ok(schema::CartLinesDiscountsGenerateRunResult { operations: vec![] }); } // Apply 10% off the order subtotal Ok(schema::CartLinesDiscountsGenerateRunResult { operations: vec![schema::CartOperation::OrderDiscountsAdd( schema::OrderDiscountsAddOperation { selection_strategy: schema::OrderDiscountSelectionStrategy::First, candidates: vec![schema::OrderDiscountCandidate { targets: vec![schema::OrderDiscountCandidateTarget::OrderSubtotal( schema::OrderSubtotalTarget { excluded_cart_line_ids: vec![], }, )], message: Some("Volume discount: 10% off".to_string()), value: schema::OrderDiscountCandidateValue::Percentage( schema::Percentage { value: Decimal(10.0) } ), conditions: None, associated_discount_code: None, }], }, )], }) }
Schritt 1.4: Testen, bereitstellen, aktivieren
# Local development with hot reload shopify app dev # When ready, deploy shopify app deploy # In the GraphiQL panel that opens (press `g` in the dev terminal), # create the automatic discount that uses your Function:
mutation { discountAutomaticAppCreate( automaticAppDiscount: { title: "Volume Discount (5+ collection items)" functionHandle: "volume-discount-fn" discountClasses: [ORDER] startsAt: "2026-04-16T00:00:00Z" } ) { automaticAppDiscount { discountId } userErrors { field message } } }
Das ist alles. Die Function ist live, versioniert und ersetzt den alten Script vollständig.
Tutorial 2: Einen Shipping Script ersetzen (Methode über Warenkorbgrenze ausblenden)
Ein häufiger Script: „Expressversand ausblenden, wenn der Warenkorbwert über 500 $ liegt, um teuren Overnight-Versand bei großen Bestellungen zu verhindern.“ Hier ist die Version als Delivery Customization Function.
Schritt 2.1: Scaffold
shopify app generate extension --template delivery_customization --name hide-express-fn
Schritt 2.2: Input-Abfrage (src/run.graphql)
query Input { cart { cost { subtotalAmount { amount } } deliveryGroups { deliveryOptions { handle title } } } }
Schritt 2.3: Logik (src/run.js — JavaScript-Variante)
// @ts-check /** * @typedef {import("../generated/api").RunInput} RunInput * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult */ const NO_CHANGES = { operations: [] }; const THRESHOLD = 500.0; const HIDE_TITLES = ["Express", "Overnight"]; /** * @param {RunInput} input * @returns {FunctionRunResult} */ export function run(input) { const subtotal = parseFloat(input.cart.cost.subtotalAmount.amount); if (subtotal < THRESHOLD) return NO_CHANGES; const operations = input.cart.deliveryGroups.flatMap((group) => group.deliveryOptions .filter((opt) => HIDE_TITLES.some((t) => opt.title.includes(t))) .map((opt) => ({ hide: { deliveryOptionHandle: opt.handle }, })) ); return { operations }; }
Schritt 2.4: Über den Admin aktivieren (keine GraphQL erforderlich)
Delivery Customizations haben eine integrierte Admin-Oberfläche. Nach shopify app deploy:
Gehe zu Einstellungen → Versand und Lieferung
Scrolle im unteren Bereich zum Abschnitt Anpassungen
Klicke auf Anpassung hinzufügen → wähle deine Function aus
Speichern
Die Regel zum Ausblenden ist in der Produktion live. Keine Mutation erforderlich.

Tutorial 3: Einen Payment Script ersetzen (Nachnahme für B2B ausblenden)
Alter Script: „Nachnahme für jeden Kunden mit dem Tag 'B2B' ausblenden.“ Hier ist die Payment Customization-Version.
Schritt 3.1: Scaffold
shopify app generate extension --template payment_customization --name hide-cod-b2b-fn
Schritt 3.2: Input-Abfrage
query Input { cart { buyerIdentity { customer { hasTags(tags: [{ tag: "B2B" }]) { tag hasTag } } } } paymentMethods { id name } }
Schritt 3.3: Logik (src/run.js)
const NO_CHANGES = { operations: [] }; export function run(input) { const tagCheck = input.cart?.buyerIdentity?.customer?.hasTags?.[0]; const isB2B = tagCheck?.hasTag === true; if (!isB2B) return NO_CHANGES; const codMethod = input.paymentMethods.find((pm) => pm.name.toLowerCase().includes("cash on delivery") ); if (!codMethod) return NO_CHANGES; return { operations: [{ hide: { paymentMethodId: codMethod.id } }], }; }
Schritt 3.4: Aktivieren
Payment Customizations haben ebenfalls eine Admin-Oberfläche unter Einstellungen → Zahlungen → Anpassungen. Gleicher Ablauf wie bei Delivery — Function auswählen, speichern, fertig.
Da du das hier liest — ein Wort zu Post-Purchase
Eine kurze Offenlegung, weil dies der Revize-Blog ist. Revize kümmert sich um die Dinge, die Functions nicht anfassen können — sobald eine Bestellung aufgegeben wurde, wollen Kunden einen Artikel hinzufügen, eine Größe tauschen, die Lieferadresse korrigieren oder einen vergessenen Rabatt anwenden. Functions sitzen im Checkout. Revize sitzt danach. Functions entscheiden, was im Warenkorb erlaubt ist; Revize gibt deinen Kunden und dem Support-Team die Möglichkeit, die Bestellung danach zu bearbeiten, ohne einen Rückerstattungs-und-Neuerstellungs-Zyklus. Das ist für zwei Arten von Shops wichtig: diejenigen mit so viel Bestellvolumen, dass manuelle Bearbeitung zusammenbricht (offensichtlich Plus-Betreiber, aber auch stark ausgelastete Advanced-Stores), und diejenigen, deren gesamte Marke auf Kundenerlebnis basiert — wo eine „Tut uns leid, das können wir nicht ändern“-E-Mail Wiederkäufe verhindert.
Wenn dein Migrationsplan Scripts → Functions abdeckt, du aber Post-Purchase-Bestelländerungen nie sauber gelöst hast, wirst du in etwa drei Wochen an die nächste „Warum ist das so schwer?“-Wand stoßen. Der gerade veröffentlichte Leitfaden zur Bestellverwaltung beschreibt den vollständigen Post-Checkout-Plan.
Zurück zur Migration.
Teststrategie: Das Muster mit markierten Kunden
Functions haben keinen „Draft-Modus“, den du im Admin umschalten kannst. Das professionelle Muster ist, die neue Function über ein Kunden-Tag zu begrenzen, den alten Script und die neue Function parallel laufen zu lassen, zu prüfen, dass sie für markierte Nutzer identische Ergebnisse liefern, und dann den Schalter umzulegen.
Schritt 1: Deine Testnutzer taggen
Füge in Kunden das Tag FN-TESTER zu zwei oder drei internen Konten hinzu.
Schritt 2: Die Function anhand des Vorhandenseins des Tags verzweigen
// At the top of your run function let is_tester = input .cart() .buyer_identity() .and_then(|bi| bi.customer()) .map(|c| c.has_any_tag()) .unwrap_or(&false); if !*is_tester { return Ok(default_result); // Fall through to existing Script } // New Function logic only runs for tagged users
Schritt 3: hasAnyTag zu deiner Input-Abfrage hinzufügen
cart { buyerIdentity { customer { hasAnyTag(tags: ["FN-TESTER"]) } } }
Schritt 4: Im Checkout verifizieren
Melde dich als markierter Nutzer an, gehe den Checkout durch und bestätige, dass die Function auslöst. Melde dich als nicht markierter Nutzer an und bestätige, dass der alte Script weiterhin läuft. Wenn die Ergebnisse einige Tage lang übereinstimmen, entferne die Tag-Prüfung und lasse die Function für alle laufen.
Schritt 5: Den alten Script unveröffentlichen
Gehe zu Apps → Script Editor → [Dein Script] → Unpublish. Sobald er unveröffentlicht ist, ist die Function die einzige Quelle der Wahrheit.
Ein Bereitstellungs-Workflow, der tatsächlich skaliert
Stelle nicht ewig von einem Entwickler-Laptop aus bereit. Sobald du ein oder zwei Scripts migriert hast, richte eine echte CI-Pipeline ein.
Der minimale praktikable Workflow
# .github/workflows/deploy-functions.yml name: Deploy Shopify Functions on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: '20' } - uses: dtolnay/rust-toolchain@stable with: { targets: wasm32-wasip1 } - run: npm install -g @shopify/cli@latest - run: shopify app deploy --force env: SHOPIFY_CLI_PARTNERS_TOKEN: ${{ secrets.SHOPIFY_CLI_PARTNERS_TOKEN }}
Erzeuge das Partner-Token im Partner-Dashboard unter Einstellungen → Tokens. Ab jetzt shippt jeder Merge auf main deine Functions. Keine Slack-Threads mehr mit „Hat Mike das bereitgestellt?“
Versionierung und Rollback
shopify app deploy erstellt einen versionierten Snapshot. Zum Zurückrollen:
shopify app versions list shopify app release --version <previous-version-id
Im Vergleich zu Scripts — bei denen Rollback bedeutete „an den alten Code denken und ihn wieder einfügen“ — ist das ein Unterschied wie Tag und Nacht.

Was die meisten Teams falsch machen
Nachdem wir Plus-Händler im letzten Jahr durch diese Migration begleitet haben, tauchen immer wieder dieselben fünf Fehler auf.
1. Functions wie einen 1:1-Script-Port behandeln. Tun sie nicht. Eine einzelne Function kann drei Scripts mit saubererer Verzweigungslogik ersetzen. Prüfe deine Scripts als System, bevor du sie neu schreibst.
2. Die Read-Scopes vergessen. Viele Functions benötigen read_customers, read_orders oder write_discounts. Füge sie in shopify.app.toml unter scopes hinzu und autorisiere die App neu, sonst gibt deine Input-Abfrage null zurück.
3. Functions für nicht markierte Kunden ohne Paritätstests ausführen. Selbst wenn dein Code richtig aussieht, werden Sonderfälle (leerer Warenkorb, Geschenkkarten, Store Credit, B2B-Entwürfe) Probleme aufzeigen. Eine markierungsbasierte Einführung kostet dich zwei Tage und erspart dir einen P1-Ausfall.
4. Den Anpassungsbericht überspringen. Er ist das beste Inventar dessen, was tatsächlich läuft. Migriere nicht aus dem Gedächtnis — migriere anhand des Berichts.
5. Collection-IDs und Kunden-Tags hart kodieren. Nutze die Function-Konfiguration über Metafields, wenn du vom Händler anpassbare Werte brauchst. Die CLI kann eine metadatenbasierte Konfiguration scaffolden — siehe Shopifys Dokumentation zur Function-Konfiguration.
Migrations-Checkliste für die nächsten 75 Tage
Ein realistischer Wochenplan, um entspannt bis zum 30. Juni zu kommen.
Woche | Maßnahme |
|---|---|
Woche 1 (diese Woche) | Den Anpassungsbericht ziehen. Jeden Script inventarisieren. Entscheiden: Function vs. Public App vs. löschen. |
Wochen 2–3 | Lokale Entwicklungsumgebung einrichten. Die erste Function scaffolden. Den einfachsten Script migrieren (meist eine Regel zum Ausblenden einer Zahlungsmethode). |
Wochen 4–6 | Discount-Scripts migrieren. Diese dauern am längsten, weil die Discounts API am umfangreichsten ist. Gründlich mit Tags testen. |
Wochen 7–8 | Shipping-/Delivery-Scripts migrieren. Delivery Customizations über den Admin aktivieren. |
Wochen 9–10 | CI-Pipeline einrichten. Alle Bereitstellungen von Entwickler-Laptops weg verlagern. |
Woche 11 (Mitte Juni) | Finale Paritätsprüfung. Alle Scripts unveröffentlichen. Den Store zwei Wochen lang nur mit Functions betreiben. |
30. Juni | Der Stichtag ist da. Nichts bricht, weil du früh fertig warst. |
Wenn du diese Woche startest, hast du Puffer. Wenn du im Juni startest, hast du keinen.

Häufig gestellte Fragen
Brauche ich Shopify Plus, um Functions zu verwenden?
Custom Functions erfordern Shopify Plus, aber Public-App-Functions funktionieren in jedem Plan. Wenn du nicht auf Plus bist, hast du zwei Wege: Installiere eine Public App aus dem Shopify App Store, die die Function für dich bereitstellt, oder upgrade auf Plus, um deine eigenen Custom Functions zu schreiben. Die meisten großen Händler, die Scripts hatten, waren ohnehin schon auf Plus, daher ändert sich in der Praxis selten etwas.
Kann ich Functions in TypeScript schreiben?
Ja — TypeScript wird vollständig unterstützt und die CLI scaffoldet es für dich. Wenn du shopify app generate extension ausführst und „JavaScript“ auswählst, enthält das generierte Projekt Typdeklarationen aus import("../generated/api"). Du kannst Dateien bei Bedarf in .ts umwandeln und eine tsconfig.json hinzufügen. Die kompilierte Ausgabe (WASM) ist unabhängig von der Quellsprache identisch.
Wie schnell sind Functions im Vergleich zu Scripts?
Functions laufen typischerweise in unter 5 ms — deutlich schneller als Ruby Scripts. Da sie in WebAssembly kompiliert werden und in einer schlanken Runtime laufen, setzt Shopify ein Ausführungsbudget von 5 ms durch. Überschreitet deine Function dieses Budget, wird die Operation verworfen und deine Function gibt keine Operationen zurück. In der Praxis benötigt eine gut geschriebene Function 1–2 ms. Die Leistungsgrenze ist wesentlich höher als bei Scripts.
Kann eine Function eine externe API aufrufen?
Nein — Functions können keine Netzwerkrequests ausführen. Sie sind reine Berechnung: Input-Warenkorbdaten → Output-Operationen. Wenn du externe Daten benötigst (ein CRM-Lookup, eine Echtzeit-Bestandsprüfung), musst du die Daten entweder vorher in Metafields speichern oder eine andere Oberfläche verwenden (App Proxy, Webhooks, Cart Transform mit Backend-Lookup). Das ist der häufigste Grund, warum Teams neu entwerfen statt nur portieren müssen.
Was ist der Unterschied zwischen Cart Transform und Discounts?
Discounts ändern Preise; Cart Transform ändert den Inhalt des Warenkorbs. Verwende die Discounts API für 10 % Rabatt, kostenlosen Versand oder BOGO. Verwende Cart Transform, um zwei Produkte zu einem Line Item zu bündeln oder eine Variante in mehrere aufzuteilen. Viele alte Scripts vermischten beide Themen — trenne sie bei der Migration in zwei Functions.
Wie teste ich eine Function lokal ohne Development Store?
Du kannst Unit-Tests mit cargo test (Rust) oder npm test (JS) ausführen, aber vollständige Integrationstests erfordern einen Development Store. Die CLI bietet shopify app function run, womit du deine Function gegen eine Beispiel-Input-Datei ausführen kannst — nützlich für schnelle Iterationen. Um das Checkout-Verhalten jedoch end-to-end zu bestätigen, brauchst du einen echten Store mit einem echten Warenkorb.
Kann ich mehrere Functions desselben Typs haben?
Ja — Shopify unterstützt mehrere Functions pro Ziel, und sie laufen in deterministischer Reihenfolge. Bei Discounts wird die Reihenfolge durch Shopify-Regeln zum Stapeln von Rabatten bestimmt. Bei Delivery- und Payment-Customizations kannst du Functions verketten, aber jede Ausgabe speist die nächste. Die meisten Teams verwenden zur Einfachheit eine Function pro Typ.
Was passiert mit meinem Script, nachdem ich die Function bereitgestellt habe?
Beide laufen parallel, bis du den Script im Apps → Script Editor unveröffentlichst. Das ist absichtlich so — es gibt dir das Testfenster für parallelen Betrieb. Nachdem du geprüft hast, dass die Function funktioniert, veröffentliche den Script manuell nicht mehr. Nach dem 30. Juni 2026 stoppen alle Scripts die Ausführung, unabhängig davon, ob du sie unveröffentlicht hast oder nicht.
Beeinflusst die Migration mein SEO oder Theme?
Nein — Functions laufen serverseitig im Checkout und berühren weder dein Theme noch Produktseiten. Sie ändern nur Rabatte, Versandoptionen und Zahlungsmethoden im Checkout. Dein Storefront, deine Produktvorlagen und dein SEO bleiben vollständig unberührt.
Wie migriere ich einen Script, der Input.line_items mit benutzerdefinierten Eigenschaften verwendet?
Benutzerdefinierte Eigenschaften sind über das attribute-Feld auf Warenkorbpositionen im GraphQL-Input zugänglich. Füge attribute(key: "your-key") { value } innerhalb der lines-Auswahl hinzu. Die Function liest sie identisch zu Scripts, die Line-Item-Properties lesen — nur über GraphQL statt über Ruby-Methodenaufrufe.
Und was ist mit Analytics und Bestell-Tags? Können Functions Daten schreiben?
Functions können keine Bestell-Tags schreiben oder selbst Webhooks auslösen — sie geben nur Operationen auf dem aktuellen Warenkorb zurück. Für Tagging oder nachgelagerte Workflows verwende Shopify Flow, ausgelöst durch das Ereignis der Bestellerstellung. Viele Händler kombinieren eine Function (für den Rabatt) mit einem Flow (um „VOLUME-DISCOUNT-APPLIED“ auf der Bestellung zu taggen).
Gibt es eine Public App, die ich installieren kann, statt eine Custom Function zu bauen?
Ja — im Shopify App Store gibt es Dutzende Apps, die Functions für gängige Anwendungsfälle verpacken. Suche nach „discount function“, „delivery customization“ oder „payment customization“. Für einfache Anwendungsfälle (Mengenrabatte, Zahlungsmethoden nach Tag ausblenden, kostenloser Versand ab X) kann dir eine bestehende App Tage an Entwicklungsarbeit sparen. Hebe dir Custom Functions für Logik auf, die wirklich einzigartig für dein Geschäft ist.
Was passiert, wenn ich die Frist am 30. Juni verpasse?
Der Script stoppt die Ausführung — es gibt keinen Fallback, keine Schonfrist und keine Verlängerung. Was auch immer der Script getan hat (der Rabatt, der ausgeblendete Versandtarif, die blockierte Zahlungsmethode) kehrt um Mitternacht UTC am 1. Juli zum Standardverhalten zurück. Wenn dein Geschäft von dieser Logik abhängt, plane, lange vor diesem Datum live zu sein. Die Migration dauert länger, als die meisten Teams schätzen, besonders mit Paritätstests.
Kann ich die Script Editor-App komplett löschen?
Du kannst sie nach dem 30. Juni 2026 deinstallieren, aber Shopify wird sie wahrscheinlich automatisch entfernen. Sobald Scripts nicht mehr ausgeführt werden, hat der Editor keinen Zweck mehr. Du kannst auch jetzt alle Scripts unveröffentlichen und die App sofort deinstallieren, wenn du die Migration abgeschlossen hast — deine Functions sind unabhängig.
Was du diese Woche tun solltest
Lies diesen Artikel nicht nur und schließe den Tab. Tue in den nächsten sieben Tagen diese vier Dinge.
1. Den Anpassungsbericht ziehen. Gehe zu Einstellungen → Checkout → Anpassungsbericht. Exportiere ihn. Das ist dein Migrations-Backlog.
2. Richte deine Entwicklungsumgebung ein. Installiere Node 18+, Shopify CLI und Rust (falls zutreffend). Bestätige, dass shopify version funktioniert. Gesamtzeit: 30 Minuten.
3. Scaffold und shippe eine winzige Function in einen Development Store. Wähle den einfachsten Script, den du hast — meist eine Regel zum Ausblenden einer Zahlungsmethode. Migriere ihn vollständig. Selbst wenn er nie in Produktion geht, hast du die Toolchain validiert.
4. Blockiere Kalenderzeit für die nächsten acht Wochen. Migrationen passieren nicht in freien Momenten zwischen Sprints. Reserviere einen wiederkehrenden Slot — zum Beispiel jeden Dienstag- und Donnerstagnachmittag — und behandle ihn wie ein Release.
Bei den Teams, die wir migrieren gesehen haben, ist das Muster immer gleich: zwei Wochen Stillstand, drei Wochen echte Arbeit, eine Woche Aufräumen. Das sind sechs Wochen. Du hast zehn. Der Puffer ist da — verbrauche ihn für Code-Review und QA, nicht dafür, den Start immer weiter aufzuschieben.
Und wenn deine Checkout-Logik einmal sortiert ist, ist der nächste große Themenblock für die meisten Teams Post-Purchase — Adressänderungen durch Kunden, Umtausche, Rabattergänzungen nach der Bestellung. Wenn das auf deiner Roadmap steht (und das sollte es, egal ob du ein hochvolumiger Plus-Betreiber oder ein CX-orientierter Advanced-Store bist), Revize ist im Shopify App Store verfügbar und funktioniert neben jeder Function, die du hier bauen wirst.
Ressourcen
Verwandte Artikel
Überarbeiten Sie Ihren Shopify-Shop. Setzen Sie auf ein herausragendes Kundenerlebnis.
© Copyright 2024, Alle Rechte vorbehalten
Überarbeiten Sie Ihren Shopify-Shop. Setzen Sie auf ein herausragendes Kundenerlebnis.
© Copyright 2024, Alle Rechte vorbehalten
Überarbeiten Sie Ihren Shopify-Shop. Setzen Sie auf ein herausragendes Kundenerlebnis.
© Copyright 2024, Alle Rechte vorbehalten
Überarbeiten Sie Ihren Shopify-Shop. Setzen Sie auf ein herausragendes Kundenerlebnis.
© Copyright 2024, Alle Rechte vorbehalten



