# Magento 2

Das punchout.dev-Modul PunchoutDev_Bridge für Magento 2.4 installieren und konfigurieren, mit Warenkorb-Marker, Auto-Login und der Content-Security-Policy.

URL: https://punchout.dev/de/docs/plugins/magento/

Das punchout.dev-Modul `PunchoutDev_Bridge` für Magento 2.4 gibt das Script-Tag aus, markiert die Warenkorbseite für punchout.dev und meldet Punchout-Einkäufer in ihrem Kundenkonto an.

## Voraussetzungen

| Voraussetzung | Wert |
| --- | --- |
| Magento | 2.4, Open Source oder Commerce |
| PHP | 8.1 bis 8.4, mit `sodium` und `json` |
| Modul | `PunchoutDev_Bridge` (Composer-Name `punchout-dev/module-bridge`), Version 2.0.0, keine Composer-Abhängigkeiten |
| Download | `PunchoutDev-Bridge-<version>.zip` aus dem Tab **Einbindung** des Shops im Portal (Shopsystem: Magento) |

## Installieren

Die Zip-Datei enthält bereits die Ordner `PunchoutDev/Bridge/`. Entpacken Sie sie nach `app/code`, das Modul landet also in `app/code/PunchoutDev/Bridge`. Führen Sie dann aus:

```bash
bin/magento module:enable PunchoutDev_Bridge
bin/magento setup:upgrade
bin/magento cache:flush
```

Im Produktionsmodus führen Sie außerdem aus:

```bash
bin/magento setup:di:compile
bin/magento setup:static-content:deploy
```

`setup:upgrade` legt eine Tabelle für die Einmal-Login-Tokens an. Sonst ändert das Modul nichts an der Datenbank.

## Konfigurieren

Öffnen Sie **Stores → Configuration → punchout.dev → General**. Jeder Wert lässt sich im Geltungsbereich Standard, Website oder Store-View setzen. Die Konfigurationspfade beginnen mit `punchout_dev/general/`. Die Konfigurationsseite ist englisch; die Tabelle nennt die Beschriftung jeder Einstellung in Klammern.

| Einstellung | Pfad | Wert |
| --- | --- | --- |
| Snippet einbinden (Embed the snippet) | `snippet_enabled` | Ja (Standard). Bei Nein wird kein Script-Tag ausgegeben. |
| Snippet-URL (Snippet URL) | `snippet_url` | `https://js.punchout.dev/pob.js`, aus dem Tab Einbindung des Portals. Bleibt das Feld leer, wird nichts ausgegeben. |
| API-Basis-URL, optional (API base URL) | `api_base` | Leer lassen. |
| Auto-Login aktivieren (Enable auto-login) | `enabled` | Ja (Standard). |
| Shop-ID (Shop ID) | `tenant_id` | Die **Shop-ID** aus dem Tab Einbindung des Portals. Wird auch als `data-shop-id` am Script-Tag ausgegeben. |
| Public-Key-Zeilen (Public key lines) | `public_keys` | Jede Zeile aus dem Tab Auto-Login des Portals, Abschnitt **Öffentliche Schlüssel**, eine je Zeile. Zeilen, die mit `#` beginnen, und leere Zeilen werden ignoriert. |

Dieselben Werte auf der Kommandozeile:

```bash
bin/magento config:set punchout_dev/general/tenant_id pob_live_…
bin/magento config:set punchout_dev/general/public_keys "k1=…"
bin/magento config:set punchout_dev/general/snippet_url https://js.punchout.dev/pob.js
bin/magento cache:flush
```

Das Modul gibt das Script-Tag auf jeder Storefront-Seite in `before.body.end` aus.

## Was das Modul markiert

Das Modul setzt einen `afterToHtml`-Interceptor auf `Magento\Checkout\Block\Cart\Grid` und umschließt dessen Ausgabe mit `<div data-punchout-cart>`. Es greift nur beim Block namens `checkout.cart.form`, dem Warenkorb-Formular auf der Warenkorbseite. Ein Mini-Warenkorb oder eine andere Liste aus derselben Klasse wird so nie markiert. Weil der Marker an der Block-Klasse hängt und nicht am Template, funktioniert er in Luma wie in Hyvä. Ein leerer Warenkorb bleibt unmarkiert.

## Auto-Login

Der Login-Endpunkt des Moduls ist `GET /punchout-dev/login?token=…`. Er ist eine Frontend-Route und im Admin-Bereich nie erreichbar. Richten Sie die Portalseite im Tab **Auto-Login** des Shops ein:

| Portalfeld | Wert |
| --- | --- |
| Adapter | Magento |
| Login-Pfad | `/punchout-dev/login`, mit dem Basispfad des Stores davor, wenn der Shop nicht direkt auf der Domain liegt, zum Beispiel `/shop/pub/punchout-dev/login` |
| Kundenreferenz | E-Mail-Adresse (empfohlen) oder Kunden-ID |

| Kundenreferenz | Abgeglichen mit |
| --- | --- |
| E-Mail-Adresse | Ein Kunde der aktuellen Website mit dieser Adresse |
| Kunden-ID | Die Kunden-Entity-ID in Magento, auf der aktuellen Website |
| Kundennummer | Nicht unterstützt |

:::caution
Magento kennt keine Kundennummer. Ist **Kundennummer** gewählt, lehnt das Modul jedes Token mit dem Grund `unsupported_ref_kind` ab, und der Einkäufer landet als Gast. Der Tab Auto-Login im Portal weist darauf hin, wenn der Adapter Magento ist. Nutzen Sie E-Mail-Adresse oder Kunden-ID.
:::

Tragen Sie dann im Tab **Einkäufer** für jeden Einkäufer-Zugang die **Shop-Kundenreferenz** ein. Ein Kunde, der seine E-Mail-Adresse noch nicht bestätigt hat, wird nicht angemeldet. Admin-Benutzer lassen sich auf diesem Weg gar nicht anmelden: Sie liegen in einer eigenen Tabelle, die der Kunden-Login nie liest.

Nach der Anmeldung leitet das Modul unverändert auf den Landing-Pfad weiter und setzt den Basispfad des Stores nicht davor. Setzen Sie den **Landing-Pfad** im Tab Allgemein auf den vollständigen Warenkorbpfad, zum Beispiel `/checkout/cart/`, oder `/shop/pub/checkout/cart/` für einen Store unter einem Unterpfad.

Der vollständige Ablauf steht auf der Seite [Auto-Login](https://punchout.dev/de/docs/plugins/auto-login/).

## Content-Security-Policy

Magento 2.4 bringt das Modul `Magento_Csp` mit. Im Report-Only-Modus lädt das Script-Tag ohne Änderung. Setzt die Storefront ihre Policy durch, muss diese die Quellen des Script-Tags erlauben. Das punchout.dev-Modul liefert keine `csp_whitelist.xml` mit, weil die Snippet-URL eine Einstellung ist. Der Tab **Einbindung** im Portal zeigt die vier Zeilen für Ihren Shop:

```txt
script-src https://js.punchout.dev
connect-src https://api.punchout.dev
style-src 'unsafe-inline'
form-action https://<host of each buyer system>:*
```

`style-src 'unsafe-inline'` ist nötig, weil die Styles des Panels inline stehen. `form-action` ist nötig, weil der Warenkorb von der Shop-Seite aus an das Einkaufssystem übergeben wird. Der Tab Einbindung baut diese Zeile aus dem Feld **Erlaubte Rücksprung-Hosts** im Tab Allgemein, ein `https://<host>:*` je Host, und zeigt den Platzhalter `https://buyer-system.example`, solange die Liste leer ist. Für den [Test-Punchout](https://punchout.dev/de/docs/getting-started/test-punchout/) muss `form-action` zusätzlich `https://api.punchout.dev` erlauben. Die ausführliche Erklärung steht unter [Das Tag einbinden](https://punchout.dev/de/docs/getting-started/install-the-tag/).

## Setup-Selbsttest

1. Erzeugen Sie im Tab **Einrichtung** des Shops im Portal einen Setup-Link (standardmäßig 60 Minuten gültig).
2. Legen Sie 2 oder 3 verschiedene Produkte in den Warenkorb.
3. Öffnen Sie die Warenkorbseite mit dem Setup-Link und klicken Sie auf **Warenkorb erkennen**.

Ist das Modul aktiv, nennt das Ergebnis die Quelle **Shop-Plugin**. Bestätigen Sie mit **Ja, passt**. Damit ist der Schritt **Warenkorb erkannt** im Portal erledigt.

## Aktualisieren

Laden Sie die neue Zip-Datei aus dem Tab Einbindung herunter, entpacken Sie sie über `app/code/PunchoutDev/Bridge` und führen Sie dann `bin/magento setup:upgrade` und `bin/magento cache:flush` aus (dazu die beiden Befehle für den Produktionsmodus). Werden die Dateien an Ort und Stelle ersetzt, kann Magento weiter das vorherige Template ausliefern. Löschen Sie deshalb auch die vorverarbeitete Kopie:

```bash
rm -rf var/view_preprocessed/pub/static/app/code/PunchoutDev
```

### Umstieg von PunchoutNinja_Bridge 1.x

Für Magento ist 2.0.0 ein neues Modul: Führen Sie `bin/magento module:disable PunchoutNinja_Bridge` aus, löschen Sie `app/code/PunchoutNinja` und betreiben Sie nie beide. Tragen Sie die Werte unter **Stores → Configuration → punchout.dev** neu ein und ändern Sie den **Login-Pfad** im Portal auf `/punchout-dev/login`.

## Fehlersuche

Das Modul schreibt je Login eine Zeile auf Level Info nach `var/log/system.log`, mit einem Ablehnungsgrund, wenn es das Token ablehnt. Das Token und den Kunden protokolliert es nie. Magento-spezifische Gründe:

| Grund | Bedeutung |
| --- | --- |
| `unsupported_ref_kind` | Die Kundenreferenz im Portal ist Kundennummer |
| `customer_unresolved` | Kein Kunde auf dieser Website passt |
| `customer_wrong_website` | Die Kunden-ID gehört zu einer anderen Website |
| `customer_unconfirmed` | Der Kunde hat seine E-Mail-Adresse nicht bestätigt |
| `store_unresolved` | Der aktuelle Store ließ sich nicht bestimmen |

Die gemeinsamen Ablehnungsgründe stehen auf der Seite [Auto-Login](https://punchout.dev/de/docs/plugins/auto-login/). Mehr unter [Fehlersuche](https://punchout.dev/de/docs/troubleshooting/).

## Vollständige README

Die englische README des Moduls beschreibt die Prüfungen des Tokens und die Tests für die Entwicklung: [README des Magento-Moduls](https://punchout.dev/de/docs/plugins/magento/readme/).
