Zum Inhalt

Admin-API — B2B-Bestellimport

Für Automatisierungen (Cron-Jobs, SFTP-Watcher, externe Systeme) bietet das Plugin drei Admin-API-Endpunkte. Sie nutzen die Standard-Shopware-Authentifizierung über OAuth.

Authentifizierung

Hole dir zuerst einen Access Token:

curl -X POST "https://shop.example.com/api/oauth/token" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "administration",
    "grant_type": "password",
    "scope": "write",
    "username": "admin",
    "password": "your-admin-password"
  }'

Antwort enthält access_token. Diesen in allen weiteren Requests als Authorization: Bearer <token>-Header mitsenden.

Integration-Account empfohlen

Für produktive Automatisierungen lege dir im Shopware-Admin unter Einstellungen → System → Integrationen einen eigenen Integration-Account mit kommora_b2b_order_import.editor-Privileg an. Damit erhältst du dauerhafte API-Credentials ohne Passwort-Änderung.

Endpunkte

Datei hochladen

POST /api/_action/kommora-b2b/upload

Multipart-Upload mit zwei Feldern: profileId (UUID des Importprofils) und file (die Bestelldatei).

Request

curl -X POST "https://shop.example.com/api/_action/kommora-b2b/upload" \
  -H "Authorization: Bearer <token>" \
  -F "profileId=019de47013e87b0c94f476546be90220" \
  -F "file=@bestellung.csv;type=text/csv"

Response

{ "id": "019de4b6e7dc7165b97015ba10e33911" }

Status-Codes:

  • 200 OK — Upload erfolgreich, Inbound-Record angelegt mit Status pending
  • 400 Bad RequestprofileId fehlt oder ist keine valide UUID, oder file fehlt
  • 401 Unauthorized — Token ungültig
  • 403 Forbidden — Token hat kein kommora_b2b_inbound_record:create-Privileg

Pipeline starten

POST /api/_action/kommora-b2b/process/{id}

Triggert die Pipeline für eine bestehende Inbound-Record. Wird typischerweise direkt nach dem Upload aufgerufen.

Request

curl -X POST "https://shop.example.com/api/_action/kommora-b2b/process/019de4b6e7dc7165b97015ba10e33911" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{}'

Response

{
  "status": "approved",
  "errorMessage": null,
  "orderId": "019de4b7467a72a780c9535ed332b808"
}

status kann sein:

  • approved — Bestellung wurde direkt angelegt (bei approvalMode = auto)
  • awaiting_approval — Pipeline durch, wartet auf manuelle Freigabe (bei approvalMode = manual)
  • failed — Pipeline fehlgeschlagen, errorMessage enthält die Ursache
  • mapped / parsed — bei Teil-Fehler

Bestellung freigeben

POST /api/_action/kommora-b2b/approve/{id}

Gibt eine Inbound-Record mit Status awaiting_approval frei und legt die Shopware-Bestellung an.

Request

curl -X POST "https://shop.example.com/api/_action/kommora-b2b/approve/019de4b6e7dc7165b97015ba10e33911" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{}'

Response

{
  "status": "approved",
  "orderId": "019de4b7467a72a780c9535ed332b808",
  "errorMessage": null
}

Beispiel: SFTP-Watcher in Bash

#!/bin/bash
# Pollt einen SFTP-Server, lädt neue Bestelldateien hoch und triggert die Pipeline

API="https://shop.example.com"
PROFILE_ID="019de47013e87b0c94f476546be90220"
LOCAL_DIR=/var/inbox/b2b-customer-x

# OAuth-Token holen (am besten als Integration-Account)
TOKEN=$(curl -s -X POST "$API/api/oauth/token" \
  -H "Content-Type: application/json" \
  -d "{\"client_id\":\"<integration-id>\",\"client_secret\":\"<integration-secret>\",\"grant_type\":\"client_credentials\"}" \
  | jq -r '.access_token')

# Pro Datei: hochladen und sofort verarbeiten lassen
for file in "$LOCAL_DIR"/*.csv; do
    [ -f "$file" ] || continue

    UPLOAD_RESP=$(curl -s -X POST "$API/api/_action/kommora-b2b/upload" \
        -H "Authorization: Bearer $TOKEN" \
        -F "profileId=$PROFILE_ID" \
        -F "file=@$file;type=text/csv")

    INBOUND_ID=$(echo "$UPLOAD_RESP" | jq -r '.id')
    if [ -z "$INBOUND_ID" ]; then
        echo "Upload failed: $file$UPLOAD_RESP"
        continue
    fi

    PROCESS_RESP=$(curl -s -X POST "$API/api/_action/kommora-b2b/process/$INBOUND_ID" \
        -H "Authorization: Bearer $TOKEN" \
        -H "Content-Type: application/json" \
        -d '{}')

    STATUS=$(echo "$PROCESS_RESP" | jq -r '.status')
    case "$STATUS" in
        approved)          mv "$file" "$LOCAL_DIR/processed/" ;;
        awaiting_approval) mv "$file" "$LOCAL_DIR/waiting-approval/" ;;
        failed)            mv "$file" "$LOCAL_DIR/failed/" ;;
    esac
done

Console-Command (Bulk-Verarbeitung)

Alternativ zur API gibt es einen Console-Befehl:

# Alle pending-Records verarbeiten (Bulk)
bin/console kommora:b2b:process --pending

# Eine bestimmte Inbound-Record verarbeiten
bin/console kommora:b2b:process 019de4b6e7dc7165b97015ba10e33911

# Eine Inbound-Record freigeben
bin/console kommora:b2b:process 019de4b6e7dc7165b97015ba10e33911 --approve

Den Bulk-Befehl --pending kannst du z. B. via System-Cron alle 5 Minuten laufen lassen:

*/5 * * * * www-data php /var/www/shop/bin/console kommora:b2b:process --pending

DAL-API (Standard Shopware)

Da kommora_b2b_profile, kommora_b2b_field_mapping und kommora_b2b_inbound_record ganz normale Shopware-Entitäten sind, kannst du auch die Standard Shopware Admin-API zum Lesen / Filtern nutzen:

Endpunkt Zweck
GET /api/kommora-b2b-profile Alle Importprofile listen
POST /api/search/kommora-b2b-inbound-record Inbound-Records mit Filter (z. B. status=approved) suchen
GET /api/kommora-b2b-inbound-record/{id} Eine einzelne Inbound-Record abrufen
DELETE /api/kommora-b2b-inbound-record/{id} Eine Inbound-Record löschen

Vollständige API-Doc unter https://shop.example.com/api/_info/openapi3.json.

Nächster Schritt

Erweiterbarkeit — eigene Format-Parser via Tagged Services hinzufügen.