Migration von Shopify Scripts zu Functions: Code-Tutorial 2026
Migration von Shopify Scripts zu Functions: Code-Tutorial 2026
Migration von Shopify Scripts zu Functions: Code-Tutorial 2026

Es ist der 16. April 2026. Gestern – am 15. April – hat Shopify den Script Editor endgültig gesperrt. Sie können keine neuen Scripts mehr erstellen oder veröffentlichen. Die vollständige Abschaltung erfolgt in 75 Tagen, am 30. Juni 2026.
Wenn Sie ein Shopify Plus-Entwickler oder die betreuende Agentur eines Plus-Shops sind und diese Migration in den letzten zwölf Monaten immer wieder in den "nächsten Sprint" verschoben haben, haben Sie ein Problem. Kein kosmetisches Problem, sondern ein Problem der Kategorie „Ihr Checkout bricht am 1. Juli um Mitternacht zusammen“. Die meisten Plus-Shops haben über die Jahre 5 bis 20 Scripts angesammelt, von denen jedes im Stillen eine Rabattregel, das Ausblenden einer Versandart oder eine Zahlungsmethode steuert, an deren Implementierung 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. Sobald Sie diesen Artikel gelesen haben, wissen Sie, wie Sie eine Function mit der Shopify CLI aufsetzen, die Rust- oder JavaScript-Logik für Rabatte, Delivery Customizations und Payment Customizations schreiben, diese sicher an einer ausgewählten Kundengruppe testen und in die Produktivumgebung ausrollen, ohne Ihren bestehenden Checkout zu gefährden.
Lassen Sie uns die Scripts aus Ihrem Shop entfernen und durch Functions ersetzen.

Schnelle Antwort: Scripts → Functions in 60 Sekunden
Die Migration in einem Absatz: Shopify Scripts (Ruby-Code im Script Editor, nur für Plus) werden durch Shopify Functions ersetzt (WebAssembly-Module, geschrieben in Rust oder JavaScript, verfügbar für alle Tarife). Sie erstellen eine Function mit
shopify app generate extension, definieren einerun.graphql-Abfrage, um die benötigten Warenkorbdaten abzurufen, schreiben einerun.rs- oderrun.js-Datei, die Werte (Rabatte, ausgeblendete Versandoptionen etc.) zurückgibt, deployen das Ganze mitshopify app deployund aktivieren es über den Admin-Bereich oder eine GraphQL-Mutation. Functions werden als kompilierte WASM in weniger als 5 ms ausgeführt, laufen in jedem Tarif und sind der einzige Weg für Anpassungen, den Shopify künftig unterstützt.
Was sich am 30. Juni tatsächlich ändert
Bevor wir Code anfassen, müssen die Termine klar sein. Es gibt zwei wichtige Daten, und beide sind entscheidend.
Datum | Was passiert | Ihre Action |
|---|---|---|
15. April 2026 (vergangen) | Script Editor ist schreibgeschützt. Keine neuen Scripts. Keine Bearbeitung bestehender Scripts. | Bestehende Scripts laufen noch. Jetzt migrieren oder Logik einfrieren. |
30. Juni 2026 | Alle Shopify Scripts stopped die Ausführung. Ohne Ausnahme. | Ihre Ersatz-Function muss vor diesem Datum live sein. |
Die Migration ist binär. Entweder ist Ihre Function bis zum 30. Juni deployed und Ihr Checkout funktioniert weiterhin, oder sie ist es nicht – und jeder betroffene Warenkorb fällt geräuschlos auf Standardpreise, Standardversandtarife und alle aktivierten Zahlungsmethoden zurück. Es gibt keine halben Sachen. Das Script läuft oder es läuft nicht, und nach dem 30. Juni läuft es definitiv nicht mehr.
Tipp: Öffnen Sie
Settings → Checkout → Customizations Reportin Ihrem Shopify-Adminbereich. Dort finden Sie jedes aktive Script Ihres Shops, dessen Funktion und den empfohlenen Ersatz-Function-Typ. Starten Sie dort.
Functions vs. Scripts: Was sich wirklich geändert hat
Dimension | Shopify Scripts (deprecated) | Shopify Functions (Ersatz) |
|---|---|---|
Sprache | Ruby DSL (Shopify-spezifisch) | Rust, JavaScript, TypeScript |
Runtime | Sandboxed Ruby auf Shopify-Infrastruktur | WebAssembly (WASM) — unter 5 ms Ausführungszeit |
Verfügbarkeit | Nur Plus-Tarif | Alle Tarife (Custom Apps erfordern Plus; Public Apps sind offen) |
Editor | Script Editor im Admin-Bereich | Lokale IDE + Shopify CLI |
Versionsverwaltung | Keine — Live-Edits | Git-friendly — vollständige Versionskontrolle |
Testen | Manuell im Checkout | Lokale Entwicklung mit |
Deployment | Klick auf "Speichern" im Admin-Bereich |
|
Ziele (Targets) | Line Items, Versand, Zahlungen | Discounts, Cart Transform, Validation, Delivery Customization, Payment Customization, Order Routing, Fulfillment Constraints, u.a. |
Der architektonische Wechsel ist gravierend. Scripts bedeuteten: "Ruby in einer Textarea anpassen." Functions bedeuten: "Eine echte App schreiben, versionieren, lokal testen und über eine CI-Pipeline deployen." Die Lernkurve ist steiler. Aber es ist auch die letzte Migration für Checkout-Logik auf absehbare Zeit – Functions sind Shopifys langfristiger Standard, keine Übergangslösung wie die Scripts.
Scripts dem richtigen Function-Typ zuordnen
Jedes Ihrer aktuellen Scripts lässt sich genau einer Function API zuordnen. Nutzen Sie diese Referenztabelle für Ihre Planung.
Alter Script-Typ | Funktionsweise | Neue Function API | Function Target |
|---|---|---|---|
Line Item Script | Rabatte auf bestimmte Produkte / Kunden / Warenkorb-Bedingungen anwenden | Cart & Checkout Discounts API |
|
Shipping Script (Rabatt) | Kostenloser / rabattierter Versand basierend auf Warenkorbregeln | Cart & Checkout Discounts API |
|
Shipping Script (Ausblenden / Umbenennen / Sortieren) | Versandart ab Wert X ausblenden, "Standard" in "Kostenlos ab 50 €" umbenennen | Delivery Customization API |
|
Payment Script | PayPal für B2B ausblenden, Nachnahme ab 500 € sperren, Reihenfolge ändern | Payment Customization API |
|
Cart-modifying Script (selten) | Produkte bündeln, Line Items austauschen | Cart Transform API |
|
Block-checkout Script | Warenkorb ablehnen, wenn SKU-Kombination ungültig | Cart & Checkout Validation API |
|
Wenn Sie zehn Scripts im Einsatz haben, werden Sie wahrscheinlich drei bis fünf Functions bauen – oft lassen sich mehrere Scripts in einer einzigen Function mit sauberer Bedingungslogik zusammenführen.

Voraussetzung: Lokale Entwicklungsumgebung einrichten
Bevor Sie eine Function erstellen, müssen drei Tools lokal installiert sein. Überprüfen Sie dies im Terminal.
1. Node.js 18+
node --version # Muss >= 18.0.0 sein
node --version # Muss >= 18.0.0 sein
Falls älter, über nvm aktualisieren oder von nodejs.org herunterladen.
2. Shopify CLI 3+
npm install -g @shopify/cli@latest shopify version # Sollte 3.x oder höher ausgeben
npm install -g @shopify/cli@latest shopify version # Sollte 3.x oder höher ausgeben
3. Rust Toolchain (nur wenn Sie Functions in Rust schreiben)
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 benötigen kein Rust. Wählen Sie eine Sprache für Ihr Team – ein Mix erhöht den Wartungsaufwand.
4. Ein Development-Shop
Loggen Sie sich in Ihr Partner-Dashboard ein und erstellen Sie einen Development-Shop oder nutzen Sie einen bestehenden. Hier testen Sie die Functions vor dem Go-live.
Ihre erste Function erstellen
Die CLI übernimmt das Scaffolding. In einem beliebigen Verzeichnis ausführen:
# Neue Shopify App erstellen (überspringen, falls bereits vorhanden) shopify app init my-checkout-functions cd my-checkout-functions # Function-Extension generieren shopify app generate extension
# Neue Shopify App erstellen (überspringen, falls bereits vorhanden) shopify app init my-checkout-functions cd my-checkout-functions # Function-Extension generieren shopify app generate extension
Folgen Sie den Prompts der CLI. Für eine Discount-Function wählen Sie:
Typ: Function
Template:
discount(odercart_checkout_validation,delivery_customization,payment_customizationetc.)Sprache: Rust oder JavaScript
Name: z. B.
volume-discount-fn
Dies erstellt das Verzeichnis extensions/volume-discount-fn/ mit:
extensions/volume-discount-fn/ ├── shopify.extension.toml # Konfiguration der Function (Targets, Build, Version) ├── src/ │ ├── cart_lines_discounts_generate_run.graphql # Input Query │ └── cart_lines_discounts_generate_run.rs # Logik der Function ├── Cargo.toml # Rust-Abhängigkeiten (nur bei Rust) └── README.md
extensions/volume-discount-fn/ ├── shopify.extension.toml # Konfiguration der Function (Targets, Build, Version) ├── src/ │ ├── cart_lines_discounts_generate_run.graphql # Input Query │ └── cart_lines_discounts_generate_run.rs # Logik der Function ├── Cargo.toml # Rust-Abhängigkeiten (nur bei Rust) └── README.md
Sie arbeiten primär in der .toml- (Konfiguration), der .graphql- (Input) und der .rs / .js-Datei (Logik).
Tutorial 1: Line Item Script ersetzen (Mengenrabatt)
Szenario: Das alte Script gewährt 10 % Rabatt auf den gesamten Warenkorb, sobald dieser 5 oder mehr Artikel aus einer bestimmten Collection enthält. Hier ist das Äquivalent als Function.
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 Sie explizit abfragen. Halten Sie die GraphQL-Query minimal – jedes weggelassene Feld sorgt für eine schnellere 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> { // Abbrechen, wenn Discount-Klasse nicht übereinstimmt let has_order_discount = input .discount() .discount_classes() .contains(&schema::DiscountClass::Order); if !has_order_discount { return Ok(schema::CartLinesDiscountsGenerateRunResult { operations: vec![] }); } // Summiere die Mengen der Artikel aus der Ziel-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![] }); } // 10 % Rabatt auf die Zwischensumme anwenden 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> { // Abbrechen, wenn Discount-Klasse nicht übereinstimmt let has_order_discount = input .discount() .discount_classes() .contains(&schema::DiscountClass::Order); if !has_order_discount { return Ok(schema::CartLinesDiscountsGenerateRunResult { operations: vec![] }); } // Summiere die Mengen der Artikel aus der Ziel-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![] }); } // 10 % Rabatt auf die Zwischensumme anwenden 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, Deployen, Aktivieren
# Lokale Entwicklung mit Hot-Reload shopify app dev # Wenn bereit, deployen shopify app deploy # In der sich öffnenden GraphiQL-Konsole (Taste `g` im Dev-Terminal drücken), # erstellen Sie den automatischen Rabatt, der Ihre Function nutzt:
# Lokale Entwicklung mit Hot-Reload shopify app dev # Wenn bereit, deployen shopify app deploy # In der sich öffnenden GraphiQL-Konsole (Taste `g` im Dev-Terminal drücken), # erstellen Sie den automatischen Rabatt, der Ihre Function nutzt:
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 das alte Script vollständig.
Tutorial 2: Shipping Script ersetzen (Expressversand ab Schwellenwert ausblenden)
Szenario: "Blende Expressversand aus, wenn die Zwischensumme im Warenkorb über 500 $ liegt, um teure Sendungen bei großen Bestellungen zu vermeiden." Hier ist die Umsetzung mit der Delivery Customization Function.
Schritt 2.1: Scaffolding
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: Aktivierung über den Admin-Bereich (kein GraphQL erforderlich)
Delivery Customizations verfügen über eine integrierte Admin-Benutzeroberfläche. Nach dem Ausführen von shopify app deploy:
Gehen Sie zu Settings → Shipping and delivery
Scrollen Sie nach unten zum Bereich Customizations
Klicken Sie auf Add customization → wählen Sie Ihre Function aus
Speichern
Die Regel ist live in der Produktivumgebung. Keine Mutation erforderlich.

Tutorial 3: Payment Script ersetzen (Nachnahme für B2B ausblenden)
Szenario: "Blende die Zahlungsmethode Nachnahme (Cash on Delivery) für alle Kunden mit dem Tag 'B2B' aus." Hier ist die Version als Payment Customization.
Schritt 3.1: Scaffolding
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 Settings → Payments → Customizations. Gleicher Ablauf wie bei den Versandoptionen: Function auswählen, speichern, fertig.
Ein Wort zu Post-Purchase-Anpassungen
Ein kurzer Hinweis, da Sie dies im Blog von Revize lesen. Revize übernimmt dort, wo Functions nicht hinkommen: Nach der Bestellung möchten Kunden oft Artikel hinzufügen, Größen ändern, Lieferadressen korrigieren oder vergessene Rabatte geltend machen. Functions steuern den Checkout. Revize greift danach. Während Functions festlegen, was im Warenkorb erlaubt ist, ermöglicht Revize Ihren Kunden und Ihrem Support-Team, Bestellungen nachträglich zu bearbeiten, ohne den gesamten Prozess stornieren und neu aufsetzen zu müssen. Das ist besonders für zwei Arten von Shops wichtig: diejenigen mit hohem Bestellvolumen, bei denen die manuelle Bearbeitung scheitert (Plus-Betreiber), und Marken, die sich über exzellenten Kundenservice definieren.
Wenn Ihr Migrationsplan zwar Scripts → Functions abdeckt, Sie aber nachträgliche Bestelländerungen noch nicht gelöst haben, werden Sie in kurzer Zeit vor der nächsten Herausforderung stehen. Unser neu veröffentlichter Leitfaden zum Order Management beschreibt den optimalen Post-Checkout-Workflow im Detail.
Zurück zur Migration.
Teststrategie: Die Methode mit Kunden-Tags
Functions bieten keinen "Entwurfsmodus" im Admin-Bereich. Der professionelle Weg ist, die neue Function zunächst über ein Kunden-Tag einzuschränken. Sie lassen das alte Script und die neue Function parallel laufen, vergleichen die Ergebnisse für getaggte Testkunden und schalten das Script erst ab, wenn alles identisch läuft.
Schritt 1: Testkunden taggen
Fügen Sie unter Customers zwei oder drei internen Konten das Tag FN-TESTER hinzu.
Schritt 2: Function auf Tag-Präsenz prüfen lassen
// Am Anfang der 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); // Altes Script weiterlaufen lassen } // Neue Logik wird nur für Testkunden ausgeführt
// Am Anfang der 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); // Altes Script weiterlaufen lassen } // Neue Logik wird nur für Testkunden ausgeführt
Schritt 3: hasAnyTag zur Input-Abfrage hinzufügen
cart { buyerIdentity { customer { hasAnyTag(tags: ["FN-TESTER"]) } } }
cart { buyerIdentity { customer { hasAnyTag(tags: ["FN-TESTER"]) } } }
Schritt 4: Im Checkout verifizieren
Melden Sie sich mit einem Testkonto an und prüfen Sie, ob die Function greift. Melden Sie sich mit einem untagged Konto an und stellen Sie sicher, dass das alte Script wie gewohnt ausgeführt wird. Wenn das System über einige Tage stabil läuft, entfernen Sie die Tag-Prüfung und aktivieren die Function für alle Kunden.
Schritt 5: Altes Script deaktivieren
Gehen Sie zu Apps → Script Editor → [Ihr Script] → Unpublish. Sobald es deaktiviert ist, steuert die Function die Logik exklusiv.
Ein Deployment-Workflow, der skalierbar ist
Führen Sie Deployments nicht dauerhaft vom Entwickler-Laptop aus. Richten Sie nach den ersten erfolgreichen Migrationen eine CI-Pipeline ein.
Der minimale CI/CD-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 }}
Generieren Sie den CLI-Token in Ihrem Partner-Dashboard unter Settings → Tokens. Damit deployt jeder Merge auf main Ihre Functions automatisch.
Versionierung und Rollback
shopify app deploy erstellt versionierte Snapshots. Für einen Rollback:
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 ein Rollback aus dem Zurückkopieren von altem Code bestand – ist dies ein massiver Fortschritt.

Die häufigsten Fehler im Migrationsprozess
In der Begleitung von Shopify Plus-Händlern im vergangenen Jahr sind uns immer wieder dieselben Fehler aufgefallen.
1. 1:1-Portierung von Scripts erzwingen. Das ist der falsche Ansatz. Eine einzige Function kann oft mehrere Einzelscripts ersetzen. Analysieren Sie Ihre bestehende Logik ganzheitlich vor dem Neuschreiben.
2. Fehlende API-Berechtigungen (Scopes). Viele Functions benötigen Berechtigungen wie read_customers, read_orders oder write_discounts. Diese müssen in der shopify.app.toml unter scopes definiert und die App neu autorisiert werden, andernfalls liefert die GraphQL-Abfrage Nullwerte.
3. Aktivierung ohne kontrollierte Testphase. Selbst bei sauberem Code können Edge Cases (Geschenkkarten, B2B-Skonti, Teillagerbestände) Probleme verursachen. Ein tag-basierter Rollout kostet zwei Tage Sicherheit, schützt aber vor Umsatzausfällen.
4. Ignorieren des Customizations Report. Dieser Bericht liefert das exakte Inventar Ihrer aktiven Anpassungen. Migrieren Sie strikt auf Basis dieses Reports, statt sich auf das Gedächtnis zu verlassen.
5. Statische ID-Zuweisung. Nutzen Sie Metafields für die Konfiguration Ihrer Functions, wenn Werte (wie Collection-IDs oder Kunden-Tags) für Redakteure änderbar sein müssen. Die CLI unterstützt Metafield-basierte Konfigurationen von Haus aus.
Migrationsplan für die kommenden 75 Tage
Ein realistischer Fahrplan, um den 30. Juni stressfrei zu erreichen.
Woche | Aufgabe |
|---|---|
Woche 1 (Diese Woche) | Holen Sie den Customizations Report. Analysieren Sie jedes Script. Entscheiden Sie: Custom Function, Public App oder Löschen. |
Wochen 2–3 | Lokale Entwicklungsumgebung einrichten. Erste Test-Function erstellen. Migrieren Sie die einfachste Logik (z. B. Bezahlmethode ausblenden). |
Wochen 4–6 | Rabatt-Scripts migrieren. Planen Sie hierfür die meiste Zeit ein, da die Discounts API die komplexeste ist. Ausführlich mit Test-Tags prüfen. |
Wochen 7–8 | Versand-Scripts migrieren. Steuern Sie Delivery Customizations über das Admin-Interface an. |
Wochen 9–10 | CI/CD-Pipeline aufsetzen. Automatisieren Sie die Deployments. |
Woche 11 (Mitte Juni) | Letzte Kontrollen. Deaktivieren Sie alle alten Scripts. Betreiben Sie den Shop zwei Wochen ausschließlich mit Functions. |
30. Juni | Tag der Abschaltung. Ihr Checkout läuft stabil weiter, da die Migration abgeschlossen ist. |
Wer jetzt startet, behält einen Puffer. Wer im Juni beginnt, riskiert Ausfälle.

Häufig gestellte Fragen (FAQ)
Benötige ich Shopify Plus, um Functions zu nutzen?
Eigene, maßgeschneiderte Functions erfordern Shopify Plus. Functions über öffentliche Apps (Public Apps) laufen hingegen auf allen Tarifen. Wer nicht auf Plus ist, kann entweder passende Apps aus dem App Store nutzen oder auf Plus upgraden, um eigenen Code zu schreiben. Da die meisten betroffenen Betriebe mit Scripts ohnehin Plus-Kunden sind, ändert sich in der Praxis meist nichts.
Kann ich Functions in TypeScript schreiben?
Ja – TypeScript wird vollständig unterstützt und direkt von der CLI vorbereitet. Wenn Sie sich beim Ausführen von shopify app generate extension für "JavaScript" entscheiden, liefert das Projekt passende Typdefinitionen aus import("../generated/api") mit. Dateiendungen können problemlos in .ts geändert und eine tsconfig.json hinzugefügt werden.
Wie schnell sind Functions im Vergleich zu Scripts?
Functions laufen in der Regel unter 5 ms – deutlich schneller als Ruby-Scripts. Aufgrund der Kompilierung zu WebAssembly gibt Shopify ein striktes Limit von 5 ms vor. Wird dieses Budget überschritten, bricht die Ausführung ab und es werden keine Änderungen angewendet. Gut geschriebene JavaScript- oder Rust-Functions benötigen meist nur 1–2 ms.
Können Functions externe Schnittstellen (APIs) ansprechen?
Nein – Functions haben keinen Netzwerkzugriff. Es handelt sich um reine Berechnungsmodule: Daten rein (Warenkorb via GraphQL) → Operationen raus. Benötigen Sie externe Daten (z. B. CRM-Abfragen oder Echtzeit-Bestände), müssen diese vorab über Metafields gespeichert werden oder andere Hooks genutzt werden (wie App Proxies, Webhooks oder Cart Transform mit Backend-Abfrage). Dies erfordert oft ein teilweises Redesign der Logik.
Was unterscheidet Cart Transform von Discounts?
Discounts verändern Preise; Cart Transform verändert Warenkorbeinhalte. Nutzen Sie die Discounts API für Preisnachlässe oder Bundles. Cart Transform dient dazu, Produkte zu bündeln oder Varianten aufzuteilen. Alte Scripts vermischten diese Logik oft. Trennen Sie diese bei der Migration sauber auf.
Wie teste ich eine Function lokal ohne Development-Shop?
Unittests lassen sich über cargo test (Rust) oder npm test (JS) ausführen, für vollständige Integrationstests ist jedoch ein Shop erforderlich. Mit dem Befehl shopify app function run können Sie die Function gegen Testdateien laufen lassen, was die Entwicklung beschleunigt. Das tatsächliche Checkout-Verhalten lässt sich aber nur über einen echten Warenkorb prüfen.
Kann ich mehrere Functions desselben Typs nutzen?
Ja – Shopify erlaubt mehrere Functions pro Target, die nacheinander ausgeführt werden. Bei Rabatten steuert Shopify die Reihenfolge über die Kombinationsregeln. Bei Versand- und Zahlungsanpassungen fließen die Ausgaben einer Function in die nächste ein. Für die Wartbarkeit empfiehlt sich jedoch ein fokussiertes Setup.
Was passiert mit meinem aktiven Script nach dem Deploy der Function?
Nichts, beide laufen parallel, bis Sie das Script im Script Editor deaktivieren. Das ist gewollt, um direkten Abgleich und Paritätstests zu ermöglichen. Deaktivieren Sie das Script manuell, sobald die Function fehlerfrei läuft. Ab dem 1. Juli 2026 werden Scripts serverseitig generell blockiert.
Hat die Migration Auswirkungen auf mein SEO oder mein Theme?
Nein – Functions laufen serverseitig direkt im Checkout-Prozess und berühren weder das Theme noch Produktseiten.
Sie beeinträchtigen weder das Frontend noch die SEO-Struktur.
Wie migriere ich Scripts, die auf zusätzliche Eigenschaften (Custom Properties) in `Input.line_items` zugreifen?
Eigenschaften von Positionen sind über das Feld attribute im GraphQL-Input der Warenkorbzeilen zugänglich. Fragen Sie attribute(key: "your-key") { value } innerhalb der lines-Selektion ab. Die Daten werden ähnlich ausgelesen wie früher bei den Line Item Properties – nur eben per GraphQL statt Ruby.
Können Functions Analytics-Daten oder Tags an Bestellungen schreiben?
Nein – Functions können keine Tags schreiben oder Webhooks auslösen. Sie modifizieren ausschließlich den aktuellen Checkout-Zustand. Nutzen Sie für nachgelagerte Logik Shopify Flow, getriggert durch die Bestellerstellung (Order Created). Häufig wird eine Function (für den Rabatt) mit einem Flow (für das Tagging der Bestellung) kombiniert.
Gibt es fertige Apps im App Store als Alternative zur Eigenentwicklung?
Ja – im Shopify App Store finden sich zahlreiche fertige Lösungen, die Functions für Standard-Szenarien bereitstellen. Suchen Sie nach Begriffen wie "Discount Function" oder "Delivery Customization". Für einfache Rabattregeln oder das Ausblenden von Versand- und Zahlungsarten nach Tags spart Ihnen eine fertige App viel Entwicklungszeit.
Was passiert, wenn ich die Deadline am 30. Juni verpasse?
Die Ausführung der alten Scripts bricht ersatzlos ab – es gibt keine Kulanzzeit und keine Fristverlängerung. Alle betroffenen Workflows fallen sofort auf das Standardverhalten zurück. Planen Sie den Übergang rechtzeitig ein, da vor allem die Testphase oft unterschätzt wird.
Kann ich den Script Editor nach der Migration deinstallieren?
Ja – die App wird nach dem 30. Juni ohnehin hinfällig. Sie können die Deinstallation direkt nach erfolgreichem Funktionswechsel vornehmen. Eigene Functions laufen vollständig autark.
Ausstehende To-Dos für diese Woche
Beginnen Sie direkt mit der Umsetzung und planen Sie die ersten Schritte für die nächsten sieben Tage ein.
1. Customizations Report prüfen. Laden Sie den Bericht unter Settings → Checkout → Customizations Report herunter. Das ist Ihre primäre Arbeitsliste für die Migration.
2. Lokale Toolchain vorbereiten. Installieren Sie Node 18, Shopify CLI und optional Rust. Überprüfen Sie das Setup mit shopify version.
3. Eine einfache Test-Function deployen. Beginnen Sie mit einem unkomplizierten Anwendungsfall, etwa dem Ausblenden einer Zahlungsart. Machen Sie sich mit dem gesamten Deploy-Prozess auf einem Dev-Shop vertraut.
4. Ressourcen für die nächsten Wochen sichern. Die Migration lässt sich nicht nebenbei erledigen. Blocken Sie feste Zeiten in den Sprints für die Teams, um eine termingerechte Fertigstellung zu gewährleisten.
Erfahrungswerte zeigen: Nach einer kurzen Einarbeitung und der initialen Logik-Portierung nimmt die Qualitätssicherung und Fehlerbehebung in der Praxis meist die meiste Zeit in Anspruch. Ein rechtzeitiger Start verhindert Engpässe vor der Deadline.
Sobald Ihre Checkout-Prozesse laufen, stehen meist Optimierungen nach dem Kauf an – Adressänderungen, Produktwechsel oder nachträgliche Rabattaktionen. Wenn Sie solche Anforderungen umsetzen wollen, steht Ihnen Revize im Shopify App Store zur Verfügung und arbeitet nahtlos mit Ihren neu erstellten Functions zusammen.
Ressourcen
Ähnliche Artikel
Es ist der 16. April 2026. Gestern – am 15. April – hat Shopify den Script Editor endgültig gesperrt. Sie können keine neuen Scripts mehr erstellen oder veröffentlichen. Die vollständige Abschaltung erfolgt in 75 Tagen, am 30. Juni 2026.
Wenn Sie ein Shopify Plus-Entwickler oder die betreuende Agentur eines Plus-Shops sind und diese Migration in den letzten zwölf Monaten immer wieder in den "nächsten Sprint" verschoben haben, haben Sie ein Problem. Kein kosmetisches Problem, sondern ein Problem der Kategorie „Ihr Checkout bricht am 1. Juli um Mitternacht zusammen“. Die meisten Plus-Shops haben über die Jahre 5 bis 20 Scripts angesammelt, von denen jedes im Stillen eine Rabattregel, das Ausblenden einer Versandart oder eine Zahlungsmethode steuert, an deren Implementierung 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. Sobald Sie diesen Artikel gelesen haben, wissen Sie, wie Sie eine Function mit der Shopify CLI aufsetzen, die Rust- oder JavaScript-Logik für Rabatte, Delivery Customizations und Payment Customizations schreiben, diese sicher an einer ausgewählten Kundengruppe testen und in die Produktivumgebung ausrollen, ohne Ihren bestehenden Checkout zu gefährden.
Lassen Sie uns die Scripts aus Ihrem Shop entfernen und durch Functions ersetzen.

Schnelle Antwort: Scripts → Functions in 60 Sekunden
Die Migration in einem Absatz: Shopify Scripts (Ruby-Code im Script Editor, nur für Plus) werden durch Shopify Functions ersetzt (WebAssembly-Module, geschrieben in Rust oder JavaScript, verfügbar für alle Tarife). Sie erstellen eine Function mit
shopify app generate extension, definieren einerun.graphql-Abfrage, um die benötigten Warenkorbdaten abzurufen, schreiben einerun.rs- oderrun.js-Datei, die Werte (Rabatte, ausgeblendete Versandoptionen etc.) zurückgibt, deployen das Ganze mitshopify app deployund aktivieren es über den Admin-Bereich oder eine GraphQL-Mutation. Functions werden als kompilierte WASM in weniger als 5 ms ausgeführt, laufen in jedem Tarif und sind der einzige Weg für Anpassungen, den Shopify künftig unterstützt.
Was sich am 30. Juni tatsächlich ändert
Bevor wir Code anfassen, müssen die Termine klar sein. Es gibt zwei wichtige Daten, und beide sind entscheidend.
Datum | Was passiert | Ihre Action |
|---|---|---|
15. April 2026 (vergangen) | Script Editor ist schreibgeschützt. Keine neuen Scripts. Keine Bearbeitung bestehender Scripts. | Bestehende Scripts laufen noch. Jetzt migrieren oder Logik einfrieren. |
30. Juni 2026 | Alle Shopify Scripts stopped die Ausführung. Ohne Ausnahme. | Ihre Ersatz-Function muss vor diesem Datum live sein. |
Die Migration ist binär. Entweder ist Ihre Function bis zum 30. Juni deployed und Ihr Checkout funktioniert weiterhin, oder sie ist es nicht – und jeder betroffene Warenkorb fällt geräuschlos auf Standardpreise, Standardversandtarife und alle aktivierten Zahlungsmethoden zurück. Es gibt keine halben Sachen. Das Script läuft oder es läuft nicht, und nach dem 30. Juni läuft es definitiv nicht mehr.
Tipp: Öffnen Sie
Settings → Checkout → Customizations Reportin Ihrem Shopify-Adminbereich. Dort finden Sie jedes aktive Script Ihres Shops, dessen Funktion und den empfohlenen Ersatz-Function-Typ. Starten Sie dort.
Functions vs. Scripts: Was sich wirklich geändert hat
Dimension | Shopify Scripts (deprecated) | Shopify Functions (Ersatz) |
|---|---|---|
Sprache | Ruby DSL (Shopify-spezifisch) | Rust, JavaScript, TypeScript |
Runtime | Sandboxed Ruby auf Shopify-Infrastruktur | WebAssembly (WASM) — unter 5 ms Ausführungszeit |
Verfügbarkeit | Nur Plus-Tarif | Alle Tarife (Custom Apps erfordern Plus; Public Apps sind offen) |
Editor | Script Editor im Admin-Bereich | Lokale IDE + Shopify CLI |
Versionsverwaltung | Keine — Live-Edits | Git-friendly — vollständige Versionskontrolle |
Testen | Manuell im Checkout | Lokale Entwicklung mit |
Deployment | Klick auf "Speichern" im Admin-Bereich |
|
Ziele (Targets) | Line Items, Versand, Zahlungen | Discounts, Cart Transform, Validation, Delivery Customization, Payment Customization, Order Routing, Fulfillment Constraints, u.a. |
Der architektonische Wechsel ist gravierend. Scripts bedeuteten: "Ruby in einer Textarea anpassen." Functions bedeuten: "Eine echte App schreiben, versionieren, lokal testen und über eine CI-Pipeline deployen." Die Lernkurve ist steiler. Aber es ist auch die letzte Migration für Checkout-Logik auf absehbare Zeit – Functions sind Shopifys langfristiger Standard, keine Übergangslösung wie die Scripts.
Scripts dem richtigen Function-Typ zuordnen
Jedes Ihrer aktuellen Scripts lässt sich genau einer Function API zuordnen. Nutzen Sie diese Referenztabelle für Ihre Planung.
Alter Script-Typ | Funktionsweise | Neue Function API | Function Target |
|---|---|---|---|
Line Item Script | Rabatte auf bestimmte Produkte / Kunden / Warenkorb-Bedingungen anwenden | Cart & Checkout Discounts API |
|
Shipping Script (Rabatt) | Kostenloser / rabattierter Versand basierend auf Warenkorbregeln | Cart & Checkout Discounts API |
|
Shipping Script (Ausblenden / Umbenennen / Sortieren) | Versandart ab Wert X ausblenden, "Standard" in "Kostenlos ab 50 €" umbenennen | Delivery Customization API |
|
Payment Script | PayPal für B2B ausblenden, Nachnahme ab 500 € sperren, Reihenfolge ändern | Payment Customization API |
|
Cart-modifying Script (selten) | Produkte bündeln, Line Items austauschen | Cart Transform API |
|
Block-checkout Script | Warenkorb ablehnen, wenn SKU-Kombination ungültig | Cart & Checkout Validation API |
|
Wenn Sie zehn Scripts im Einsatz haben, werden Sie wahrscheinlich drei bis fünf Functions bauen – oft lassen sich mehrere Scripts in einer einzigen Function mit sauberer Bedingungslogik zusammenführen.

Voraussetzung: Lokale Entwicklungsumgebung einrichten
Bevor Sie eine Function erstellen, müssen drei Tools lokal installiert sein. Überprüfen Sie dies im Terminal.
1. Node.js 18+
node --version # Muss >= 18.0.0 sein
Falls älter, über nvm aktualisieren oder von nodejs.org herunterladen.
2. Shopify CLI 3+
npm install -g @shopify/cli@latest shopify version # Sollte 3.x oder höher ausgeben
3. Rust Toolchain (nur wenn Sie Functions in Rust schreiben)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh rustup target add wasm32-wasip1 cargo --version
JavaScript-Functions benötigen kein Rust. Wählen Sie eine Sprache für Ihr Team – ein Mix erhöht den Wartungsaufwand.
4. Ein Development-Shop
Loggen Sie sich in Ihr Partner-Dashboard ein und erstellen Sie einen Development-Shop oder nutzen Sie einen bestehenden. Hier testen Sie die Functions vor dem Go-live.
Ihre erste Function erstellen
Die CLI übernimmt das Scaffolding. In einem beliebigen Verzeichnis ausführen:
# Neue Shopify App erstellen (überspringen, falls bereits vorhanden) shopify app init my-checkout-functions cd my-checkout-functions # Function-Extension generieren shopify app generate extension
Folgen Sie den Prompts der CLI. Für eine Discount-Function wählen Sie:
Typ: Function
Template:
discount(odercart_checkout_validation,delivery_customization,payment_customizationetc.)Sprache: Rust oder JavaScript
Name: z. B.
volume-discount-fn
Dies erstellt das Verzeichnis extensions/volume-discount-fn/ mit:
extensions/volume-discount-fn/ ├── shopify.extension.toml # Konfiguration der Function (Targets, Build, Version) ├── src/ │ ├── cart_lines_discounts_generate_run.graphql # Input Query │ └── cart_lines_discounts_generate_run.rs # Logik der Function ├── Cargo.toml # Rust-Abhängigkeiten (nur bei Rust) └── README.md
Sie arbeiten primär in der .toml- (Konfiguration), der .graphql- (Input) und der .rs / .js-Datei (Logik).
Tutorial 1: Line Item Script ersetzen (Mengenrabatt)
Szenario: Das alte Script gewährt 10 % Rabatt auf den gesamten Warenkorb, sobald dieser 5 oder mehr Artikel aus einer bestimmten Collection enthält. Hier ist das Äquivalent als Function.
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 Sie explizit abfragen. Halten Sie die GraphQL-Query minimal – jedes weggelassene Feld sorgt für eine schnellere 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> { // Abbrechen, wenn Discount-Klasse nicht übereinstimmt let has_order_discount = input .discount() .discount_classes() .contains(&schema::DiscountClass::Order); if !has_order_discount { return Ok(schema::CartLinesDiscountsGenerateRunResult { operations: vec![] }); } // Summiere die Mengen der Artikel aus der Ziel-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![] }); } // 10 % Rabatt auf die Zwischensumme anwenden 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, Deployen, Aktivieren
# Lokale Entwicklung mit Hot-Reload shopify app dev # Wenn bereit, deployen shopify app deploy # In der sich öffnenden GraphiQL-Konsole (Taste `g` im Dev-Terminal drücken), # erstellen Sie den automatischen Rabatt, der Ihre Function nutzt:
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 das alte Script vollständig.
Tutorial 2: Shipping Script ersetzen (Expressversand ab Schwellenwert ausblenden)
Szenario: "Blende Expressversand aus, wenn die Zwischensumme im Warenkorb über 500 $ liegt, um teure Sendungen bei großen Bestellungen zu vermeiden." Hier ist die Umsetzung mit der Delivery Customization Function.
Schritt 2.1: Scaffolding
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: Aktivierung über den Admin-Bereich (kein GraphQL erforderlich)
Delivery Customizations verfügen über eine integrierte Admin-Benutzeroberfläche. Nach dem Ausführen von shopify app deploy:
Gehen Sie zu Settings → Shipping and delivery
Scrollen Sie nach unten zum Bereich Customizations
Klicken Sie auf Add customization → wählen Sie Ihre Function aus
Speichern
Die Regel ist live in der Produktivumgebung. Keine Mutation erforderlich.

Tutorial 3: Payment Script ersetzen (Nachnahme für B2B ausblenden)
Szenario: "Blende die Zahlungsmethode Nachnahme (Cash on Delivery) für alle Kunden mit dem Tag 'B2B' aus." Hier ist die Version als Payment Customization.
Schritt 3.1: Scaffolding
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 Settings → Payments → Customizations. Gleicher Ablauf wie bei den Versandoptionen: Function auswählen, speichern, fertig.
Ein Wort zu Post-Purchase-Anpassungen
Ein kurzer Hinweis, da Sie dies im Blog von Revize lesen. Revize übernimmt dort, wo Functions nicht hinkommen: Nach der Bestellung möchten Kunden oft Artikel hinzufügen, Größen ändern, Lieferadressen korrigieren oder vergessene Rabatte geltend machen. Functions steuern den Checkout. Revize greift danach. Während Functions festlegen, was im Warenkorb erlaubt ist, ermöglicht Revize Ihren Kunden und Ihrem Support-Team, Bestellungen nachträglich zu bearbeiten, ohne den gesamten Prozess stornieren und neu aufsetzen zu müssen. Das ist besonders für zwei Arten von Shops wichtig: diejenigen mit hohem Bestellvolumen, bei denen die manuelle Bearbeitung scheitert (Plus-Betreiber), und Marken, die sich über exzellenten Kundenservice definieren.
Wenn Ihr Migrationsplan zwar Scripts → Functions abdeckt, Sie aber nachträgliche Bestelländerungen noch nicht gelöst haben, werden Sie in kurzer Zeit vor der nächsten Herausforderung stehen. Unser neu veröffentlichter Leitfaden zum Order Management beschreibt den optimalen Post-Checkout-Workflow im Detail.
Zurück zur Migration.
Teststrategie: Die Methode mit Kunden-Tags
Functions bieten keinen "Entwurfsmodus" im Admin-Bereich. Der professionelle Weg ist, die neue Function zunächst über ein Kunden-Tag einzuschränken. Sie lassen das alte Script und die neue Function parallel laufen, vergleichen die Ergebnisse für getaggte Testkunden und schalten das Script erst ab, wenn alles identisch läuft.
Schritt 1: Testkunden taggen
Fügen Sie unter Customers zwei oder drei internen Konten das Tag FN-TESTER hinzu.
Schritt 2: Function auf Tag-Präsenz prüfen lassen
// Am Anfang der 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); // Altes Script weiterlaufen lassen } // Neue Logik wird nur für Testkunden ausgeführt
Schritt 3: hasAnyTag zur Input-Abfrage hinzufügen
cart { buyerIdentity { customer { hasAnyTag(tags: ["FN-TESTER"]) } } }
Schritt 4: Im Checkout verifizieren
Melden Sie sich mit einem Testkonto an und prüfen Sie, ob die Function greift. Melden Sie sich mit einem untagged Konto an und stellen Sie sicher, dass das alte Script wie gewohnt ausgeführt wird. Wenn das System über einige Tage stabil läuft, entfernen Sie die Tag-Prüfung und aktivieren die Function für alle Kunden.
Schritt 5: Altes Script deaktivieren
Gehen Sie zu Apps → Script Editor → [Ihr Script] → Unpublish. Sobald es deaktiviert ist, steuert die Function die Logik exklusiv.
Ein Deployment-Workflow, der skalierbar ist
Führen Sie Deployments nicht dauerhaft vom Entwickler-Laptop aus. Richten Sie nach den ersten erfolgreichen Migrationen eine CI-Pipeline ein.
Der minimale CI/CD-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 }}
Generieren Sie den CLI-Token in Ihrem Partner-Dashboard unter Settings → Tokens. Damit deployt jeder Merge auf main Ihre Functions automatisch.
Versionierung und Rollback
shopify app deploy erstellt versionierte Snapshots. Für einen Rollback:
shopify app versions list shopify app release --version <previous-version-id
Im Vergleich zu Scripts – bei denen ein Rollback aus dem Zurückkopieren von altem Code bestand – ist dies ein massiver Fortschritt.

Die häufigsten Fehler im Migrationsprozess
In der Begleitung von Shopify Plus-Händlern im vergangenen Jahr sind uns immer wieder dieselben Fehler aufgefallen.
1. 1:1-Portierung von Scripts erzwingen. Das ist der falsche Ansatz. Eine einzige Function kann oft mehrere Einzelscripts ersetzen. Analysieren Sie Ihre bestehende Logik ganzheitlich vor dem Neuschreiben.
2. Fehlende API-Berechtigungen (Scopes). Viele Functions benötigen Berechtigungen wie read_customers, read_orders oder write_discounts. Diese müssen in der shopify.app.toml unter scopes definiert und die App neu autorisiert werden, andernfalls liefert die GraphQL-Abfrage Nullwerte.
3. Aktivierung ohne kontrollierte Testphase. Selbst bei sauberem Code können Edge Cases (Geschenkkarten, B2B-Skonti, Teillagerbestände) Probleme verursachen. Ein tag-basierter Rollout kostet zwei Tage Sicherheit, schützt aber vor Umsatzausfällen.
4. Ignorieren des Customizations Report. Dieser Bericht liefert das exakte Inventar Ihrer aktiven Anpassungen. Migrieren Sie strikt auf Basis dieses Reports, statt sich auf das Gedächtnis zu verlassen.
5. Statische ID-Zuweisung. Nutzen Sie Metafields für die Konfiguration Ihrer Functions, wenn Werte (wie Collection-IDs oder Kunden-Tags) für Redakteure änderbar sein müssen. Die CLI unterstützt Metafield-basierte Konfigurationen von Haus aus.
Migrationsplan für die kommenden 75 Tage
Ein realistischer Fahrplan, um den 30. Juni stressfrei zu erreichen.
Woche | Aufgabe |
|---|---|
Woche 1 (Diese Woche) | Holen Sie den Customizations Report. Analysieren Sie jedes Script. Entscheiden Sie: Custom Function, Public App oder Löschen. |
Wochen 2–3 | Lokale Entwicklungsumgebung einrichten. Erste Test-Function erstellen. Migrieren Sie die einfachste Logik (z. B. Bezahlmethode ausblenden). |
Wochen 4–6 | Rabatt-Scripts migrieren. Planen Sie hierfür die meiste Zeit ein, da die Discounts API die komplexeste ist. Ausführlich mit Test-Tags prüfen. |
Wochen 7–8 | Versand-Scripts migrieren. Steuern Sie Delivery Customizations über das Admin-Interface an. |
Wochen 9–10 | CI/CD-Pipeline aufsetzen. Automatisieren Sie die Deployments. |
Woche 11 (Mitte Juni) | Letzte Kontrollen. Deaktivieren Sie alle alten Scripts. Betreiben Sie den Shop zwei Wochen ausschließlich mit Functions. |
30. Juni | Tag der Abschaltung. Ihr Checkout läuft stabil weiter, da die Migration abgeschlossen ist. |
Wer jetzt startet, behält einen Puffer. Wer im Juni beginnt, riskiert Ausfälle.

Häufig gestellte Fragen (FAQ)
Benötige ich Shopify Plus, um Functions zu nutzen?
Eigene, maßgeschneiderte Functions erfordern Shopify Plus. Functions über öffentliche Apps (Public Apps) laufen hingegen auf allen Tarifen. Wer nicht auf Plus ist, kann entweder passende Apps aus dem App Store nutzen oder auf Plus upgraden, um eigenen Code zu schreiben. Da die meisten betroffenen Betriebe mit Scripts ohnehin Plus-Kunden sind, ändert sich in der Praxis meist nichts.
Kann ich Functions in TypeScript schreiben?
Ja – TypeScript wird vollständig unterstützt und direkt von der CLI vorbereitet. Wenn Sie sich beim Ausführen von shopify app generate extension für "JavaScript" entscheiden, liefert das Projekt passende Typdefinitionen aus import("../generated/api") mit. Dateiendungen können problemlos in .ts geändert und eine tsconfig.json hinzugefügt werden.
Wie schnell sind Functions im Vergleich zu Scripts?
Functions laufen in der Regel unter 5 ms – deutlich schneller als Ruby-Scripts. Aufgrund der Kompilierung zu WebAssembly gibt Shopify ein striktes Limit von 5 ms vor. Wird dieses Budget überschritten, bricht die Ausführung ab und es werden keine Änderungen angewendet. Gut geschriebene JavaScript- oder Rust-Functions benötigen meist nur 1–2 ms.
Können Functions externe Schnittstellen (APIs) ansprechen?
Nein – Functions haben keinen Netzwerkzugriff. Es handelt sich um reine Berechnungsmodule: Daten rein (Warenkorb via GraphQL) → Operationen raus. Benötigen Sie externe Daten (z. B. CRM-Abfragen oder Echtzeit-Bestände), müssen diese vorab über Metafields gespeichert werden oder andere Hooks genutzt werden (wie App Proxies, Webhooks oder Cart Transform mit Backend-Abfrage). Dies erfordert oft ein teilweises Redesign der Logik.
Was unterscheidet Cart Transform von Discounts?
Discounts verändern Preise; Cart Transform verändert Warenkorbeinhalte. Nutzen Sie die Discounts API für Preisnachlässe oder Bundles. Cart Transform dient dazu, Produkte zu bündeln oder Varianten aufzuteilen. Alte Scripts vermischten diese Logik oft. Trennen Sie diese bei der Migration sauber auf.
Wie teste ich eine Function lokal ohne Development-Shop?
Unittests lassen sich über cargo test (Rust) oder npm test (JS) ausführen, für vollständige Integrationstests ist jedoch ein Shop erforderlich. Mit dem Befehl shopify app function run können Sie die Function gegen Testdateien laufen lassen, was die Entwicklung beschleunigt. Das tatsächliche Checkout-Verhalten lässt sich aber nur über einen echten Warenkorb prüfen.
Kann ich mehrere Functions desselben Typs nutzen?
Ja – Shopify erlaubt mehrere Functions pro Target, die nacheinander ausgeführt werden. Bei Rabatten steuert Shopify die Reihenfolge über die Kombinationsregeln. Bei Versand- und Zahlungsanpassungen fließen die Ausgaben einer Function in die nächste ein. Für die Wartbarkeit empfiehlt sich jedoch ein fokussiertes Setup.
Was passiert mit meinem aktiven Script nach dem Deploy der Function?
Nichts, beide laufen parallel, bis Sie das Script im Script Editor deaktivieren. Das ist gewollt, um direkten Abgleich und Paritätstests zu ermöglichen. Deaktivieren Sie das Script manuell, sobald die Function fehlerfrei läuft. Ab dem 1. Juli 2026 werden Scripts serverseitig generell blockiert.
Hat die Migration Auswirkungen auf mein SEO oder mein Theme?
Nein – Functions laufen serverseitig direkt im Checkout-Prozess und berühren weder das Theme noch Produktseiten.
Sie beeinträchtigen weder das Frontend noch die SEO-Struktur.
Wie migriere ich Scripts, die auf zusätzliche Eigenschaften (Custom Properties) in `Input.line_items` zugreifen?
Eigenschaften von Positionen sind über das Feld attribute im GraphQL-Input der Warenkorbzeilen zugänglich. Fragen Sie attribute(key: "your-key") { value } innerhalb der lines-Selektion ab. Die Daten werden ähnlich ausgelesen wie früher bei den Line Item Properties – nur eben per GraphQL statt Ruby.
Können Functions Analytics-Daten oder Tags an Bestellungen schreiben?
Nein – Functions können keine Tags schreiben oder Webhooks auslösen. Sie modifizieren ausschließlich den aktuellen Checkout-Zustand. Nutzen Sie für nachgelagerte Logik Shopify Flow, getriggert durch die Bestellerstellung (Order Created). Häufig wird eine Function (für den Rabatt) mit einem Flow (für das Tagging der Bestellung) kombiniert.
Gibt es fertige Apps im App Store als Alternative zur Eigenentwicklung?
Ja – im Shopify App Store finden sich zahlreiche fertige Lösungen, die Functions für Standard-Szenarien bereitstellen. Suchen Sie nach Begriffen wie "Discount Function" oder "Delivery Customization". Für einfache Rabattregeln oder das Ausblenden von Versand- und Zahlungsarten nach Tags spart Ihnen eine fertige App viel Entwicklungszeit.
Was passiert, wenn ich die Deadline am 30. Juni verpasse?
Die Ausführung der alten Scripts bricht ersatzlos ab – es gibt keine Kulanzzeit und keine Fristverlängerung. Alle betroffenen Workflows fallen sofort auf das Standardverhalten zurück. Planen Sie den Übergang rechtzeitig ein, da vor allem die Testphase oft unterschätzt wird.
Kann ich den Script Editor nach der Migration deinstallieren?
Ja – die App wird nach dem 30. Juni ohnehin hinfällig. Sie können die Deinstallation direkt nach erfolgreichem Funktionswechsel vornehmen. Eigene Functions laufen vollständig autark.
Ausstehende To-Dos für diese Woche
Beginnen Sie direkt mit der Umsetzung und planen Sie die ersten Schritte für die nächsten sieben Tage ein.
1. Customizations Report prüfen. Laden Sie den Bericht unter Settings → Checkout → Customizations Report herunter. Das ist Ihre primäre Arbeitsliste für die Migration.
2. Lokale Toolchain vorbereiten. Installieren Sie Node 18, Shopify CLI und optional Rust. Überprüfen Sie das Setup mit shopify version.
3. Eine einfache Test-Function deployen. Beginnen Sie mit einem unkomplizierten Anwendungsfall, etwa dem Ausblenden einer Zahlungsart. Machen Sie sich mit dem gesamten Deploy-Prozess auf einem Dev-Shop vertraut.
4. Ressourcen für die nächsten Wochen sichern. Die Migration lässt sich nicht nebenbei erledigen. Blocken Sie feste Zeiten in den Sprints für die Teams, um eine termingerechte Fertigstellung zu gewährleisten.
Erfahrungswerte zeigen: Nach einer kurzen Einarbeitung und der initialen Logik-Portierung nimmt die Qualitätssicherung und Fehlerbehebung in der Praxis meist die meiste Zeit in Anspruch. Ein rechtzeitiger Start verhindert Engpässe vor der Deadline.
Sobald Ihre Checkout-Prozesse laufen, stehen meist Optimierungen nach dem Kauf an – Adressänderungen, Produktwechsel oder nachträgliche Rabattaktionen. Wenn Sie solche Anforderungen umsetzen wollen, steht Ihnen Revize im Shopify App Store zur Verfügung und arbeitet nahtlos mit Ihren neu erstellten Functions zusammen.
Ressourcen
Ähnliche Artikel
Es ist der 16. April 2026. Gestern – am 15. April – hat Shopify den Script Editor endgültig gesperrt. Sie können keine neuen Scripts mehr erstellen oder veröffentlichen. Die vollständige Abschaltung erfolgt in 75 Tagen, am 30. Juni 2026.
Wenn Sie ein Shopify Plus-Entwickler oder die betreuende Agentur eines Plus-Shops sind und diese Migration in den letzten zwölf Monaten immer wieder in den "nächsten Sprint" verschoben haben, haben Sie ein Problem. Kein kosmetisches Problem, sondern ein Problem der Kategorie „Ihr Checkout bricht am 1. Juli um Mitternacht zusammen“. Die meisten Plus-Shops haben über die Jahre 5 bis 20 Scripts angesammelt, von denen jedes im Stillen eine Rabattregel, das Ausblenden einer Versandart oder eine Zahlungsmethode steuert, an deren Implementierung 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. Sobald Sie diesen Artikel gelesen haben, wissen Sie, wie Sie eine Function mit der Shopify CLI aufsetzen, die Rust- oder JavaScript-Logik für Rabatte, Delivery Customizations und Payment Customizations schreiben, diese sicher an einer ausgewählten Kundengruppe testen und in die Produktivumgebung ausrollen, ohne Ihren bestehenden Checkout zu gefährden.
Lassen Sie uns die Scripts aus Ihrem Shop entfernen und durch Functions ersetzen.

Schnelle Antwort: Scripts → Functions in 60 Sekunden
Die Migration in einem Absatz: Shopify Scripts (Ruby-Code im Script Editor, nur für Plus) werden durch Shopify Functions ersetzt (WebAssembly-Module, geschrieben in Rust oder JavaScript, verfügbar für alle Tarife). Sie erstellen eine Function mit
shopify app generate extension, definieren einerun.graphql-Abfrage, um die benötigten Warenkorbdaten abzurufen, schreiben einerun.rs- oderrun.js-Datei, die Werte (Rabatte, ausgeblendete Versandoptionen etc.) zurückgibt, deployen das Ganze mitshopify app deployund aktivieren es über den Admin-Bereich oder eine GraphQL-Mutation. Functions werden als kompilierte WASM in weniger als 5 ms ausgeführt, laufen in jedem Tarif und sind der einzige Weg für Anpassungen, den Shopify künftig unterstützt.
Was sich am 30. Juni tatsächlich ändert
Bevor wir Code anfassen, müssen die Termine klar sein. Es gibt zwei wichtige Daten, und beide sind entscheidend.
Datum | Was passiert | Ihre Action |
|---|---|---|
15. April 2026 (vergangen) | Script Editor ist schreibgeschützt. Keine neuen Scripts. Keine Bearbeitung bestehender Scripts. | Bestehende Scripts laufen noch. Jetzt migrieren oder Logik einfrieren. |
30. Juni 2026 | Alle Shopify Scripts stopped die Ausführung. Ohne Ausnahme. | Ihre Ersatz-Function muss vor diesem Datum live sein. |
Die Migration ist binär. Entweder ist Ihre Function bis zum 30. Juni deployed und Ihr Checkout funktioniert weiterhin, oder sie ist es nicht – und jeder betroffene Warenkorb fällt geräuschlos auf Standardpreise, Standardversandtarife und alle aktivierten Zahlungsmethoden zurück. Es gibt keine halben Sachen. Das Script läuft oder es läuft nicht, und nach dem 30. Juni läuft es definitiv nicht mehr.
Tipp: Öffnen Sie
Settings → Checkout → Customizations Reportin Ihrem Shopify-Adminbereich. Dort finden Sie jedes aktive Script Ihres Shops, dessen Funktion und den empfohlenen Ersatz-Function-Typ. Starten Sie dort.
Functions vs. Scripts: Was sich wirklich geändert hat
Dimension | Shopify Scripts (deprecated) | Shopify Functions (Ersatz) |
|---|---|---|
Sprache | Ruby DSL (Shopify-spezifisch) | Rust, JavaScript, TypeScript |
Runtime | Sandboxed Ruby auf Shopify-Infrastruktur | WebAssembly (WASM) — unter 5 ms Ausführungszeit |
Verfügbarkeit | Nur Plus-Tarif | Alle Tarife (Custom Apps erfordern Plus; Public Apps sind offen) |
Editor | Script Editor im Admin-Bereich | Lokale IDE + Shopify CLI |
Versionsverwaltung | Keine — Live-Edits | Git-friendly — vollständige Versionskontrolle |
Testen | Manuell im Checkout | Lokale Entwicklung mit |
Deployment | Klick auf "Speichern" im Admin-Bereich |
|
Ziele (Targets) | Line Items, Versand, Zahlungen | Discounts, Cart Transform, Validation, Delivery Customization, Payment Customization, Order Routing, Fulfillment Constraints, u.a. |
Der architektonische Wechsel ist gravierend. Scripts bedeuteten: "Ruby in einer Textarea anpassen." Functions bedeuten: "Eine echte App schreiben, versionieren, lokal testen und über eine CI-Pipeline deployen." Die Lernkurve ist steiler. Aber es ist auch die letzte Migration für Checkout-Logik auf absehbare Zeit – Functions sind Shopifys langfristiger Standard, keine Übergangslösung wie die Scripts.
Scripts dem richtigen Function-Typ zuordnen
Jedes Ihrer aktuellen Scripts lässt sich genau einer Function API zuordnen. Nutzen Sie diese Referenztabelle für Ihre Planung.
Alter Script-Typ | Funktionsweise | Neue Function API | Function Target |
|---|---|---|---|
Line Item Script | Rabatte auf bestimmte Produkte / Kunden / Warenkorb-Bedingungen anwenden | Cart & Checkout Discounts API |
|
Shipping Script (Rabatt) | Kostenloser / rabattierter Versand basierend auf Warenkorbregeln | Cart & Checkout Discounts API |
|
Shipping Script (Ausblenden / Umbenennen / Sortieren) | Versandart ab Wert X ausblenden, "Standard" in "Kostenlos ab 50 €" umbenennen | Delivery Customization API |
|
Payment Script | PayPal für B2B ausblenden, Nachnahme ab 500 € sperren, Reihenfolge ändern | Payment Customization API |
|
Cart-modifying Script (selten) | Produkte bündeln, Line Items austauschen | Cart Transform API |
|
Block-checkout Script | Warenkorb ablehnen, wenn SKU-Kombination ungültig | Cart & Checkout Validation API |
|
Wenn Sie zehn Scripts im Einsatz haben, werden Sie wahrscheinlich drei bis fünf Functions bauen – oft lassen sich mehrere Scripts in einer einzigen Function mit sauberer Bedingungslogik zusammenführen.

Voraussetzung: Lokale Entwicklungsumgebung einrichten
Bevor Sie eine Function erstellen, müssen drei Tools lokal installiert sein. Überprüfen Sie dies im Terminal.
1. Node.js 18+
node --version # Muss >= 18.0.0 sein
Falls älter, über nvm aktualisieren oder von nodejs.org herunterladen.
2. Shopify CLI 3+
npm install -g @shopify/cli@latest shopify version # Sollte 3.x oder höher ausgeben
3. Rust Toolchain (nur wenn Sie Functions in Rust schreiben)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh rustup target add wasm32-wasip1 cargo --version
JavaScript-Functions benötigen kein Rust. Wählen Sie eine Sprache für Ihr Team – ein Mix erhöht den Wartungsaufwand.
4. Ein Development-Shop
Loggen Sie sich in Ihr Partner-Dashboard ein und erstellen Sie einen Development-Shop oder nutzen Sie einen bestehenden. Hier testen Sie die Functions vor dem Go-live.
Ihre erste Function erstellen
Die CLI übernimmt das Scaffolding. In einem beliebigen Verzeichnis ausführen:
# Neue Shopify App erstellen (überspringen, falls bereits vorhanden) shopify app init my-checkout-functions cd my-checkout-functions # Function-Extension generieren shopify app generate extension
Folgen Sie den Prompts der CLI. Für eine Discount-Function wählen Sie:
Typ: Function
Template:
discount(odercart_checkout_validation,delivery_customization,payment_customizationetc.)Sprache: Rust oder JavaScript
Name: z. B.
volume-discount-fn
Dies erstellt das Verzeichnis extensions/volume-discount-fn/ mit:
extensions/volume-discount-fn/ ├── shopify.extension.toml # Konfiguration der Function (Targets, Build, Version) ├── src/ │ ├── cart_lines_discounts_generate_run.graphql # Input Query │ └── cart_lines_discounts_generate_run.rs # Logik der Function ├── Cargo.toml # Rust-Abhängigkeiten (nur bei Rust) └── README.md
Sie arbeiten primär in der .toml- (Konfiguration), der .graphql- (Input) und der .rs / .js-Datei (Logik).
Tutorial 1: Line Item Script ersetzen (Mengenrabatt)
Szenario: Das alte Script gewährt 10 % Rabatt auf den gesamten Warenkorb, sobald dieser 5 oder mehr Artikel aus einer bestimmten Collection enthält. Hier ist das Äquivalent als Function.
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 Sie explizit abfragen. Halten Sie die GraphQL-Query minimal – jedes weggelassene Feld sorgt für eine schnellere 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> { // Abbrechen, wenn Discount-Klasse nicht übereinstimmt let has_order_discount = input .discount() .discount_classes() .contains(&schema::DiscountClass::Order); if !has_order_discount { return Ok(schema::CartLinesDiscountsGenerateRunResult { operations: vec![] }); } // Summiere die Mengen der Artikel aus der Ziel-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![] }); } // 10 % Rabatt auf die Zwischensumme anwenden 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, Deployen, Aktivieren
# Lokale Entwicklung mit Hot-Reload shopify app dev # Wenn bereit, deployen shopify app deploy # In der sich öffnenden GraphiQL-Konsole (Taste `g` im Dev-Terminal drücken), # erstellen Sie den automatischen Rabatt, der Ihre Function nutzt:
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 das alte Script vollständig.
Tutorial 2: Shipping Script ersetzen (Expressversand ab Schwellenwert ausblenden)
Szenario: "Blende Expressversand aus, wenn die Zwischensumme im Warenkorb über 500 $ liegt, um teure Sendungen bei großen Bestellungen zu vermeiden." Hier ist die Umsetzung mit der Delivery Customization Function.
Schritt 2.1: Scaffolding
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: Aktivierung über den Admin-Bereich (kein GraphQL erforderlich)
Delivery Customizations verfügen über eine integrierte Admin-Benutzeroberfläche. Nach dem Ausführen von shopify app deploy:
Gehen Sie zu Settings → Shipping and delivery
Scrollen Sie nach unten zum Bereich Customizations
Klicken Sie auf Add customization → wählen Sie Ihre Function aus
Speichern
Die Regel ist live in der Produktivumgebung. Keine Mutation erforderlich.

Tutorial 3: Payment Script ersetzen (Nachnahme für B2B ausblenden)
Szenario: "Blende die Zahlungsmethode Nachnahme (Cash on Delivery) für alle Kunden mit dem Tag 'B2B' aus." Hier ist die Version als Payment Customization.
Schritt 3.1: Scaffolding
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 Settings → Payments → Customizations. Gleicher Ablauf wie bei den Versandoptionen: Function auswählen, speichern, fertig.
Ein Wort zu Post-Purchase-Anpassungen
Ein kurzer Hinweis, da Sie dies im Blog von Revize lesen. Revize übernimmt dort, wo Functions nicht hinkommen: Nach der Bestellung möchten Kunden oft Artikel hinzufügen, Größen ändern, Lieferadressen korrigieren oder vergessene Rabatte geltend machen. Functions steuern den Checkout. Revize greift danach. Während Functions festlegen, was im Warenkorb erlaubt ist, ermöglicht Revize Ihren Kunden und Ihrem Support-Team, Bestellungen nachträglich zu bearbeiten, ohne den gesamten Prozess stornieren und neu aufsetzen zu müssen. Das ist besonders für zwei Arten von Shops wichtig: diejenigen mit hohem Bestellvolumen, bei denen die manuelle Bearbeitung scheitert (Plus-Betreiber), und Marken, die sich über exzellenten Kundenservice definieren.
Wenn Ihr Migrationsplan zwar Scripts → Functions abdeckt, Sie aber nachträgliche Bestelländerungen noch nicht gelöst haben, werden Sie in kurzer Zeit vor der nächsten Herausforderung stehen. Unser neu veröffentlichter Leitfaden zum Order Management beschreibt den optimalen Post-Checkout-Workflow im Detail.
Zurück zur Migration.
Teststrategie: Die Methode mit Kunden-Tags
Functions bieten keinen "Entwurfsmodus" im Admin-Bereich. Der professionelle Weg ist, die neue Function zunächst über ein Kunden-Tag einzuschränken. Sie lassen das alte Script und die neue Function parallel laufen, vergleichen die Ergebnisse für getaggte Testkunden und schalten das Script erst ab, wenn alles identisch läuft.
Schritt 1: Testkunden taggen
Fügen Sie unter Customers zwei oder drei internen Konten das Tag FN-TESTER hinzu.
Schritt 2: Function auf Tag-Präsenz prüfen lassen
// Am Anfang der 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); // Altes Script weiterlaufen lassen } // Neue Logik wird nur für Testkunden ausgeführt
Schritt 3: hasAnyTag zur Input-Abfrage hinzufügen
cart { buyerIdentity { customer { hasAnyTag(tags: ["FN-TESTER"]) } } }
Schritt 4: Im Checkout verifizieren
Melden Sie sich mit einem Testkonto an und prüfen Sie, ob die Function greift. Melden Sie sich mit einem untagged Konto an und stellen Sie sicher, dass das alte Script wie gewohnt ausgeführt wird. Wenn das System über einige Tage stabil läuft, entfernen Sie die Tag-Prüfung und aktivieren die Function für alle Kunden.
Schritt 5: Altes Script deaktivieren
Gehen Sie zu Apps → Script Editor → [Ihr Script] → Unpublish. Sobald es deaktiviert ist, steuert die Function die Logik exklusiv.
Ein Deployment-Workflow, der skalierbar ist
Führen Sie Deployments nicht dauerhaft vom Entwickler-Laptop aus. Richten Sie nach den ersten erfolgreichen Migrationen eine CI-Pipeline ein.
Der minimale CI/CD-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 }}
Generieren Sie den CLI-Token in Ihrem Partner-Dashboard unter Settings → Tokens. Damit deployt jeder Merge auf main Ihre Functions automatisch.
Versionierung und Rollback
shopify app deploy erstellt versionierte Snapshots. Für einen Rollback:
shopify app versions list shopify app release --version <previous-version-id
Im Vergleich zu Scripts – bei denen ein Rollback aus dem Zurückkopieren von altem Code bestand – ist dies ein massiver Fortschritt.

Die häufigsten Fehler im Migrationsprozess
In der Begleitung von Shopify Plus-Händlern im vergangenen Jahr sind uns immer wieder dieselben Fehler aufgefallen.
1. 1:1-Portierung von Scripts erzwingen. Das ist der falsche Ansatz. Eine einzige Function kann oft mehrere Einzelscripts ersetzen. Analysieren Sie Ihre bestehende Logik ganzheitlich vor dem Neuschreiben.
2. Fehlende API-Berechtigungen (Scopes). Viele Functions benötigen Berechtigungen wie read_customers, read_orders oder write_discounts. Diese müssen in der shopify.app.toml unter scopes definiert und die App neu autorisiert werden, andernfalls liefert die GraphQL-Abfrage Nullwerte.
3. Aktivierung ohne kontrollierte Testphase. Selbst bei sauberem Code können Edge Cases (Geschenkkarten, B2B-Skonti, Teillagerbestände) Probleme verursachen. Ein tag-basierter Rollout kostet zwei Tage Sicherheit, schützt aber vor Umsatzausfällen.
4. Ignorieren des Customizations Report. Dieser Bericht liefert das exakte Inventar Ihrer aktiven Anpassungen. Migrieren Sie strikt auf Basis dieses Reports, statt sich auf das Gedächtnis zu verlassen.
5. Statische ID-Zuweisung. Nutzen Sie Metafields für die Konfiguration Ihrer Functions, wenn Werte (wie Collection-IDs oder Kunden-Tags) für Redakteure änderbar sein müssen. Die CLI unterstützt Metafield-basierte Konfigurationen von Haus aus.
Migrationsplan für die kommenden 75 Tage
Ein realistischer Fahrplan, um den 30. Juni stressfrei zu erreichen.
Woche | Aufgabe |
|---|---|
Woche 1 (Diese Woche) | Holen Sie den Customizations Report. Analysieren Sie jedes Script. Entscheiden Sie: Custom Function, Public App oder Löschen. |
Wochen 2–3 | Lokale Entwicklungsumgebung einrichten. Erste Test-Function erstellen. Migrieren Sie die einfachste Logik (z. B. Bezahlmethode ausblenden). |
Wochen 4–6 | Rabatt-Scripts migrieren. Planen Sie hierfür die meiste Zeit ein, da die Discounts API die komplexeste ist. Ausführlich mit Test-Tags prüfen. |
Wochen 7–8 | Versand-Scripts migrieren. Steuern Sie Delivery Customizations über das Admin-Interface an. |
Wochen 9–10 | CI/CD-Pipeline aufsetzen. Automatisieren Sie die Deployments. |
Woche 11 (Mitte Juni) | Letzte Kontrollen. Deaktivieren Sie alle alten Scripts. Betreiben Sie den Shop zwei Wochen ausschließlich mit Functions. |
30. Juni | Tag der Abschaltung. Ihr Checkout läuft stabil weiter, da die Migration abgeschlossen ist. |
Wer jetzt startet, behält einen Puffer. Wer im Juni beginnt, riskiert Ausfälle.

Häufig gestellte Fragen (FAQ)
Benötige ich Shopify Plus, um Functions zu nutzen?
Eigene, maßgeschneiderte Functions erfordern Shopify Plus. Functions über öffentliche Apps (Public Apps) laufen hingegen auf allen Tarifen. Wer nicht auf Plus ist, kann entweder passende Apps aus dem App Store nutzen oder auf Plus upgraden, um eigenen Code zu schreiben. Da die meisten betroffenen Betriebe mit Scripts ohnehin Plus-Kunden sind, ändert sich in der Praxis meist nichts.
Kann ich Functions in TypeScript schreiben?
Ja – TypeScript wird vollständig unterstützt und direkt von der CLI vorbereitet. Wenn Sie sich beim Ausführen von shopify app generate extension für "JavaScript" entscheiden, liefert das Projekt passende Typdefinitionen aus import("../generated/api") mit. Dateiendungen können problemlos in .ts geändert und eine tsconfig.json hinzugefügt werden.
Wie schnell sind Functions im Vergleich zu Scripts?
Functions laufen in der Regel unter 5 ms – deutlich schneller als Ruby-Scripts. Aufgrund der Kompilierung zu WebAssembly gibt Shopify ein striktes Limit von 5 ms vor. Wird dieses Budget überschritten, bricht die Ausführung ab und es werden keine Änderungen angewendet. Gut geschriebene JavaScript- oder Rust-Functions benötigen meist nur 1–2 ms.
Können Functions externe Schnittstellen (APIs) ansprechen?
Nein – Functions haben keinen Netzwerkzugriff. Es handelt sich um reine Berechnungsmodule: Daten rein (Warenkorb via GraphQL) → Operationen raus. Benötigen Sie externe Daten (z. B. CRM-Abfragen oder Echtzeit-Bestände), müssen diese vorab über Metafields gespeichert werden oder andere Hooks genutzt werden (wie App Proxies, Webhooks oder Cart Transform mit Backend-Abfrage). Dies erfordert oft ein teilweises Redesign der Logik.
Was unterscheidet Cart Transform von Discounts?
Discounts verändern Preise; Cart Transform verändert Warenkorbeinhalte. Nutzen Sie die Discounts API für Preisnachlässe oder Bundles. Cart Transform dient dazu, Produkte zu bündeln oder Varianten aufzuteilen. Alte Scripts vermischten diese Logik oft. Trennen Sie diese bei der Migration sauber auf.
Wie teste ich eine Function lokal ohne Development-Shop?
Unittests lassen sich über cargo test (Rust) oder npm test (JS) ausführen, für vollständige Integrationstests ist jedoch ein Shop erforderlich. Mit dem Befehl shopify app function run können Sie die Function gegen Testdateien laufen lassen, was die Entwicklung beschleunigt. Das tatsächliche Checkout-Verhalten lässt sich aber nur über einen echten Warenkorb prüfen.
Kann ich mehrere Functions desselben Typs nutzen?
Ja – Shopify erlaubt mehrere Functions pro Target, die nacheinander ausgeführt werden. Bei Rabatten steuert Shopify die Reihenfolge über die Kombinationsregeln. Bei Versand- und Zahlungsanpassungen fließen die Ausgaben einer Function in die nächste ein. Für die Wartbarkeit empfiehlt sich jedoch ein fokussiertes Setup.
Was passiert mit meinem aktiven Script nach dem Deploy der Function?
Nichts, beide laufen parallel, bis Sie das Script im Script Editor deaktivieren. Das ist gewollt, um direkten Abgleich und Paritätstests zu ermöglichen. Deaktivieren Sie das Script manuell, sobald die Function fehlerfrei läuft. Ab dem 1. Juli 2026 werden Scripts serverseitig generell blockiert.
Hat die Migration Auswirkungen auf mein SEO oder mein Theme?
Nein – Functions laufen serverseitig direkt im Checkout-Prozess und berühren weder das Theme noch Produktseiten.
Sie beeinträchtigen weder das Frontend noch die SEO-Struktur.
Wie migriere ich Scripts, die auf zusätzliche Eigenschaften (Custom Properties) in `Input.line_items` zugreifen?
Eigenschaften von Positionen sind über das Feld attribute im GraphQL-Input der Warenkorbzeilen zugänglich. Fragen Sie attribute(key: "your-key") { value } innerhalb der lines-Selektion ab. Die Daten werden ähnlich ausgelesen wie früher bei den Line Item Properties – nur eben per GraphQL statt Ruby.
Können Functions Analytics-Daten oder Tags an Bestellungen schreiben?
Nein – Functions können keine Tags schreiben oder Webhooks auslösen. Sie modifizieren ausschließlich den aktuellen Checkout-Zustand. Nutzen Sie für nachgelagerte Logik Shopify Flow, getriggert durch die Bestellerstellung (Order Created). Häufig wird eine Function (für den Rabatt) mit einem Flow (für das Tagging der Bestellung) kombiniert.
Gibt es fertige Apps im App Store als Alternative zur Eigenentwicklung?
Ja – im Shopify App Store finden sich zahlreiche fertige Lösungen, die Functions für Standard-Szenarien bereitstellen. Suchen Sie nach Begriffen wie "Discount Function" oder "Delivery Customization". Für einfache Rabattregeln oder das Ausblenden von Versand- und Zahlungsarten nach Tags spart Ihnen eine fertige App viel Entwicklungszeit.
Was passiert, wenn ich die Deadline am 30. Juni verpasse?
Die Ausführung der alten Scripts bricht ersatzlos ab – es gibt keine Kulanzzeit und keine Fristverlängerung. Alle betroffenen Workflows fallen sofort auf das Standardverhalten zurück. Planen Sie den Übergang rechtzeitig ein, da vor allem die Testphase oft unterschätzt wird.
Kann ich den Script Editor nach der Migration deinstallieren?
Ja – die App wird nach dem 30. Juni ohnehin hinfällig. Sie können die Deinstallation direkt nach erfolgreichem Funktionswechsel vornehmen. Eigene Functions laufen vollständig autark.
Ausstehende To-Dos für diese Woche
Beginnen Sie direkt mit der Umsetzung und planen Sie die ersten Schritte für die nächsten sieben Tage ein.
1. Customizations Report prüfen. Laden Sie den Bericht unter Settings → Checkout → Customizations Report herunter. Das ist Ihre primäre Arbeitsliste für die Migration.
2. Lokale Toolchain vorbereiten. Installieren Sie Node 18, Shopify CLI und optional Rust. Überprüfen Sie das Setup mit shopify version.
3. Eine einfache Test-Function deployen. Beginnen Sie mit einem unkomplizierten Anwendungsfall, etwa dem Ausblenden einer Zahlungsart. Machen Sie sich mit dem gesamten Deploy-Prozess auf einem Dev-Shop vertraut.
4. Ressourcen für die nächsten Wochen sichern. Die Migration lässt sich nicht nebenbei erledigen. Blocken Sie feste Zeiten in den Sprints für die Teams, um eine termingerechte Fertigstellung zu gewährleisten.
Erfahrungswerte zeigen: Nach einer kurzen Einarbeitung und der initialen Logik-Portierung nimmt die Qualitätssicherung und Fehlerbehebung in der Praxis meist die meiste Zeit in Anspruch. Ein rechtzeitiger Start verhindert Engpässe vor der Deadline.
Sobald Ihre Checkout-Prozesse laufen, stehen meist Optimierungen nach dem Kauf an – Adressänderungen, Produktwechsel oder nachträgliche Rabattaktionen. Wenn Sie solche Anforderungen umsetzen wollen, steht Ihnen Revize im Shopify App Store zur Verfügung und arbeitet nahtlos mit Ihren neu erstellten Functions zusammen.
Ressourcen
Ähnliche 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



