Anleitungen

Shopify

Noch nicht lauffähigProjektbaum für die Shopify-CLI (shopify app deploy)

Der Programmteil steht, aber es fehlt ein Schritt, den wir nicht allein gehen können. Was genau fehlt, steht in der Anleitung — bitte lesen Sie das, bevor Sie Zeit investieren.

Schon eingebaut? So legen Sie fest, welche Ware geprüft wird

Passwort: edelverify — Shopify lässt bei Entwicklungs-Shops keine offene Vorführung zu.

Als Datei: EINBAU.md · PRUEFPLAN.md

Einbau

EdelVerify für Shopify — Einbau

Altersprüfung über den Ausweis Ihrer Kundschaft. Diese Anleitung führt Sie durch die Einrichtung, auch wenn Sie mit Shopify noch nie etwas zu tun hatten. Sie brauchen dafür keine Programmierkenntnisse, aber Zugang zum Shopify-Admin Ihres Ladens.

Rechnen Sie mit 20 Minuten. Der einzige Schritt, den man vergessen kann und der dann alles Sichtbare abschaltet, ist Schritt 5.


0. Zuerst: Was Sie bekommen — und was nicht

Shopify betreibt die Kasse selbst. Fremder Code darf dort nur, was Shopify vorsieht. Für den Selbstbau-Weg, den diese Anleitung beschreibt, folgen daraus genau zwei Ausbaustufen — warum die Spalten nach dem Tarif heissen und wann das nicht mehr gilt, steht direkt unter der Tabelle:

Selbstbau-Wegohne Shopify Plusmit Shopify Plus
Hinweis und Prüffenster im Ladenjaja
Kassenknöpfe im Warenkorb gesperrtja (umgehbar)ja (umgehbar)
Sperre vor dem Bestellabschlussneinja, von Shopify erzwungen
Wirkt bei Apple Pay / Shop Pay / Google Payneinja
Jede betroffene Bestellung wird geprüftjaja
Ohne Nachweis: Versand angehalten, Bestellung markiertjaja

Warum hier «mit Plus» und «ohne Plus» steht — und wann es nicht gilt

Diese Anleitung beschreibt den Selbstbau-Weg: Sie laden dieses Paket herunter und veröffentlichen es mit der Shopify-CLI für Ihren eigenen Laden. Das ist eine *custom app*, und dafür gilt tatsächlich:

«Only stores on a Shopify Plus plan can use custom apps that contain Shopify Function APIs.»

Es gibt einen dritten Weg, und auf dem fällt diese Grenze weg. Kommt dieselbe App aus dem Shopify App Store, läuft die Sperre vor dem Bestellabschluss auf jedem Tarif, auch auf Basic:

«All plans: Except as noted in individual API pages, stores on any plan can use public apps that are distributed through the Shopify App Store and contain functions.» — https://shopify.dev/docs/api/functions/latest#api-availability

Unsere App-Store-Fassung ist in Arbeit. Bis sie dort steht, gilt für diesen Selbstbau-Weg die Tabelle oben unverändert. Wenn Sie kein Plus haben und auf die Sperre vor dem Bestellabschluss angewiesen sind: schreiben Sie uns, dann sagen wir Ihnen, wo die Zulassung gerade steht.

Und eine Ehrlichkeit vorweg, die für beide Wege gilt: Auch die Sperre an der Kasse ist kein vollständiger Riegel. Sie läuft nicht bei Vorbestellungen, nicht im Kassensystem im Laden, nicht bei Abo-Folgebestellungen und nicht bei nachträglich bearbeiteten Bestellungen. Was in allen diesen Fällen greift, ist die Prüfung nach dem Bestelleingang — die Zeile, die in der Tabelle oben in beiden Spalten «ja» trägt. Sie ist der Teil, auf den Sie sich verlassen können.


Und eine dritte Einschränkung: eine Grenze für den ganzen Laden

Die Altersprüfung kennt zwei Schwellen, 16 und 18. In WooCommerce, Shopware und Magento lässt sich die Grenze je Warengruppe setzen — Bier ab 16, Spirituosen ab 18, im selben Laden.

Auf dem Selbstbau-Weg, den diese Anleitung beschreibt, geht das nicht. Dort ist die Sammlung die Warengruppe, und dieser App-Block kennt genau eine. Es gilt deshalb eine Grenze für alles, was geprüft wird, und sie kommt aus der Vorgabe Ihres EdelVerify-Kontos (unter *Shops*, ab Werk 18). Im Theme lässt sie sich nicht einstellen, und das ist Absicht: Eine Grenze im Theme könnte von der Vorgabe abweichen, gegen die der Server den Nachweis wieder einlöst — Ihre Kundschaft sähe ein grünes Prüffenster und danach eine Absage.

Wer beides braucht, hat zwei Wege:

  1. Auf 18 stellen und Bier mitprüfen. Zu streng, aber nie zu lasch — und für die meisten Läden die richtige Antwort.
  2. Zwei Anbindungen: zwei Schlüsselpaare, zwei EdelVerify-Konten, zwei Läden. Aufwändig; sagen Sie uns, wenn Sie es brauchen, dann bauen wir es.

Mit der App-Store-Fassung fällt diese Einschränkung weg. Dort steht die Grenze je Sammlung — und wahlweise je Schlagwort am Produkt — in der EdelVerify-Seite im Shopify-Admin, und die Sperre an der Kasse rechnet sie mit: Bier ab 16, Spirituosen ab 18, im selben Warenkorb. Liegt beides darin, gilt die strengere. Diese Fassung ist gebaut und noch nicht zugelassen; wo die Zulassung steht, sagen wir Ihnen auf Anfrage.

Eines bleibt auch dort so: Das Prüffenster im Laden kennt den Warenkorb nicht. Es fragt deshalb immer nach der strengsten Grenze, die Ihr Laden verlangen kann — wer eine Sammlung auf «ab 18» stellt, dessen Gäste weisen 18 nach, auch beim Bier. Der Gewinn liegt bei der angemeldeten Kundschaft und bei dem, was die Kasse durchlässt, nicht bei der Frage im Prüffenster.

Die Grenze, die wirklich gilt, steht im Prüffenster: Es holt sie beim Start vom Dienst und schreibt sie hin («Über 16 bestätigt»). Sie muss dort nicht geraten werden.


Auf dem Selbstbau-Weg gibt es ohne Shopify Plus keine Altersprüfung vor dem Bestellabschluss. Der Grund dafür ist nicht der Tarif Ihres Ladens, sondern der Vertriebsweg der App — die Function hängt daran, nicht am Abonnement: Custom App, deshalb die Grenze. Ob sie für Sie gilt, hängt damit an einem einzigen offenen Punkt, und den kennen nur wir: ob unsere App im Shopify App Store zugelassen ist. Fragen Sie uns danach, bevor Sie deswegen den Tarif wechseln.

Die Zusage ohne diese Sperre lautet: *Jede betroffene Bestellung wird binnen Sekunden geprüft und ohne Nachweis vom Versand angehalten.* Die Bestellung entsteht, das Geld wird eingezogen, nur die Ware geht nicht raus.

Mit Shopify Plus kommt eine echte Sperre dazu, die auch bei Apple Pay greift. Sie prüft aber nur, ob ein Nachweis-Kennzeichen im Warenkorb liegt, nicht ob es echt ist. Wer weiss, was er tut, setzt es sich selbst — und wird dann nach der Bestellung gefasst, genau wie ohne Plus.

Alles, was mit Plus zu tun hat, steht in dieser Anleitung unter «Nur mit Plus». Ohne Plus überspringen Sie diese Abschnitte ersatzlos.


1. Was Sie bereithalten müssen

  • Zugang zum Shopify-Admin Ihres Ladens (Rolle: Inhaber oder ein Mitarbeiter mit den Rechten «Apps und Vertriebskanäle» und «Themes»)
  • Das Paket: https://verify.edelbyte.ch/v1/shopify/edelverify-shopify.zip — der Projektbaum für die Shopify-CLI, samt dieser Anleitung und dem Prüfplan
  • Ihre beiden EdelVerify-Schlüssel aus Ihrem Konto, siehe unten:
  • öffentlicher Schlüssel, beginnt mit pk_live_ (zum Testen: pk_test_)
  • geheimer Schlüssel, beginnt mit sk_live_ (zum Testen: sk_test_)
  • Ihre myshopify.com-Adresse — den Laden selbst richten wir für Sie ein (siehe Schritt 3); einen Installationslink gibt es erst mit der Fassung aus dem Shopify App Store
  • ein Android-Handy mit der EdelVerify-App und einem Ausweis, um am Ende selbst zu probieren — welche Dokumente durchkommen, steht in Abschnitt 1b

Der geheime Schlüssel gehört nie ins Theme. Er wird ausschliesslich im EdelVerify-Bereich der App eingetragen (Schritt 4) und liegt dort auf unserem Server. Was im Theme steht, kann jeder Besucher lesen.

Woher Sie die Schlüssel bekommen

Das Konto entsteht automatisch: Sie buchen unter https://verify.edelbyte.ch/preise einen Tarif — mit Karte oder TWINT —, und das Schlüsselpaar steht unmittelbar danach bereit. Zum Bauen genügen die Testschlüssel pk_test_… und sk_test_…; der Testbetrieb ist dauerhaft gratis. Herkunft und Altersgrenze tragen Sie im Konto unter «Einstellungen» selbst ein.

Was bei Shopify — anders als bei WooCommerce, Shopware und Magento — nicht selbstbedient läuft, ist der Laden: Solange unsere App nicht im Shopify App Store steht, richten wir ihn für Sie ein (Schritte 3 und 4). Melden Sie uns dafür Ihre myshopify.com-Adresse und Ihre eigene Domain.

  • E-Mail: info@edelbyte.ch
  • Telefon: 044 500 25 04

Was es kostet

Ab 19 Franken im Monat, keine Gebühr je Prüfung, monatlich kündbar und ohne Vorauszahlung. Über dem Kontingent kostet eine bestandene Prüfung 10 Rappen, nie mehr als der nächsthöhere Tarif — abgeschaltet wird die Prüfung nie. Die Stufen stehen unter https://verify.edelbyte.ch/preise. Der Testbetrieb kostet nichts, und zwar dauerhaft. Für Shopify kommt hinzu, was in Abschnitt 0 steht: Solange die App nicht aus dem Shopify App Store kommt, verlangt der Riegel vor dem Bestellabschluss Shopify Plus. Das ist ein Preis, den Shopify stellt, nicht wir — und er entfällt, sobald die App dort steht.

Was Sie dafür heute nicht bekommen: Nachweise über die staatliche E-ID. Der Weg ist gebaut und abgeschaltet, weil der Bund die Einführung am

  1. Juni 2026 verschoben hat und kein neues Datum nennt. Was heute läuft, ist

der Ausweis selbst — und was er belegt, steht im nächsten Abschnitt.

Die vollständige technische Anleitung — Schnittstelle, Fehlerschlüssel, Webhook, Testausgänge — steht unter https://verify.edelbyte.ch/entwickler


1b. Wer kommt durch, und womit

Geprüft wird über den Ausweis Ihrer Kundschaft. Es gibt vier Wege, und sie belegen nicht dasselbe — das ist die Entscheidung, die Sie treffen, und keine Fussnote:

WegBelegtBelegt nicht
Staatliche E-IDEinen vom Bund signierten Nachweis, geprüft gegen das eidgenössische Vertrauensregister. Der stärkste Nachweis, den es gibt.Nichts, was fehlte — aber heute abgeschaltet: Der Bund hat die Einführung am 30. Juni 2026 verschoben und nennt kein neues Datum.
Ausweischip (App)Dass das Dokument körperlich vorlag: Der Chip gibt nur etwas heraus, wenn ihm die abgelesenen Zeilen der Datenseite gezeigt werden.Dass das Dokument echt ist — dafür fehlt die Prüfung gegen die Länderzertifikate. Und nicht, dass die meldende App unverändert ist.
Ausweiszeilen (App)Formal gültige Zeilen eines amtlichen Ausweises: Prüfziffern gehen auf, Bauform stimmt, Dokument nicht abgelaufen.Dass das Dokument vorlag — ein Foto der Rückseite genügt. Die Kamera unterscheidet ein Dokument nicht von seinem Abbild.
Ausweiszeilen (Browser)Dasselbe, ohne App; die Prüfziffern rechnet unser Server, nicht der Browser.Zusätzlich die Zusage, dass überhaupt gelesen wurde. Das Fenster läuft im Browser der Kundschaft. Die schwächste Stufe, die es gibt.

Die beiden Zeilen-Stufen sind ab Werk aus. Ihr Laden verlangt den Chip, solange Sie nichts anderes sagen; freischalten lassen sie sich über info@edelbyte.ch — nachdem Sie die rechte Spalte gelesen haben. Einen Wahlschirm bekommt Ihre Kundschaft nicht zu sehen: Solange der E-ID-Weg abgeschaltet ist, startet die Ausweisprüfung sofort.

Welche Dokumente durchkommen: Schweizer Pass und Ausländerausweis über den Chip, ab Werk. Die Schweizer Identitätskarte trägt keinen Chip und kommt über die Ausweiszeilen durch — sie funktioniert also nur, wenn Sie diese Stufe freigeschaltet haben; die biometrische Identitätskarte mit Chip ist ab

  1. November 2026 beantragbar. Ausländische Pässe und Ausweise mit

maschinenlesbaren Zeilen ebenso.

Die App, die Chip und Zeilen liest, steht seit dem 20. August 2026 für Android im Play Store (https://play.google.com/store/apps/details?id=ch.edelbyte.edelverify). Die Fassung fürs iPhone ist in Arbeit; ein Datum nennen wir dafür nicht, weil die Prüfzeit bei Apple nicht in unserer Hand liegt. Wer kein Android-Gerät hat, kommt heute nur über die Ausweiszeilen im Browser durch — und auch das nur, wenn Sie diese Stufe freigeschaltet haben.


2. Die Artikel bestimmen, die geprüft werden sollen

Shopify braucht eine Liste, welche Artikel altersbeschränkt sind. Dafür dient eine Collection (deutsch im Admin: «Kategorie» bzw. «Sammlung»).

  1. Shopify-Admin → Produkte → Sammlungen → Sammlung erstellen
  2. Titel z. B. Altersgeprüft 18+
  3. Sammlungstyp: manuell oder automatisch, wie es Ihnen lieber ist
  4. Speichern und die betroffenen Artikel hinzufügen
  5. Wichtig: Rechts unter Vertriebskanäle muss Online Store angehakt sein.
  6. Notieren Sie den Handle. Er steht ganz unten auf der Seite der Sammlung unter «Vorschau der Suchmaschinenliste» → Bearbeiten → in der URL, z. B. altersgeprueft-18.

Warum der Vertriebskanal wichtig ist: Eine Sammlung, die im Online Store nicht verfügbar ist, sieht Ihr Theme nicht — der Hinweis im Laden bliebe dann aus. Geprüft würde die Bestellung trotzdem, aber der Kunde erführe erst hinterher davon. Das ist der ungünstigste aller Fälle.

Lassen Sie das Feld später leer, wenn *alles* in Ihrem Laden altersbeschränkt ist. Leer heisst ausdrücklich der ganze Shop, nicht «nichts».


3. Die App installieren

Diese App lässt sich heute noch nicht selbst installieren. Es gibt keinen Installationslink, den Sie öffnen könnten: Der OAuth-Weg von Shopify ist bei uns nicht gebaut — die Rückrufadressen, die Shopify nach der Zustimmung anspringen würde, antworten mit 404. Auch einen EdelVerify-Bereich im Shopify-Admin gibt es nicht: Unsere Seiten verbieten die Einbettung ausdrücklich (X-Frame-Options: DENY, frame-ancestors 'none'), ein eingebetteter Bereich kann dort also gar nicht erst erscheinen.

Stattdessen legt EdelByte Ihren Shop von Hand an. Sagen Sie uns Ihre myshopify.com-Adresse; wir richten die Anbindung ein und melden uns mit den Angaben, die Sie für Schritt 5 brauchen. Die Berechtigungstabelle unten beschreibt, was die App dabei erhält — lesen Sie sie, auch wenn Sie nichts anzuklicken haben.

Shopify zeigt in der Zustimmung, welche Berechtigungen die App verlangt. Jede hat genau einen Grund:

BerechtigungWofür
Bestellungen lesendie neue Bestellung überhaupt sehen
Bestellungen bearbeitenKennzeichen, Notiz und Prüfvermerk an die Bestellung schreiben
Produkte lesenprüfen, ob ein Artikel aus Ihrer Sammlung bestellt wurde
Fulfillment (eigenes Lager und Dienstleister)den Versand anhalten, wenn kein Nachweis vorliegt
App-Proxydie Rückmeldung des Prüffensters unter Ihrer eigenen Domain entgegennehmen

Jeder Shopify-Shop braucht eine eigene Anbindung. Nur wenn Ihre Shops in derselben Plus-Organisation liegen, genügt eine.


4. Schlüssel eintragen

Auch dieser Schritt läuft heute über uns. Es gibt keinen EdelVerify-Bereich im Shopify-Admin, in dem Sie etwas eintragen könnten — aus demselben Grund wie in Schritt 3. Wir hinterlegen die folgenden Angaben für Sie; melden Sie sie uns, dann ist der Schritt in wenigen Minuten erledigt:

  1. Geheimer Schlüssel (sk_live_…). Er bleibt auf unserem Server und wird nie an den Browser ausgeliefert. Schicken Sie ihn uns nicht per E-Mail — wir erzeugen ihn ohnehin selbst und teilen ihn Ihnen mit.
  2. Sammlung → den Handle aus Schritt 2, z. B. altersgeprueft-18.
  3. Nicht geprüfte Bestellungen automatisch stornieren bleibt aus. Eine Stornierung ist bei Shopify unumkehrbar; ein angehaltener Versand ist in zehn Sekunden wieder freigegeben. Sagen Sie uns ausdrücklich Bescheid, wenn Sie das anders wollen.
  4. Verbindung prüfen. Wir prüfen für Sie nach, ob die Prüfstelle erreichbar ist, ob der geheime Schlüssel angenommen wird und ob Ihr Laden als Herkunft zugelassen ist, und melden Ihnen das Ergebnis zurück.

Den öffentlichen Schlüssel (pk_live_…) tragen Sie im nächsten Schritt im Theme ein — dorthin gehört er, und nur dorthin. Das ist der erste Schritt, den Sie wirklich selbst machen.


5. Den App-Block im Theme einschalten — der Schritt, den man vergisst

Shopify schaltet Blöcke einer App nicht von selbst ein. Solange Sie das nicht tun, ist im Laden nichts von der Altersprüfung zu sehen.

  1. Shopify-Admin → Onlineshop → Themes
  2. Beim aktiven Theme auf Anpassen
  3. Links in der Seitenleiste ganz unten auf App-Einbettungen (englisch: *App embeds*)
  4. Altersprüfung (EdelVerify) finden und den Schalter auf ein stellen
  5. Auf den Namen klicken — jetzt erscheinen die Einstellungen:
  6. Öffentlicher Schlüssel: pk_live_… einsetzen
  7. Collection der altersbeschränkten Artikel: der Handle aus Schritt 2, oder leer für den ganzen Shop
  8. Kassenknöpfe ohne Nachweis sperren: eingeschaltet lassen
  9. Die technischen Einstellungen darunter bleiben, wie sie sind
  10. Oben rechts Speichern

Was passiert, wenn Sie diesen Schritt vergessen

Im Laden erscheint kein Prüffenster und kein Hinweis. Kunden bestellen altersbeschränkte Ware, ohne je nach ihrem Alter gefragt worden zu sein.

Die Bestellungen werden trotzdem geprüft und ohne Nachweis vom Versand angehalten — Sie sitzen dann also auf lauter angehaltenen Bestellungen von Kunden, die gar nicht wussten, dass sie etwas hätten bestätigen sollen. Jede einzelne müssen Sie von Hand nachfassen.

Mit Plus kommt hinzu: Die Kasse blockt, aber im Laden gibt es keinen Weg, die Prüfung zu bestehen. Ihre Kunden stehen vor einer verschlossenen Tür ohne Klinke.

Prüfen Sie es deshalb sofort nach: Schritt 7.

Wechseln Sie das Theme später (oder installieren ein neues), müssen Sie diesen Schritt im neuen Theme wiederholen.


6. Der Webhook — nichts zu tun, aber gut zu wissen

Das Abonnement auf orders/create bringt die App mit; Sie müssen im Admin nichts einrichten. Es ist die verbindliche Prüfung: Innerhalb von Sekunden nach jeder Bestellung entscheidet unser Server, ob ein Nachweis vorliegt.

Was Sie danach an der Bestellung sehen:

FallKennzeichenWeitere Wirkung
geprüftedelverify:geprueftPrüfvermerk auf der Bestellseite
nicht geprüftedelverify:ungeprueftVersand angehalten, Notiz, Risiko «hoch»
nichts Altersbeschränktes dabeiedelverify:nicht-noetig—
Testbetriebzusätzlich edelverify:test—

Nach den Kennzeichen können Sie die Bestellliste filtern: tag:edelverify-ungeprueft. Eine eigene Spalte in der Bestellliste erlaubt Shopify einer App nicht.

Reicht ein Kunde den Nachweis nach, geben Sie den Versand im EdelVerify-Bereich wieder frei — oder in Shopify direkt beim jeweiligen Versandauftrag über Halten aufheben.


7. Probekauf — bitte wirklich machen

  1. Legen Sie einen altersbeschränkten Artikel in den Warenkorb.
  2. Unten erscheint der Streifen «Ihr Warenkorb enthält altersbeschränkte Artikel …». Erscheint er nicht, ist Schritt 5 nicht erledigt — oder die Sammlung ist nicht im Online Store verfügbar (Schritt 2, Punkt 5).
  3. Öffnen Sie die Warenkorbseite. Es legt sich eine Ebene darüber.
  4. Alter bestätigen → QR-Code erscheint → mit der EdelVerify-App scannen, den Ausweis lesen lassen, bestätigen.
  5. Das Fenster wird grün, danach lädt die Seite neu, Streifen und Ebene sind weg.
  6. Bestellen Sie zu Ende und öffnen Sie die Bestellung im Admin: Sie trägt edelverify:geprueft.

Die Reihenfolge in Punkt 5 ist wichtig. Lädt die Seite neu, bevor das Fenster grün wird, ist etwas falsch eingerichtet — melden Sie es uns, statt es zu wiederholen: Ein Nachweis wird genau einmal ausgeliefert.


8. Nur mit Plus: die erzwungene Sperre einschalten

Ohne Shopify Plus überspringen Sie diesen Abschnitt: Auf dem Selbstbau-Weg lässt sich die Function dann nicht aktivieren. Das ist kein Fehler und auch nicht Ihr Tarif allein — Shopify beschränkt Functions in Custom Apps auf Plus, in Public Apps aus dem App Store nicht. Kommt unsere App dort an, entfällt diese Hürde; wo die Zulassung gerade steht, sagen wir Ihnen auf Anfrage.

  1. Die App muss mit der Berechtigung Validierungen installiert sein. Ist sie erst nachträglich dazugekommen, fragt Shopify Sie erneut um Zustimmung.
  2. Im Shopify-Admin: **Einstellungen → Checkout → Validierungen → Validierung hinzufügen**, dann «EdelVerify Altersprüfung» wählen. Lassen Sie sie danach eingeschaltet.
  3. Stellen Sie dort auch **«Checkout blockieren, wenn die Regel nicht ausgeführt werden kann»** ein. Ab Werk ist das aus, und aus heisst: Fällt die Regel aus, geht die Bestellung durch.
  4. Probekauf wiederholen, diesmal ohne Bestätigung: Der Checkout muss die Bestellung mit der Meldung «Bitte bestätigen Sie zuerst, dass Sie über 18 sind …» verweigern — auch über Apple Pay oder Shop Pay.

Höchstens 25 solcher Validierungen sind je Shop möglich; unsere ist eine davon.

Auf dem Selbstbau-Weg von Hand angelegt, prüft die Regel den GANZEN Laden ab 18. Sie liest ihre Einstellungen aus zwei Metafeldern, die nur die App-Store-Fassung schreibt; findet sie keine, fällt sie auf die strengste Auslegung zurück. Das ist Absicht — eine Regel, die sich durch eine fehlende Einstellung öffnen lässt, wäre keine —, aber Sie sollten es wissen, bevor Sie sich über einen Streifen an der Kaffeetasse wundern.


9. Wenn etwas nicht tut

BeobachtungHäufigste Ursache
Kein Streifen im LadenApp-Block nicht eingeschaltet (Schritt 5) oder im neuen Theme nicht wiederholt
Streifen erscheint bei jedem ArtikelSammlungsfeld ist leer — das heisst «ganzer Shop»
Streifen erscheint nie, obwohl der Artikel in der Sammlung istSammlung nicht im Vertriebskanal «Online Store»
Fenster öffnet nicht, Meldung «gerade nicht erreichbar»falscher oder fehlender öffentlicher Schlüssel, oder Ihre Domain ist im EdelVerify-Admin nicht als Herkunft zugelassen
Alles bestätigt, Bestellung trotzdem ungeprueftgeheimer Schlüssel falsch (Schritt 4, «Verbindung prüfen»)
Sperre wirkt nicht bei Apple Payohne Plus so vorgesehen; mit Plus: Schritt 8 nicht ausgeführt

10. Was Sie Ihren Kunden gegenüber sagen können

  • Übermittelt wird eine einzige Angabe: Altersgrenze erfüllt oder nicht. Kein Name, kein Geburtsdatum, keine Ausweiskopie.
  • An der Bestellung steht nur, dass, wann und gegen welche Grenze geprüft wurde — der Nachweis selbst wird nirgends gespeichert.
  • Geprüft wird über den Ausweis: den Chip im Pass oder Ausländerausweis, und — wenn Sie die Stufe freischalten — über die maschinenlesbaren Zeilen, mit denen auch die Schweizer Identitätskarte durchkommt. Die staatliche E-ID ist eingebaut und wird freigeschaltet, sobald der Bund sie ausgibt.

Prüfplan

Damit nehmen Sie den Einbau selbst ab, ohne uns zu fragen. Geht ein Punkt nicht durch, schicken Sie ihn uns mit der Nummer — dann wissen wir sofort, wo wir suchen.

Prüfplan — Shopify-Seite

Was hier steht, liess sich ohne einen echten Shopify-Shop nicht klären. Alles, was sich an der Dokumentation klären liess, ist aus dieser Liste entfernt und steht am Ende unter «Was bereits belegt ist» — damit niemand dieselbe Arbeit zweimal macht.

Sortiert nach Risiko: Wer oben abbricht, braucht unten nicht weiterzulesen.

Es geht durchgehend um den Shop-seitigen Teil: shopify.app.toml, Theme App Extension, Validation Function. Der Server (App Proxy, Webhook, Admin-API-Aufrufe) hat seinen eigenen Plan.

Zur Altersgrenze steht hier nichts zu prüfen — und das ist der Befund. Die Schnittstelle kann gegen 16 oder gegen 18 prüfen, und die anderen drei Pakete stellen das je Warengruppe ein. Dieses Paket nicht: Shopifys Warengruppe ist die Sammlung, und der App-Block kennt genau eine. Es gilt deshalb eine Grenze für alles, und sie kommt aus der Vorgabe des EdelVerify-Kontos — dieselbe, gegen die der App-Proxy den Nachweis wieder einlöst.

Der Block schickt bewusst kein min_age mit. Täte er es, könnte die Grenze im Theme von der Vorgabe abweichen: Der Laden startete eine 16er-Prüfung, der Server verlangte 18, und die Kundschaft sähe ein grünes Prüffenster und danach eine abgewiesene Rückmeldung. Nachgeprüft wird das statisch: python3 scripts/pakete-pruefen.py, Abschnitt K — «setzt die Grenze nirgends selbst».

Die Einschränkung steht ausführlich in EINBAU.md, Abschnitt 0. Sie gehört ins Verkaufsgespräch, nicht in eine Fussnote nach der Installation.

Es gibt keinen Installationsweg — und auch das ist ein Befund, kein Prüfpunkt. Der OAuth-Weg ist nicht gebaut: Die Rückrufadressen, die Shopify nach der Zustimmung anspringen würde, antworten auf verify.edelbyte.ch mit 404 (gemessen für /auth/callback und /auth/shopify/callback). Ein eingebetteter App-Bereich im Shopify-Admin ist ebenfalls ausgeschlossen: Die Seiten liefern X-Frame-Options: DENY und frame-ancestors 'none', ein Rahmen kann dort also nie rendern.

Solange das so ist, legt EdelByte jeden Shop von Hand an, und alle Einstellungen aus EINBAU.md, Schritt 4, nehmen wir vor. Für diesen Prüfplan heisst das: Die Prüfungen unten setzen einen bereits von Hand angelegten Entwicklungsshop voraus — sie prüfen den Shop-seitigen Teil, nicht die Installation. Wer den OAuth-Weg baut, braucht dafür einen eigenen Plan; die Prüfungen hier decken ihn nicht ab.


0. Umgebung

npm install -g @shopify/cli@latest
shopify version

# Im Ordner der App:
shopify app config link          # verbindet mit der App im Dev Dashboard
shopify app dev --store=<dev-store>.myshopify.com

Ausserdem gebraucht:

  • ein Entwicklungsshop mit einem Online-Store-2.0-Theme (Dawn genügt) und einer Sammlung, die im Vertriebskanal «Online Store» verfügbar ist
  • ein EdelVerify-Testkonto mit pk_test_… / sk_test_…; die Domain des Entwicklungsshops muss dort als erlaubte Herkunft eingetragen sein, sonst scheitert Prüfung 6 und man sucht den Fehler im falschen System
  • ein Android-Handy mit der EdelVerify-App und einem Ausweis. Der E-ID-Weg ist abgeschaltet (EID_WEG_AKTIV, Vorgabe aus) — geprüft wird der Ausweis, und es gibt keinen Wahlschirm davor.
  • für Weg B: ein Shop mit Shopify Plus. Ein gewöhnlicher Entwicklungsshop genügt nicht — Functions in Custom-Apps sind Plus vorbehalten. Ob ein Partner-Development-Store die Plus-Merkmale mitbringt, ist selbst zu prüfen (Prüfung 9).
  • eine Rust-Werkzeugkette samt Wasm-Ziel:
  curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  rustup target add wasm32-unknown-unknown

Auf dem Rechner, auf dem dieses Paket zuletzt bearbeitet wurde, war sie nicht vorhanden (cargo not found). Der Rust-Teil ist deshalb bis heute nie übersetzt worden — siehe Prüfung 3, und lesen Sie sie, bevor Sie sich auf die Function verlassen.


Hoch

1. Überlebt ein Warenkorb-Attribut mit führendem Unterstrich die Bestellung?

Die ganze Bindung des Nachweises an die Bestellung hängt daran. Belegt ist nur, dass doppelter Unterstrich das Attribut überall verschwinden lässt; über den einfachen sagt die Dokumentation nichts.

Erste Bauhandlung, vor allem anderen. Im Laden, in der Browserkonsole:

await fetch(window.Shopify.routes.root + 'cart/update.js', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    attributes: { _edelverify: 'mit-strich', edelverify: 'ohne-strich' },
  }),
}).then((r) => r.json())

Dann eine Testbestellung abschliessen und nachsehen:

# Nutzdaten des Webhooks (Server-Log) — Feld note_attributes
# und/oder über die Admin API:
shopify app function replay   # nein, hier nicht; stattdessen:
query {
  orders(first: 1, reverse: true) {
    nodes { name customAttributes { key value } }
  }
}

Erwartet: beide Schlüssel kommen an. Wenn nur `edelverify` ankommt: an drei Stellen umstellen und nirgends sonst — blocks/edelverify.liquid (ev_attribut), src/cart_validations_generate_run.graphql (attribute(key:)) und die Webhook-Auswertung im Server.

2. Sieht die Validation Function dasselbe Attribut? *(nur mit Plus)*

Auch wenn das Attribut in der Bestellung ankommt, ist damit nicht gesagt, dass cart.attribute(key: "_edelverify") in der Function-Eingabe etwas liefert.

shopify app function run          # mit einer eigenen Eingabe-JSON
shopify app function replay       # mit einer echten Ausführung aus dem Shop

Erwartet: In der Eingabe der abgespielten Ausführung steht "attribute": { "value": "…" }. Steht dort null, obwohl das Attribut im Warenkorb liegt, ist die Function auf Plus wirkungslos — dann bleibt nur der Webhook, und das gehört dem Kunden gesagt.

3. Übersetzt die Function überhaupt?

Der Rust-Teil ist ein Gerüst. Die erzeugten Typpfade (schema::cart_validations_generate_run::input::cart::lines::Merchandise) und die Rückgabearten der Zugriffsmethoden (&String gegen &str, &bool gegen bool) stammen aus der Dokumentation, nicht aus einem Übersetzungslauf.

cd extensions/edelverify-gate
shopify app function schema          # holt schema.graphql
rustup target add wasm32-unknown-unknown
cargo build --target=wasm32-unknown-unknown --release
cargo doc --open                     # zeigt die tatsächlich erzeugten Typen
ls -l target/wasm32-unknown-unknown/release/edelverify_gate.wasm

Erwartet: Übersetzung ohne Fehler, Datei unter 256 kB. Weicht ein Typpfad ab, steht die richtige Schreibweise in cargo doc; die Logik bleibt davon unberührt.

Stand: nie ausgeführt. Zwei Gründe, beide handfest:

  1. Auf dem Rechner, auf dem dieses Paket gepflegt wird, gibt es kein cargo.
  2. schema.graphql liegt nicht im Paket und kann dort auch nicht liegen: Sie wird mit shopify app function schema geholt und setzt ein angemeldetes Partnerkonto samt verbundener App voraus. Ohne sie schlägt schon #[typegen("schema.graphql")] in main.rs fehl — und damit auch `cargo test, obwohl die Tests in cart_validations_generate_run.rs` keinen einzigen Shopify-Typ anfassen.

Was daraus folgt: Der erste Bau auf einem eingerichteten Rechner ist keine Formsache, sondern die erste echte Prüfung dieses Codes. Die naheliegenden Fundstellen sind die Zugriffsmethoden der Aliase (kollektion16(), schlagwort18() — typegen leitet sie aus der Eingabeabfrage ab) und die Rückgabearten (&bool gegen bool).

cargo test ist danach der zweite Schritt und der wichtigere: Die Entscheidungstabelle in mod tests ist die einzige Stelle, an der die Regel «18 schlägt 16» im Rust überhaupt zugesichert ist.

Ebenfalls hier zu klären: ob die erzeugte Wasm-Datei bei einem Paketnamen mit Unterstrich tatsächlich edelverify_gate.wasm heisst — der Pfad in shopify.extension.toml muss stimmen, sonst schlägt der Deploy fehl.

4. Der Cart-Token in der Rückmeldeadresse

Unser Skript hängt den Token aus GET /cart.js als ?ct= an die Proxy-Adresse. Zwei Fragen auf einmal:

  1. Reicht der App Proxy eigene Abfrageparameter durch und nimmt sie in die Signatur auf? (Das Beispiel in der Dokumentation zeigt extra=1&extra=2 — aber unser Wert enthält selbst ein ?key=…, also kodierte Sonderzeichen.)
  2. Ist der Wert derselbe wie cart_token in den Nutzdaten von orders/create, oder nur der Teil vor ?key=?

Handgriff: Im Laden eine Prüfung durchführen, im Server-Log die ankommende URL und den berechneten Signaturvergleich mitschreiben; danach die Bestellung abschliessen und cart_token aus dem Webhook danebenlegen.

Erwartet: Signatur stimmt, und die beiden Token lassen sich aufeinander abbilden. Wenn nicht, wird serverseitig auf den Teil vor ?key= normalisiert — an einer Stelle, nicht an zweien.

5. Wird `gate.js` von einer Content-Security-Policy geblockt?

Das Skript lädt https://verify.edelbyte.ch/v1/gate.js dynamisch nach. Setzt das Theme (oder eine andere App) eine CSP mit script-src, ohne unsere Domain zu nennen, passiert nichts — und zwar lautlos ausser einer Meldung in der Konsole.

Handgriff: Warenkorbseite öffnen, Konsole beobachten, dann auf «Alter bestätigen» klicken.

Erwartet: Das Skript lädt, window.EdelVerify existiert, das Fenster geht auf. Bei einer CSP-Meldung: mit dem Theme-Anbieter klären, ob verify.edelbyte.ch in script-src und connect-src aufgenommen werden kann.


Mittel

6. Die Prüfung von Anfang bis Ende, mit echtem Ausweis

  • [ ] Streifen erscheint, sobald ein Artikel der Sammlung im Warenkorb liegt
  • [ ] Auf der Warenkorbseite legt sich die Ebene darüber; Escape schliesst sie
  • [ ] «Alter bestätigen» öffnet das Fenster von gate.js, QR erscheint
  • [ ] In der EdelVerify-App den Ausweis lesen lassen → Fenster wird grün
  • [ ] Im Netzwerk-Tab: POST /apps/edelverify/confirm?ct=… antwortet 200 {"ok":true} vor dem Neuladen
  • [ ] Danach POST /cart/update.js mit dem Attribut, dann Neuladen (~0,9 s)
  • [ ] Nach dem Neuladen: kein Streifen mehr, Kassenknöpfe frei

Die Reihenfolge der letzten drei Punkte ist der Test. Lädt die Seite neu, bevor /confirm geantwortet hat, wird die Übermittlung abgebrochen und der Nachweis ist verbrannt — er wird genau einmal ausgeliefert. Deshalb hängt das Neuladen an edelverify:stored, nicht an edelverify:verified.

Danach ins Server-Log sehen: weder `sk_…` noch `av_…` darf dort auftauchen.

7. Überschreibt `cart/update.js` fremde Attribute?

Manche Themes und Apps schreiben selbst Warenkorb-Attribute. Ob unser Aufruf nur den eigenen Schlüssel setzt oder die übrigen mitnimmt, ist zu messen — sonst löschen wir einem anderen etwas weg (oder umgekehrt, und unser Nachweis verschwindet beim nächsten Klick des Themes).

await fetch(window.Shopify.routes.root + 'cart/update.js', {
  method: 'POST', headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ attributes: { fremd: 'bleibt?' } }),
}).then(r => r.json())
// dann unser Attribut setzen und erneut GET /cart.js lesen

Erwartet: fremd steht danach noch da.

8. Kassenknöpfe in echten Themes

Die Auswahl [name="checkout"], .shopify-payment-button__button, form[action*="/checkout"] [type="submit"] deckt Dawn ab. Ein gekauftes Theme kann andere Knöpfe haben, vor allem in der Warenkorb-Schublade.

  • [ ] Dawn: Warenkorbseite und Schublade
  • [ ] Das Theme des Kunden, beide Orte
  • [ ] Nach dem Öffnen/Schliessen der Schublade greift die Sperre weiterhin (Beobachter)
  • [ ] Express-Checkouts (Shop Pay, Apple Pay, Google Pay) gehen daran vorbei — das ist erwartet und ohne Plus nicht zu ändern. Trotzdem einmal ansehen, damit es niemanden überrascht.

9. Läuft die Function auf dem Zielsystem überhaupt? *(nur mit Plus)*

Zu klären, bevor irgendetwas zugesagt wird:

  • Tarif je Shop des Kunden (nur Plus kann Custom-Apps mit Functions)
  • ob die Shops in einer Plus-Organisation liegen (entscheidet, ob eine Installation genügt)
  • ob ein Partner-Development-Store die Function annimmt (zum Entwickeln)
shopify app deploy
# danach im Admin: Einstellungen → Checkout → Validierungen

Erwartet: Die Validierung erscheint und lässt sich einschalten. Kommt eine Tarifmeldung, ist Weg B für diesen Shop erledigt — dann gilt Weg A, und das gehört ins Kundengespräch, nicht in ein Ticket.

10. Instruktionsbudget

Erst messen, dann die Härtung aus Bauvorgabe 6.5 (signiertes Attribut mit HMAC-SHA256) zusagen.

shopify app function replay

Erwartet: Die einfache Fassung liegt weit unter den Referenzbeispielen (17 177 bzw. 19 272 Instruktionen für vergleichbare Prüfungen). Erst wenn HMAC-SHA256 dazukommt, wird es eng — dann hier nachmessen, nicht schätzen.

11. Der Umfang der Function

Die Collection-IDs stehen als Literal in der Eingabeabfrage und werden beim Deploy eingesetzt; das Metafeld edelverify/config entscheidet nur zwischen «ganzer Shop» und «nur diese Collection».

  • [ ] Metafeld gesetzt (metafieldsSet auf die Validation) → Function sieht den Wert in der Eingabe
  • [ ] Metafeld nicht gesetzt → jeder Warenkorb gilt als altersbeschränkt (gewollt: fail-closed), und der Händler merkt es sofort
  • [ ] Platzhalter COLLECTION_ID_EINSETZEN nicht ersetzt → dieselbe Wirkung wie ohne Metafeld, nie eine stille Freigabe

Niedrig

12. Theme-Editor: Block, Einstellungen, Übersetzungen

  • [ ] Altersprüfung (EdelVerify) erscheint unter Theme-Einstellungen → App-Einbettungen
  • [ ] Alle sechs Einstellungen sind da, mit deutschen Beschriftungen — steht dort roher Text wie t:settings.public_key.label, findet Shopify die Schema-Sprachdateien nicht
  • [ ] Der Direktlink zum Einschalten funktioniert: https://<shop>.myshopify.com/admin/themes/current/editor?context=apps&template=index&activateAppId=<client_id>/edelverify (der letzte Teil ist der Dateiname des Blocks, nicht der Name der Extension)
  • [ ] Im Editor erscheint der Streifen, ohne dass etwas gesperrt wird (Shopify.designMode)

13. Sprachwahl im Laden

  • [ ] Ein deutschsprachiger Laden zeigt die Texte aus de.json
  • [ ] fr / it ebenso
  • [ ] Eine nicht abgedeckte Sprache fällt auf en.default.json zurück und zeigt Englisch — keine leeren Streifen, keine Schlüsselnamen

Offen ist dabei, ob eine Theme App Extension zwingend en.default.json als Vorgabedatei verlangt oder auch de.default.json annähme. Deshalb liegt Englisch als Vorgabe bei; das ist die risikoärmere Wahl, nicht die schönste.

14. Auswahlfeld statt Handle

Die Sammlung wird heute als Text (Handle) eingetragen. Schöner wäre ein Auswahlfeld ("type": "collection"). Belegt ist nur, dass Resource-Settings in App blocks existieren; für App embed blocks sagt die Dokumentation nichts, und sie können ausdrücklich nicht auf dynamische Quellen zeigen.

Handgriff: In einer Wegwerf-Fassung des Blocks "type": "collection" setzen, shopify app deploy, im Editor nachsehen. Wird das Feld angeboten und liefert block.settings.collection.handle einen Wert, wird umgestellt — das spart die häufigste Fehleingabe (Titel statt Handle).

15. Warenkorb-Schublade und `request.page_type`

Die sperrende Ebene erscheint nur, wenn request.page_type == 'cart'. Themes mit Schublade führen den Kunden nie auf diese Seite.

  • [ ] In einem Schubladen-Theme: Klick auf «Zur Kasse» in der Schublade wird abgefangen und öffnet die Prüfung direkt
  • [ ] Nach dem Abbrechen bleibt der Kunde in der Schublade, nichts hängt

16. Grössengrenzen bei Deploy

shopify app deploy

Shopify prüft die Extension beim Deploy: alle Dateien zusammen ≤ 10 MB, höchstens 30 Blöcke, Liquid über alle Dateien ≤ 100 kB, je Sprachdatei ≤ 15 kB. Für JavaScript und CSS gelten 10 kB bzw. 100 kB als Empfehlung, nicht als harte Grenze. Unsere Dateien liegen deutlich darunter — nachsehen lohnt erst, wenn jemand etwas hinzufügt.


17. Legt der Server die Validation wirklich an? *(App-Store-Fassung)*

Der Schritt, der bis zum 6. September 2026 gar nicht gebaut war: Die Extension beschrieb in ihren Kommentaren zwei Metafelder, die unser Server schreibe — den Code dazu gab es nicht. Die Function war installiert und wirkungslos.

# In der eingebetteten App einmal speichern, danach im Admin:
#   Einstellungen → Checkout → Validierungen
# Erwartet: «EdelVerify Altersprüfung», eingeschaltet.
#
# Und über die Admin-API:
query { validations(first: 10) { nodes {
  id enabled blockOnFailure
  config: metafield(key: "config") { jsonValue }
  variablen: metafield(namespace: "$app:edelverify", key: "variables") { jsonValue }
} } }

Erwartet: enabled: true, blockOnFailure: true, beide Metafelder gefüllt, variables mit allen vier Schlüsseln — auch den leeren.

Zu messen ist ausserdem, ob $app:edelverify als Namensraum eines Input-Variablen-Metafelds von Shopify wirklich angenommen wird. Wird es das nicht, meldet Shopify InvalidVariableValueError beim Function-Lauf, und die Function fällt auf «ganzer Shop, ab 18» zurück — sie sperrt dann zu viel, nicht zu wenig, aber der Händler merkt es an der falschen Stelle.

18. Trennt die Kasse Bier von Spirituosen?

# Sammlung «Bier» auf ab 16, Sammlung «Spirituosen» auf ab 18.
# 1. Nur Bier im Warenkorb, angemeldeter Kunde mit Nachweis ab 16
#    → Kasse lässt durch.
# 2. Flasche Whisky dazulegen
#    → Kasse verweigert mit «… über 18 …».

Erwartet: Punkt 2 verweigert. Verweigert er nicht, ist die Reihenfolge in grenze_der_zeile verdreht — und dann liesse sich jede 18er-Ware mit einem zusätzlichen 16er-Eintrag entschärfen.

19. Wird ein angemeldeter Kunde wirklich dreissig Tage nicht neu gefragt?

# 1. Angemeldet prüfen, Bestellung abschliessen.
# 2. Abmelden, wieder anmelden, neuer Warenkorb.
# 3. Erwartet: kein Prüffenster, Kasse lässt durch.
# 4. Im Admin: Kunde → Metafelder → app-eigenes `verification`
#    Erwartet: {"v":1,"ab":[16,18],"bis":"JJJJ-MM-TT"}

Und die Gegenprobe, die wichtiger ist: Wird die Bestellung aus Schritt 3 vom orders/create-Webhook als geprüft gewertet? Sie trägt kein Warenkorb-Attribut. Wertet der Webhook sie als kein_attribut, hält er eine Bestellung an, die die Kasse eben durchgelassen hat — geprüft und trotzdem abgewiesen.

20. Fällt der `bis`-Tag um einen Tag zu früh oder zu spät?

Der Nachweis läuft auf die Minute ab, die Function kann nur Tage vergleichen. Hinterlegt wird deshalb der letzte Tag, der ganz in der Gültigkeit liegt.

# Prüfung um 08:00, Nachweis 30 Tage gültig.
# Erwartet im Metafeld: bis = Ablauftag MINUS EINS.

Ist es der Ablauftag selbst, trägt der Nachweis an diesem Tag bis Mitternacht — und zwar auch im Webhook, der dasselbe Feld liest.


Was bereits belegt ist

Diese Punkte standen zur Frage und sind an shopify.dev geklärt (Stand

  1. August 2026). Sie gehören nicht mehr geprüft.
FrageAntwortQuelle
Aufbau von shopify.app.tomlname, client_id, application_url, embedded, handle, [access_scopes] scopes, [auth] redirect_urls, [webhooks] api_version + [[webhooks.subscriptions]] mit topics / compliance_topics / uri, [app_proxy] url/prefix/subpath, [build]app-configuration
Erlaubte Werte für prefixa, apps, community, tools; subpath ≤ 30 Zeichen, nicht admin, services, password, loginebenda
Inhalt von shopify.extension.toml (Theme)nur name, type = "theme", optional handletheme-app-extensions/configuration
Ordner der Theme App Extensionassets, blocks, snippets, locales, package.json, shopify.extension.tomlebenda
App embed block"target" ist head, compliance_head oder body; wird vor </head> bzw. </body> eingefügt; ab Werk deaktiviert, der Händler muss ihn im Theme-Editor einschaltenebenda
Weitere Schema-Attributename (< 25 Zeichen, ohne App-Namen), stylesheet, javascript, enabled_on/disabled_on, class, tag, settings, default, available_ifebenda
Blöcke im Checkout«App blocks and app embed blocks can't be rendered on checkout pages» — deshalb liegt die sperrende Ebene über dem Warenkorbebenda
Grenzen10 MB gesamt, 30 Blöcke, 100 Sprachdateien à 15 kB, Liquid ≤ 100 kB (erzwungen); CSS 100 kB / JS 10 kB (empfohlen)ebenda
Direktlink zum Einschalten…/admin/themes/current/editor?context=apps&template={template}&activateAppId={api_key}/{handle}, {handle} = Dateiname des Blocksebenda
Privates Warenkorb-Attributdoppelter Unterstrich; solche Attribute sind «not available in the Liquid cart.attributes object or the Ajax API» — für uns unbrauchbarAjax Cart API
Felder aus GET /cart.jstoken, item_count, attributes, items[].key, .product_id, .variant_id, .quantity; Token in der Form Z2Nw…?key=…ebenda
Sprachbewusste Ajax-Adressenwindow.Shopify.routes.root, endet immer auf /Ajax API
product.collections in Liquidvorhanden — aber «Collections that aren't available on the Online Store sales channel aren't included». Daher der Pflichtschritt im EINBAU.product
request.page_typeWerte u. a. cart, product, collection, indexrequest
App-Proxy-SignaturParameter shop, path_prefix, timestamp, logged_in_customer_id, signature; unkodiert, sortiert, verkettet, HMAC-SHA256 mit dem Client Secret, hexauthenticate-app-proxies
Cookies über den Proxykeine — Shopify entfernt Cookie und Set-Cookieebenda
Händler ändert die Proxy-URLEinstellungen → Apps und Vertriebskanäle → {App} → App-Proxy → URL anpassen; Änderungen an subpath/prefix in der App wirken nur auf neue Installationenapp-proxies
Function: Netzzugrifffür gewöhnliche Plus-Händler nicht verfügbarnetwork-access
Function: inAnyCollection(ids:)vorhanden, ids ist Pflicht. Die Liste kommt aus Input query variables — einem JSON-Metafeld auf dem Function Owner, deklariert unter [extensions.input.variables]. Der frühere Eintrag «Literal, keine Laufzeitvariablen» war falsch und hat die Function shop-spezifisch gemacht.Cart and Checkout Validation, input variables
Function: cart.attribute(key:)vorhanden, liefert key und valueebenda
Function: validation.metafield(namespace:key:)vorhanden, value ist immer eine Zeichenketteebenda
Function: Ziel der Fehlermeldung«You can also use $.cart to target the current checkout page»ebenda
Function in Rust#[typegen("schema.graphql")] mit #[query("src/….graphql")], Einstieg #[shopify_function] fn cart_validations_generate_run(input: schema::cart_validations_generate_run::Input); Union über schema::…::input::cart::lines::Merchandise::ProductVariant(v); main() bricht abRust for Functions, Beispiele in der Validation-Referenz
Function: Bauzielab shopify_function 2.0 wasm32-unknown-unknown, Wasm-Datei < 256 kBRust for Functions
Functions und Tarif«Only stores on a Shopify Plus plan can use custom apps that contain Shopify Function APIs.»functions
Functions und Tarif, der andere Fall«All plans: Except as noted in individual API pages, stores on any plan can use public apps that are distributed through the Shopify App Store and contain functions.» — die Grenze oben gilt für CUSTOM APPS, nicht für den App Storefunctions/latest
Kann der Laden die Altersgrenze selbst wählen?im Theme nein, in der App-Store-Fassung jaIm Theme-Block steht bewusst kein Feld: Eine Grenze dort könnte von der Vorgabe abweichen, gegen die /api/shopify/proxy/confirm einlöst — grünes Prüffenster, danach Absage. Belegt durch scripts/pakete-pruefen.py, Abschnitt K. In der eingebetteten App dagegen wird sie je Sammlung und je Schlagwort gesetzt und in zwei Metafelder an der Validation geschrieben.
Womit startet die Prüfung im Laden?mit der strengsten Grenze des LadensDas Prüffenster kennt den Warenkorb nicht. Deshalb hebt POST /api/shopify/einstellungen die Vorgabe des Händlerkontos beim Speichern notfalls an (hoechsteGrenze) — nie ab. Ohne das könnte ein Gast eine 16er-Prüfung bestehen, die dem Webhook danach nicht genügt: durch die Kasse, dann Versandstopp.
Zeigt das Prüffenster die richtige Grenze?jagate.js liest min_age aus der Antwort des Dienstes und schreibt sie in den Text («Über 16 bestätigt»). Es rät sie nicht. Nachgemessen: scripts/api-vertragstest.py, Abschnitt 10.
Woran erkennt der Erfolg sich — over_18 oder age_ok?age_okover_18 ist nur wahr, wenn gegen 18 geprüft wurde; bei einer bestandenen 16er-Prüfung steht dort false. Sowohl gate.js als auch /api/shopify/proxy/confirm lesen deshalb age_ok. In einem Laden mit Grenze 16 wäre die andere Wahl eine Kundschaft, die alt genug ist und trotzdem abgewiesen wird. Belegt: scripts/pakete-pruefen.py, Abschnitt J.
Braucht die Validation Function die Grenze?ja, seit der Grenze je SammlungFür den Gastweg nicht: Dort prüft sie nur, ob ein Kennzeichen im Warenkorb liegt — mehr kann sie nicht, sie darf nicht ins Netz. Für den Nachweis am Kundenkonto schon: Sie vergleicht ab gegen die Grenze der Ware, und ein «über 16» darf für Spirituosen nicht reichen.
Wie kommt die Grenze in die Function?zwei Metafelder an der Validationconfig ({modus, grenze}) im app-eigenen Namensraum $app, variables (vier Listen) in $app:edelverify. Zwei Namensräume, weil nur diese beiden Formen belegt sind: der weggelassene Namensraum beim Lesen, die $app:<suffix>-Form im Beispiel der Input-Variablen. Geschrieben werden beide in einem metafieldsSet — getrennt gäbe es einen Zustand, in dem die neue Grenze schon gilt und die alten Listen noch.