JTL Shop 5 Plugin

Mit diversen Extensions

Unser Plugin für die Integration verschiedener Tools:

  • Einbindung der AUSGEZEICHNET.org Siegel und Trust-Badges.
  • Einbindung der Widgets für die Präsentation von Score und Bewertungen.
  • Bewertungseinladungen via Invite API.

Hier können Sie die aktuelle Version unseres

JTL Plugins herunterladen.

Hinweis
Pencil Pencil

Anleitung wird überarbeitet. Aktuelle Plugin Version: 1.2.0

AUSGEZEICHNET.org Reach & Review – Anleitung für JTL-Shop 5

Plugin-ID: ausgezeichnet_jtl5  ·  Version: 1.2.0  ·  Shop-Versionen: 5.5.0 – 5.9.9

Das Plugin verbindet den JTL-Shop mit AUSGEZEICHNET.org:

  • zeigt Bewertungs-Widgets (Siegel, Badge, Modal, Slider, Carousel, Produktbewertungen) im Shop an,
  • fügt personalisierte Bewertungslinks in Transaktions-E-Mails ein,
  • versendet automatisch Bewertungseinladungen über die AUSGEZEICHNET.org API, sobald eine Bestellung einen bestimmten Status erreicht.

1. Installationsanleitung

1.1 Voraussetzungen

  • JTL-Shop 5.5.0 – 5.9.9
  • Ein AUSGEZEICHNET.org Account mit Zugriff auf das Kundencenter
  • Für Feature „Automatische Einladung“: ein AUSGEZEICHNET.org API-Schlüssel (im Kundencenter erstellbar)
  • Für „Manuelle Shop-Bewertungseinladung“ (Tools und Setup): AUSGEZEICHNET.org PROFESSIONAL-Plan

1.2 Plugin hochladen und aktivieren

  1. Admin-Backend → Plugins → Übersicht → Plugin hochladen.
  2. ausgezeichnet_jtl5.zip auswählen und hochladen.
  3. Plugin in der Liste aktivieren.
  4. Beim ersten Aktivieren legt das Plugin automatisch die Tabelle xplugin_ausgezeichnet_jtl5_invites an (Migration Migration20260629000001). Das ist die Tracking-Tabelle für die automatische Einladung (siehe Abschnitt 2.4) – hier ist keine manuelle Aktion nötig.

1.3 Grunddaten eintragen (Tab „Grundeinstellungen“)

Alle Werte findest du im AUSGEZEICHNET.org Kundencenter:

Feld Bedeutung
Organisation-ID Wird für die Widget-Script-URLs benötigt. Ohne diesen Wert werden keine Widgets geladen.
Kontonummer Kundencenter → Kontonummer. Fließt in die Hash-Berechnung der Bewertungslinks ein.
Bewertungs-ID Kundencenter → Bewertungs-ID. Ebenfalls Teil der Hash-Berechnung.
Bewertungs-URL Basis-URL für personalisierte Bewertungslinks. Nur Schema+Host+Pfad eintragen, keine Query-Parameter – vorhandene werden automatisch entfernt. Muss https:// sein.
API-Schlüssel Nötig für die automatische Einladungs-Funktion. Kann alternativ per Umgebungsvariable AUSGEZEICHNET_API_KEY gesetzt werden (überschreibt den Wert aus dem Backend – praktisch für getrennte Staging-/Live-Systeme).
Sprach-Override Optional, z. B. de oder en. Leer lassen für automatische Erkennung aus der Shop-Sprache.

1.4 Installation prüfen

Tab Tools und Setup öffnen (letzter Reiter des Plugins) → Abschnitt „Konfigurationsstatus“ zeigt für jedes Pflichtfeld ✓/✗. Erst wenn alle fünf Punkte grün sind, funktionieren Widgets, E-Mail-Links und automatische Einladungen vollständig.

Damit ist die Installation abgeschlossen. Die eigentliche Funktionskonfiguration erfolgt in den Tabs „Widgets“, „E-Mail Bewertungslink“ und „Automatische Einladung“ – siehe Betriebsanleitung.


2. Betriebsanleitung

Das Plugin hat 5 Admin-Tabs. Änderungen an Selectbox-/Text-Einstellungen wirken sofort, ohne dass der Shop-Cache manuell geleert werden muss.

2.1 Tab „Widgets“

Einstellung Beschreibung
Schwebendes Siegel/Badge „Dynamic Seal“ und „Trust Badge“ schließen sich gegenseitig aus – nur eines aktivieren.
Review Modal / Review Collector (Split/Hero) / Review Slider / Review Carousel Jeweils eigenständig aktivierbar. Erfordern ein Platzhalter-Element im Shop-Template (ID/Attribut laut AUSGEZEICHNET.org Dashboard) – ohne passenden Platzhalter erscheint nichts, obwohl das Skript geladen wird.
Produkt-Bewertungswidget Zeigt Produktbewertungen. Auf jeder Produktseite fügt das Plugin den Container
automatisch ein, SKU = JTL-Artikelnummer (cArtNr). Das Skript product-rating.js wird nur auf Seiten geladen, die einen solchen Container enthalten.
Produkt-Widget Darstellungstyp Badge / Hero / Horizontal → Attribut auorg-data-type.
Produkt-Widget automatisch einfügen Standard „Ja“. Auf „Nein“ stellen, wenn der Container manuell (z. B. per OnPage-Composer-Portlet) gesetzt wird. Ein bereits vorhandener Container wird nie verdoppelt.
Produkt-Widget Einfügestelle (CSS-Selektor) Der Container wird nach dem ersten passenden Element eingefügt. Standard .product-title (Produktname im NOVA-Template); nur bei eigenen Templates anpassen.
Review Collector (Legacy) Nur auf ausdrückliche Empfehlung des AUSGEZEICHNET.org Supports aktivieren.
Ausgeschlossene Seiten Eine URL-Teilzeichenkette pro Zeile (z. B. /bestellvorgang, /mein-konto, /warenkorb). Auf passenden Seiten werden keine Widgets geladen – die Einwilligungs-Checkbox (siehe 2.3) wird davon nicht beeinflusst und weiterhin angezeigt.

Alle aktivierten Widget-Skripte werden pro Seitenaufruf einmal vor eingefügt (Hook HOOK_SMARTY_OUTPUTFILTER).

2.2 Tab „E-Mail Bewertungslink“ (Feature 2)

Fügt einen Bewertungsblock (Text + Button + optionales Siegel-Bild) in Transaktions-E-Mails ein. Es gibt zwei unabhängige Wege, das umzusetzen – einen davon wählen, nicht kombinieren:

a) Automatisch injizieren (empfohlen)
Im Tab Tools und Setup → Abschnitt „E-Mail Bewertungsblock – Auto-Setup“ → Button „▶ Bewertungsblock einfügen“. Das Plugin hängt dann an die ausgewählten E-Mail-Templates (temailvorlage) einen mit markierten Smarty-Snippet an, der die Bewertungs-URL bei jedem E-Mail-Versand individuell berechnet. Über „✕ Bewertungsblock entfernen“ lässt sich das wieder rückgängig machen. Die Tabelle in diesem Abschnitt zeigt, welche der drei Templates (Bestellbestätigung, Versandbestätigung, Rechnung) bereits injiziert sind.

b) Manuell im Template einbinden
In ein beliebiges E-Mail-Template einfügen:

{ausgezeichnet_email_block kBestellung=$oBestellung->kBestellung collmethod="pos"}

collmethod ist "pos" (Point of Sale, z. B. Bestellbestätigung/Rechnung) oder "af" (After Fulfillment, z. B. Versandbestätigung).

Steuerbar über die drei Selectboxen „In Bestellbestätigung/Versandbestätigung/Rechnungs-E-Mail einfügen“ (wirken nur auf Methode a), sowie Blocktext, Button-Beschriftung und optionale Siegel-Bild-URL (muss https:// sein).

2.3 Tab „Automatische Einladung“ (Feature 4)

Versendet automatisiert Bewertungseinladungen über die AUSGEZEICHNET.org Invite-API.

Einstellung Beschreibung
Automatische Einladung aktiviert Hauptschalter.
Trigger: Nach Zahlung/Rechnung Löst aus, wenn die Bestellung Status „In Bearbeitung“ (2) oder „Bezahlt“ (3) erhält.
Trigger: Nach Versand/Abschluss Löst aus, wenn die Bestellung Status „Versandt“ (4) erhält. Sinnvoll bei digitalen Produkten oder wenn „In Bearbeitung“ übersprungen wird.
Verzögerung in Tagen (0–30) Wartezeit, die AUSGEZEICHNET.org selbst einhält, bevor die Einladungs-E-Mail verschickt wird (z. B. 7 Tage, damit das Paket ankommen kann).
Collection Method „After Fulfillment“ oder „Point of Sale“ – nur für die Shop-Bewertungseinladung relevant.
Shop-Bewertungseinladung senden Eine Einladung pro Bestellung für die Gesamt-Shop-Bewertung.
Produkt-Bewertungseinladungen senden Eine Einladung pro Bestellposition (SKU/Artikelnummer, Fallback: interne Artikel-ID).
Einwilligung erforderlich Wenn aktiviert: Checkbox im Checkout, standardmäßig nicht vorangehakt (Opt-in). Wenn deaktiviert: alle Kunden gelten als eingewilligt.
Wichtig: Wenn „Automatische Einladung aktiviert“ = Ja, aber kein Trigger aktiv ist, zeigt der Tab „Tools und Setup“ eine Warnung an – in diesem Zustand wird nie etwas versendet.
Wichtig: Wenn du die Einwilligung nutzt, prüfe den vorgeschlagenen Checkbox-Text unter „Text der Einwilligungs-Checkbox“ rechtlich (DSGVO/TTDSG-Konformität liegt in eurer Verantwortung, nicht im Plugin).

2.4 Automatische Einladung: Idempotenz & Tracking

Beim Bestellabschluss (Hook HOOK_BESTELLABSCHLUSS_INC_BESTELLUNGINDB_ENDE) legt das Plugin pro Bestellung genau einen Datensatz in xplugin_ausgezeichnet_jtl5_invites an (E-Mail, Name, Einwilligung, Status). Beim Statuswechsel (Hook HOOK_BESTELLUNGEN_XML_BESTELLSTATUS) prüft das Plugin diesen Datensatz:

  • kein Datensatz vorhanden → Bestellung existierte vor Plugin-Installation, Einladung wird übersprungen (Log-Eintrag „notice“).
  • bConsent = 0 → Kunde hat nicht eingewilligt, keine Einladung.
  • bSent = 1 → bereits gesendet, keine doppelte Einladung (auch bei mehrfachem Statuswechsel, z. B. hin- und zurückgesetzt).

Erst wenn die API-Aufrufe erfolgreich waren, wird bSent = 1 und dGesendet gesetzt. Bei einem API-Fehler bleibt der Datensatz auf „nicht gesendet“ stehen und es gibt aktuell keinen automatischen Retry – ein erneuter Statuswechsel (z. B. manuell im Backend Status kurz zurück- und wieder vorsetzen) würde einen neuen Versuch auslösen.

2.5 Tab „Tools und Setup“ (Feature 4.6)

  • Konfigurationsstatus: Live-Übersicht, ob Organisation-ID, Kontonummer, Bewertungs-ID, Bewertungs-URL und API-Schlüssel gesetzt sind.
  • E-Mail Bewertungsblock – Auto-Setup: siehe 2.2a.
  • Manuelle Shop-Bewertungseinladung: Einmalige Einladung an eine beliebige E-Mail-Adresse, unabhängig vom Bestellprozess. Erfordert einen konfigurierten API-Schlüssel und den AUSGEZEICHNET.org PROFESSIONAL-Plan.

Alle Formulare auf dieser Seite sind CSRF-geschützt (JTL-Admin-Token); bei „Sicherheitstoken ungültig“ die Seite neu laden und erneut versuchen (meist nach sehr langer Inaktivität der Backend-Session).

2.6 Monitoring & Troubleshooting

  • Fehlgeschlagene API-Aufrufe und fehlende API-Schlüssel werden über das JTL-Log (Shop::Container()->getLogService()) protokolliert, sichtbar unter Admin → System → Fehlerprotokoll/Logs. Log-Einträge sind mit dem Präfix [ausgezeichnet_jtl5] versehen.
  • Widgets erscheinen nicht: Organisation-ID prüfen, aktuelle Seiten-URL gegen die Liste „Ausgeschlossene Seiten“ prüfen, bei Modal/Collector/Slider/Carousel das nötige Platzhalter-Element im Template prüfen.
  • Produkt-Bewertungswidget erscheint nicht: Im Seitenquelltext nach auorgProductRating suchen. Fehlt der Container, passt der CSS-Selektor nicht zum Template oder der Artikel hat keine Artikelnummer. Ist er vorhanden, aber leer, liegen bei AUSGEZEICHNET.org für diese SKU (noch) keine Bewertungen vor.
  • E-Mail-Bewertungslink erscheint nicht: Bewertungs-URL/Kontonummer/Bewertungs-ID müssen gesetzt sein (Status-Tabelle in Tools und Setup); bei Methode 2.2a prüfen, ob das Template tatsächlich als „✓ Ja“ markiert ist.
  • Automatische Einladung wird nicht versendet: Reihenfolge prüfen – Hauptschalter aktiv? Mindestens ein Trigger aktiv (Warnhinweis beachten)? API-Schlüssel gesetzt? Einwilligung des Kunden vorhanden (bConsent)? Wurde schon versendet (bSent)? Log auf HTTP-Fehler der AUSGEZEICHNET.org API prüfen.
  • Änderungen an Konfiguration wirken nicht sofort: Seite neu laden bzw. Browser-/Shop-Cache leeren, falls Seiten aus dem Cache ausgeliefert werden.

2.7 Bekannte Einschränkungen

  • Kein automatischer Retry bei fehlgeschlagenen Einladungs-API-Aufrufen (siehe 2.4).
  • Produkt-Bewertungswidget: Bei Variationsartikeln wird die Artikelnummer des beim Seitenaufruf angezeigten Artikels übergeben. Wechselt der Kunde die Variation per AJAX, aktualisiert sich das Widget nicht.
  • Die Einwilligungs-Checkbox wird anhand von URL-Mustern (/bestellvorgang, /checkout) bzw. Smarty-Seitentyp erkannt; bei stark angepassten Checkout-Templates ggf. die CSS-Selektoren in OutputFilterHook::maybeInjectConsentCheckbox() anpassen.
  • Manuelle Einladung (Tools und Setup) und automatische Produkt-/Shop-Bewertungseinladungen erfordern unterschiedliche AUSGEZEICHNET.org Plan-Stufen – im Zweifel im Kundencenter prüfen.

3. Änderungen in Version 1.2.0

Bereich Problem Fix
Hooks/OutputFilterHook.php Das Produkt-Bewertungswidget lud nur product-rating.js, setzte aber keinen Container mit SKU – das Widget blieb unsichtbar, solange der Container nicht von Hand ins Template eingefügt wurde. Container wird auf Produktseiten automatisch mit cArtNr eingefügt; Skript nur noch auf Seiten mit Container, offizielle URL www.ausgezeichnet.org/widgets/…/product-rating.js?lang=… mit defer
Services/Config.php Einstellung „Produkt-Widget Darstellungstyp“ wurde nie ausgewertet. Wird als auorg-data-type übergeben
info.xml – Neue Einstellungen „automatisch einfügen“ und „Einfügestelle (CSS-Selektor)“

3a. Änderungen in Version 1.1.0

Version 1.0.2 ließ sich auf JTL-Shop 5.5–5.9 nicht installieren und hätte im Betrieb das Frontend lahmgelegt. Behoben wurde:

Bereich Problem Fix
info.xml MinShopVersion 550 / MaxShopVersion 599 werden von JTLs SemVer-Parser als 5.50.0 / 5.99.0 gelesen (die 3-stellige Kurzform ist MAJOR + 2-stellige MINOR). Der Shop meldete daher „kompatibel mit 5.50.0 – 5.99.0“ und brach die Installation mit SHOP_VERSION_COMPATIBILITY ab. Punktnotation 5.5.0 / 5.9.9
info.xml Plugin-Name enthielt . und &; JTLs Validator erlaubt nur [A-Za-z0-9_() -] → INVALID_NAME. Gleiches beim Tab „Tools & Setup“. Name → AUSGEZEICHNET-org_Shop-Product_Reviews, Tab → „Tools und Setup“
Migrations/ Migration implementierte JTL\Update\IMigration nicht. Der MigrationManager wirft dafür eine InvalidNamespaceException – die Tabelle wurde nie angelegt. implements IMigration + $author / $description
Hooks/OutputFilterHook.php Typehints auf \phpQueryObject; die Klasse heißt seit Shop 5 JTL\phpQuery\phpQueryObject, ein globaler Alias existiert nicht → TypeError bei jedem Seitenaufruf im Frontend. Namespaced Import
Hooks/OutputFilterHook.php ->last() gibt es auf phpQueryObject nicht (__call() wirft); der Fallback für die Einwilligungs-Checkbox knallte, sobald #CustomerComment fehlte. :last-Pseudoselektor + Count-Guard
Hooks/OutputFilterHook.php Checkout-Erkennung prüfte nSeitenTyp === 17 – das ist PAGE_VERGLEICHSLISTE, nicht der Checkout. PAGE_BESTELLVORGANG (11)
Hooks/OrderStatusHook.php „Nach Versand“ prüfte Status 3 = BESTELLUNG_STATUS_BEZAHLT, nicht 4 = VERSANDT. Shop-Konstanten statt Magic Numbers; „nach Zahlung“ deckt jetzt 2 und 3 ab
OrderStatusHook, OrderCompletedHook, tab_tools.php getSingleObject()/getObjects() wurden mit dem alten ReturnType-Argument aufgerufen. Aktuelle Signatur ist (string $stmt, array $params = []) → TypeError. ReturnType entfernt
adminmenu/tab_tools.php Helfer waren globale Funktionen in einer Datei, die der PluginController per require (nicht require_once) einbindet → Redeclare-/Kollisionsrisiko; eigener CSRF-Nachbau statt JTL\Helpers\Form. Neue Klasse Services\AdminTools, CSRF über Form::getTokenInput() / Form::validateToken()

Die Einstellungen und die Tracking-Tabelle sind unverändert – ein Update von 1.0.x erfordert keine Neukonfiguration.