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

Wie man Shopify Scripts zu Functions migriert: Das vollständige Code-Tutorial (Ausgabe 2026) — Revize-Blogartikel-Header

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.



Developer migrating Shopify Scripts to Shopify Functions modules

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 eine run.graphql-Abfrage, um die benötigten Warenkorbdaten abzurufen, schreiben eine run.rs- oder run.js-Datei, die Werte (Rabatte, ausgeblendete Versandoptionen etc.) zurückgibt, deployen das Ganze mit shopify app deploy und 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 Report in 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 shopify app dev, Preview-Links

Deployment

Klick auf "Speichern" im Admin-Bereich

shopify app deploy im Terminal

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

cart.lines.discounts.generate.run

Shipping Script (Rabatt)

Kostenloser / rabattierter Versand basierend auf Warenkorbregeln

Cart & Checkout Discounts API

cart.delivery-options.discounts.generate.run

Shipping Script (Ausblenden / Umbenennen / Sortieren)

Versandart ab Wert X ausblenden, "Standard" in "Kostenlos ab 50 €" umbenennen

Delivery Customization API

cart.delivery-options.transform.run

Payment Script

PayPal für B2B ausblenden, Nachnahme ab 500 € sperren, Reihenfolge ändern

Payment Customization API

cart.payment-methods.transform.run

Cart-modifying Script (selten)

Produkte bündeln, Line Items austauschen

Cart Transform API

cart.transform.run

Block-checkout Script

Warenkorb ablehnen, wenn SKU-Kombination ungültig

Cart & Checkout Validation API

cart.validations.generate.run

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.



Shopify Functions unifying discounts, delivery, and payment customizations

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 (oder cart_checkout_validation, delivery_customization, payment_customization etc.)

  • 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:

  1. Gehen Sie zu Settings → Shipping and delivery

  2. Scrollen Sie nach unten zum Bereich Customizations

  3. Klicken Sie auf Add customization → wählen Sie Ihre Function aus

  4. Speichern

Die Regel ist live in der Produktivumgebung. Keine Mutation erforderlich.



Shopify delivery customization Function hiding shipping option at checkout

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.



Shopify Functions deployment pipeline across local staging and production environments

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.



Week-by-week migration roadmap from Shopify Scripts to Functions

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.



Developer migrating Shopify Scripts to Shopify Functions modules

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 eine run.graphql-Abfrage, um die benötigten Warenkorbdaten abzurufen, schreiben eine run.rs- oder run.js-Datei, die Werte (Rabatte, ausgeblendete Versandoptionen etc.) zurückgibt, deployen das Ganze mit shopify app deploy und 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 Report in 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 shopify app dev, Preview-Links

Deployment

Klick auf "Speichern" im Admin-Bereich

shopify app deploy im Terminal

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

cart.lines.discounts.generate.run

Shipping Script (Rabatt)

Kostenloser / rabattierter Versand basierend auf Warenkorbregeln

Cart & Checkout Discounts API

cart.delivery-options.discounts.generate.run

Shipping Script (Ausblenden / Umbenennen / Sortieren)

Versandart ab Wert X ausblenden, "Standard" in "Kostenlos ab 50 €" umbenennen

Delivery Customization API

cart.delivery-options.transform.run

Payment Script

PayPal für B2B ausblenden, Nachnahme ab 500 € sperren, Reihenfolge ändern

Payment Customization API

cart.payment-methods.transform.run

Cart-modifying Script (selten)

Produkte bündeln, Line Items austauschen

Cart Transform API

cart.transform.run

Block-checkout Script

Warenkorb ablehnen, wenn SKU-Kombination ungültig

Cart & Checkout Validation API

cart.validations.generate.run

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.



Shopify Functions unifying discounts, delivery, and payment customizations

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 (oder cart_checkout_validation, delivery_customization, payment_customization etc.)

  • 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:

  1. Gehen Sie zu Settings → Shipping and delivery

  2. Scrollen Sie nach unten zum Bereich Customizations

  3. Klicken Sie auf Add customization → wählen Sie Ihre Function aus

  4. Speichern

Die Regel ist live in der Produktivumgebung. Keine Mutation erforderlich.



Shopify delivery customization Function hiding shipping option at checkout

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.



Shopify Functions deployment pipeline across local staging and production environments

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.



Week-by-week migration roadmap from Shopify Scripts to Functions

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.



Developer migrating Shopify Scripts to Shopify Functions modules

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 eine run.graphql-Abfrage, um die benötigten Warenkorbdaten abzurufen, schreiben eine run.rs- oder run.js-Datei, die Werte (Rabatte, ausgeblendete Versandoptionen etc.) zurückgibt, deployen das Ganze mit shopify app deploy und 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 Report in 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 shopify app dev, Preview-Links

Deployment

Klick auf "Speichern" im Admin-Bereich

shopify app deploy im Terminal

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

cart.lines.discounts.generate.run

Shipping Script (Rabatt)

Kostenloser / rabattierter Versand basierend auf Warenkorbregeln

Cart & Checkout Discounts API

cart.delivery-options.discounts.generate.run

Shipping Script (Ausblenden / Umbenennen / Sortieren)

Versandart ab Wert X ausblenden, "Standard" in "Kostenlos ab 50 €" umbenennen

Delivery Customization API

cart.delivery-options.transform.run

Payment Script

PayPal für B2B ausblenden, Nachnahme ab 500 € sperren, Reihenfolge ändern

Payment Customization API

cart.payment-methods.transform.run

Cart-modifying Script (selten)

Produkte bündeln, Line Items austauschen

Cart Transform API

cart.transform.run

Block-checkout Script

Warenkorb ablehnen, wenn SKU-Kombination ungültig

Cart & Checkout Validation API

cart.validations.generate.run

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.



Shopify Functions unifying discounts, delivery, and payment customizations

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 (oder cart_checkout_validation, delivery_customization, payment_customization etc.)

  • 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:

  1. Gehen Sie zu Settings → Shipping and delivery

  2. Scrollen Sie nach unten zum Bereich Customizations

  3. Klicken Sie auf Add customization → wählen Sie Ihre Function aus

  4. Speichern

Die Regel ist live in der Produktivumgebung. Keine Mutation erforderlich.



Shopify delivery customization Function hiding shipping option at checkout

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.



Shopify Functions deployment pipeline across local staging and production environments

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.



Week-by-week migration roadmap from Shopify Scripts to Functions

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

The Universal Commerce Protocol UCP Guide How to Start a Shopify Store in 2026 The True Cost of Returns Guide How to Change Shipping Address on Shopify Best Shopify Customer Service Apps 10 Advanced Shopify Flow Workflows How to Add Discount on Shopify After Checkout How to Edit an Order on Shopify Shopify Draft Orders Complete Guide How to Do a Partial Refund on Shopify Shopify Social Login Complete Guide Post Purchase Email Marketing Automating E-commerce with Shopify Flow Customize Shopify Login Redirect Shopify New Customer Accounts Migration Guide How Poor Customer Support Can Sabotage Your Business How Refunds Work on Shopify In-House Warranty Management vs Shopify Apps Shopify Checkout Extensibility 2026: Deadline, Migration, and What's Broken How to Let Customers Cancel Orders on Shopify Shopify Legacy Customer Accounts Are Deprecated How to Edit Your Shopify Order Confirmation Email How to Do an Exchange on Shopify How to Sell on ChatGPT with Shopify Agentic Storefronts Shopify Functions Migration Tutorial Shopify AI Toolkit Guide 2026: Agents, MCP, and UCP Explained Shopify Sidekick vs Your Agency: The 2026 Scorecard for Plus Stores Shopify B2B 2026 Complete Guide Shopify Order Management Guide 2026 Shopify Advanced to Plus 2026 Migration Playbook 20 Shopify Flow AI Prompts Plus Operators Copy Shopify MCP Developer Guide 2026 EU Withdrawal Button for Shopify 2026 Best Shopify Order Editing Apps 2026