# Shopware 6

> **Shopware 6** – Eingang via Flow-Builder-Webhook, Ausgang via Admin-API. Benötigtes Addon: `connector_shopware6`.

## Überblick

Mit dieser Integration verbinden Sie einen Shopware-6-Shop mit Orderport in beide Richtungen:

- **Eingang (Shop → Orderport)**: Shopware schickt neue Bestellungen per Flow-Builder-Webhook an Orderport. Orderport normalisiert die Payload und wandelt sie in Ihr Zielformat (openTrans XML oder JSON).
- **Ausgang (Orderport → Shop)**: Orderport legt Bestellungen, die aus einem anderen Kanal (z. B. Ariba, EDIFACT) stammen, direkt als Shopware-6-Order an – inklusive Kunde, Adresse, Positionen, Zahlungs- und Versandart.

Typische Einsatzfälle:

- Sie nehmen Bestellungen aus einem B2B-Einkaufsportal entgegen und wollen sie in Ihrem Shopware-Shop sichtbar haben.
- Sie betreiben einen Shopware-Shop und müssen die Bestellungen an ein ERP-System weiterreichen.

## Kompatibilität

### Unterstützte Versionen

| Bereich | Version |
|---|---|
| Shopware | **6.7** (Admin API v3) |
| Webhook-Quelle | Shopware Flow Builder (ab 6.4) |
| Admin-API-Auth | OAuth 2.0 Client Credentials |

### Bekannte Einschränkungen

- **Nur Einzelbestellungen.** Keine Batch-Imports über mehrere Orders in einem Request.
- **Status-Updates/Stornierungen fließen nicht zurück.** Eine einmal angelegte Bestellung wird von Orderport nicht weiter aktualisiert. Spätere Zustandsänderungen müssen in Shopware manuell oder über einen eigenen Workflow passieren.
- **Keine Rückgabe-/Retouren-Abwicklung.**
- **Produkt-Lookup nur über Artikelnummer.** Orderport sucht beim Import per SKU/`productNumber`. Wird ein Artikel nicht gefunden, wird die Position als *custom line item* angelegt (ohne Produktverknüpfung).
- **Mehrere Versandziele je Order** (Split-Shipping) werden nicht unterstützt – nur eine Lieferadresse pro Bestellung.
- **Mengenrabatte / Promotion-Codes** werden nicht übersetzt; der Brutto-/Nettobetrag wird aus den Einzelpositionen neu berechnet.

## Authentifizierung

### Für den Eingang (Webhook vom Shop)

Shopware signiert den Webhook-Body optional mit einem geheimen Schlüssel. In Orderport legen Sie dazu eine **Credential vom Typ „HMAC-SHA256"** an und hinterlegen denselben Schlüssel im Shopware-Flow-Builder. Signatur-Header: `X-Shopware-Signature`.

Alternativ nutzen Sie **Bearer Token** – einfacher einzurichten, aber weniger sicher, weil der Token als Header-Wert übertragen und nicht pro Request neu berechnet wird.

### Für den Ausgang (Admin API schreibt)

Orderport authentifiziert sich mit **OAuth 2.0 Client Credentials** an der Shopware-Admin-API:

- Token-Endpoint: `{Shop-URL}/api/oauth/token`
- Benötigt: **Client-ID** und **Client-Secret** aus einem Admin-API-Integration-Account
- Token wird automatisch nachgeholt, wenn er abläuft

## Einrichten in Orderport

### Pipeline anlegen (Eingang)

1. **Pipelines → Neue Pipeline** → **Experten-Wizard** (oder **Simple Wizard** mit Preset *Shopware 6*)
2. Eingabeformat: **Shopware 6**, Ausgabeformat je nach Ziel: **openTrans** oder **JSON**
3. Mapping-Vorschläge werden automatisch generiert (Bestellnummer, Datum, Summen, Kunde, Adressen, Positionen)
4. Transport wählen – z. B. HTTP POST an Ihr ERP, REST-API oder E-Mail

### Pipeline anlegen (Ausgang in einen Shop)

1. **Simple Wizard → Ziel: Shopware 6 Shop**
2. Shop-URL, Client-ID und Client-Secret eingeben, **Verbindung testen**
3. Sobald die Verbindung steht, lädt Orderport per Admin-API nach:
   - Sales Channels
   - Währungen
   - Zahlungsarten
   - Versandarten
   - Bestellstatus (order.state, order_delivery.state, order_transaction.state)
4. Werte auswählen, Mapping vom Quellformat in das Shopware-Ziel-Schema
5. Transport wird automatisch auf „REST API" mit Adapter `shopware6` gesetzt

### Credential anlegen (nur beim Eingang)

Auf der Pipeline-Detailseite **Credentials → Hinzufügen**:

- **HMAC-SHA256** – empfohlen. Orderport zeigt das Secret einmalig an. Tragen Sie es im Flow Builder als *Signature Secret* ein. Header-Name: `X-Shopware-Signature`.
- **Bearer Token** – alternativ. Der Token wird ebenfalls einmalig angezeigt.

### Mapping

Shopware-6-Quellfelder und die empfohlenen Zielfelder sind unten dokumentiert. Die KI-Vorschläge greifen alle wesentlichen Felder automatisch; Spezialfälle (z. B. Steuerkennzeichen, Preis-Modus brutto vs. netto) lassen sich im Mapping-Editor anpassen.

## Einrichten im Shop

### Eingehender Webhook (Flow Builder)

1. **Einstellungen → System → Flow Builder → Flows**
2. Neuen Flow mit Trigger **Bestellung aufgegeben** anlegen (Event `checkout.order.placed`)
3. Aktion **Webhook senden** hinzufügen
4. URL: Webhook-URL aus Orderport (`https://orderport.app/api/v1/webhook/{token}`)
5. HTTP-Methode: **POST**
6. Signatur: **Eigenes Secret setzen**, identisch zum in Orderport hinterlegten HMAC-Secret

### Admin-API-Zugang (für Ausgang)

1. **Einstellungen → System → Integrationen → Zugang hinzufügen**
2. Rolle: mindestens *Schreibrechte auf `order`, `customer`, `product`, `sales_channel`, `payment_method`, `shipping_method`*
3. Die Admin-UI zeigt **Access Key ID** und **Secret Access Key** einmalig an. Diese tragen Sie im Orderport-Wizard als Client-ID und Client-Secret ein.

## Technische Details

### Eingangs-Payload

Shopware liefert eine verschachtelte JSON-Struktur mit den relevanten Bestellfeldern (gekürztes Beispiel):

```json
{
  "orderNumber": "10001",
  "orderDateTime": "2024-03-15T14:30:00+01:00",
  "amountTotal": 1785.00,
  "amountNet": 1500.00,
  "currency": { "isoCode": "EUR" },
  "orderCustomer": {
    "customerNumber": "KD-001",
    "company": "Muster GmbH",
    "email": "bestellung@muster.de",
    "firstName": "Max",
    "lastName": "Mustermann"
  },
  "deliveries": [{
    "shippingOrderAddress": {
      "street": "Industriestr. 42",
      "zipcode": "80331",
      "city": "München",
      "country": { "iso": "DE" }
    }
  }],
  "lineItems": [{
    "productNumber": "WIDGET-001",
    "label": "Premium Widget Blau",
    "quantity": 10,
    "unitPrice": 150.00,
    "totalPrice": 1500.00
  }]
}
```

### Verfügbare Quellfelder

| Pfad | Bedeutung |
|---|---|
| `order.number` | Bestellnummer |
| `order.date` | Bestelldatum (ISO 8601) |
| `order.total_gross` | Gesamtbetrag brutto |
| `order.total_net` | Gesamtbetrag netto |
| `order.currency` | Währungscode (z. B. `EUR`) |
| `customer.number` | Kundennummer |
| `customer.company` | Firma |
| `customer.email` | E-Mail |
| `customer.first_name` / `customer.last_name` | Name |
| `shipping.street` / `.zip` / `.city` / `.country` | Lieferadresse |
| `lines[].sku` | Artikelnummer |
| `lines[].name` | Artikelname |
| `lines[].quantity` | Menge |
| `lines[].unit_price` / `.total_price` | Preise pro Position |

### Ausgangs-Payload (Admin-API-Schema)

Der `shopware6`-Adapter erzeugt ein komplettes Order-Objekt mit vorberechneten Steuern und festen UUIDs. Wesentliche Bestandteile:

- `orderNumber`, `orderDateTime`, `stateId`
- `currencyId`, `salesChannelId`, `paymentMethodId`, `shippingMethodId`
- `price` (inkl. `calculatedTaxes`, `taxRules`, `taxStatus`)
- `lineItems[]` (Produkt wird per SKU aufgelöst; nicht gefundene SKUs werden als `type: "custom"` angelegt)
- `orderCustomer` (versucht per E-Mail einen bestehenden Kunden zu matchen – sonst neu angelegt)
- `transactions[]`, `deliveries[]`, `billingAddress`, `shippingOrderAddress`

### Adapter-Konfiguration

Die folgenden Werte werden im Simple Wizard erfragt bzw. beim Verbindungs-Test geladen:

| Feld | Pflicht | Quelle |
|---|---|---|
| `api_url` | ja | Eingabe im Wizard |
| `client_id` / `client_secret` | ja | Eingabe im Wizard |
| `sales_channel_id` | ja | Auswahl aus API |
| `currency_id` | ja | Auswahl aus API |
| `payment_method_id` | ja | Auswahl aus API |
| `shipping_method_id` | ja | Auswahl aus API |
| `order_state_id` | ja | Auswahl aus API (State-Machine `order.state`) |
| `order_delivery_state_id` | automatisch | Auflösung der `order_delivery.state`-Initial-State |
| `order_transaction_state_id` | automatisch | Auflösung der `order_transaction.state`-Initial-State |
| `default_tax_rate` | ja | Eingabe (Default 19 %) |
| `country_map` | optional | JSON-Map ISO-Code → Country-UUID (Fallback: Live-Lookup) |
| `salutation_map` | optional | JSON-Map Anrede → Salutation-UUID (Fallback: Live-Lookup) |
| `price_mode` | optional | `net` (Default) oder `gross` – steuert, wie Quell-Preise interpretiert werden |

### Preis-Modus

Der Shopware-Adapter erwartet Brutto-Preise. Liefert Ihr Quellsystem Netto-Preise, lässt Orderport sich mit `price_mode: "net"` (Default) konfigurieren – die Werte werden dann mit dem Steuersatz hochgerechnet. Bei `price_mode: "gross"` werden die Werte 1:1 übernommen.

### Endpoint

Webhook-URL je Pipeline: `https://orderport.app/api/v1/webhook/{token}`. Der Token steht in der Pipeline-Detailseite zum Kopieren bereit.

## Fehlerbehebung

| Symptom | Ursache | Lösung |
|---|---|---|
| Bestellungen kommen in Shopware an, aber Rechnungsadresse ist leer | Shopware füllt `billingAddress.orderId` nicht automatisch | Kein Eingreifen nötig – Orderport setzt `orderId` auf beiden Adress-Objekten explizit. Tritt das weiterhin auf, prüfen Sie die Shopware-Version (< 6.5). |
| „Shopware konnte initialStateId nicht auflösen" | OAuth-Token abgelaufen oder Berechtigungen fehlen | Client-ID/Secret im Orderport-Wizard erneuern, Integration in Shopware muss Rechte auf `state_machine` haben |
| Produkt wird als *custom line item* angelegt statt verknüpft | SKU stimmt nicht mit Shopware-`productNumber` überein | SKU-Schreibweise prüfen (case-sensitive) oder `product_map` in der Adapter-Konfiguration ergänzen |
| 401 beim Webhook-Eingang | HMAC-Secret unterschiedlich in Shop und Orderport | Secret in Orderport durch Neu-Anlage einer Credential erneuern, in Shopware ersetzen |
| 413 Payload Too Large | Shopware sendet sehr großen Order-Blob (> 5 MB) | Flow Builder so konfigurieren, dass nur benötigte Felder gesendet werden |

## Nächste Schritte

- [Feldmapping](/docs/feldmapping) – Felder verfeinern
- [Zugangsdaten](/docs/credentials) – HMAC/Bearer im Detail
- [REST API](/docs/rest-api) – Transport-Details für den Ausgang
