# Update / easy.affiliate REST-API (Baskets)

## 📝 Einleitung

Um Warenkorb-Positionen von Orders automatisiert im easy.affiliate-System bearbeiten zu können, stellt die easy Marketing GmbH eine Webservice-API zur Verfügung. Diese ermöglicht es, einzelne Positionen bestehender Orders im Nachgang zu bearbeiten – z. B. bei Teilretouren, Teilstornos oder Preiskorrekturen.

Nach jeder Änderung werden **Bestellwert, Provision und Status der Order automatisch aus ihren Positionen neu berechnet**.

Jedem User stehen hierfür ein Authentifizierungs-Token und eine Login_id zur Verfügung, die über das Frontend abgerufen werden können.

- **User-ID:** Wo ist die User-ID hinterlegt? (Siehe Frontend-Profil)
- **Access-Token:** Wo ist der Access-Token hinterlegt? (Siehe API-Einstellungen)

## Endpunkte

| Zielgruppe | URL |
|---|---|
| Admin | `https://SUBDOMAIN.de/ws/V6/admin/REST/Baskets` |

## Beispiele

### Beispiel mit cURL

```bash
curl -X PUT \
  -H "Content-Type: application/json" \
  -H "X-Network-ID: -1" \
  -H "X-Auth-Token: ADMIN_APIUSER_TOKEN" \
  -H "X-Auth-ID: ADMIN_APIUSER_LOGIN_ID" \
  -d '[{ "id": 981234, "amount": 1 },{ "id": 981235, "status": 2 }]' \
  https://SUBDOMAIN.de/ws/V6/admin/REST/Baskets
```

### Codebeispiel

Mit der folgenden Methode können eine oder mehrere Warenkorb-Positionen geupdatet werden. Ein Beispielaufruf sieht folgendermaßen aus:

**Headers**

| Variable | Wert / Bedeutung |
|---|---|
| Content-Type | application/json |
| X-Network-ID | -1 |
| X-Auth-Token | ADMIN_APIUSER_TOKEN |
| X-Auth-ID | ADMIN_APIUSER_LOGIN_ID |

**Body**

```json
[
    {
        "id": 981234,
        "amount": 1
    },
    {
        "basket_item_id": 981235,
        "status": 2
    },
    {
        "id": 981236,
        "price": 17.50,
        "additional": { "retoure_grund": "zu klein" }
    }
]
```

Für eine einzelne Position kann statt der Liste auch direkt ein Objekt gesendet werden, z. B. `{ "id": 981234, "amount": 1 }`.

## Variablenerläuterung

### Headers

| Variable | Bedeutung | Datentyp |
|---|---|---|
| Content-Type | Der Content-Type des Requests | String |
| X-NETWORKID | Hier wird die ID des Mandanten eingetragen. Wenn nur ein Mandant vorhanden ist oder mandantenübergreifend gearbeitet wird, muss der Wert “-1” eingetragen werden. | Integer |
| X-AUTH-TOKEN | Hier wird der API-Authentifizierungs-Token des Admin Nutzers hinterlegt. | String |
| X-AUTH-ID | Hier wird die ID des Admin Nutzers hinterlegt. | Integer |

### Body

| Parameter | Beschreibung | Datentyp | Pflichtfeld |
|---|---|---|---|
| `id` | ID der Warenkorb-Position. Steht in der Antwort der Anlage (`basket[].id`) bzw. im Order-Export. | Integer | ✅ Ja (oder `basket_item_id`) |
| `basket_item_id` | Alternative Schreibweise für `id`. | Integer | ✅ Ja (oder `id`) |
| `amount` | Neue Menge der Position. | Integer | Nein |
| `price` | Neuer Preis **einer** Einheit, Punkt als Dezimaltrenner. | Float | Nein |
| `status` | Status der Position: 0 = offen, 1 = bestätigt, 2 = storniert, 3 = ausgezahlt. | Integer | Nein |
| `commission` | Provisionswert der Position in Kampagnenwährung. Wird er nicht übergeben, wird die Provision neu berechnet (Preis × Menge × Provisionssatz der Position). | Float | Nein |
| `additional` | Objekt `{ "key": "value", … }`. Die übergebenen Keys werden in die bestehenden Zusatzfelder der Position eingefügt bzw. überschrieben; nicht übergebene Keys bleiben erhalten. | Object | Nein |

*) Hinweis: Alle Werte außer `additional` müssen numerisch sein. Weitere Felder (z. B. `productname`, `article_number`, `campaign_id`) werden ignoriert und können über diesen Endpunkt nicht geändert werden.

## 🔄 Auswirkung auf die Order

Nach jeder Änderung wird die zugehörige Order aus **allen** ihren Positionen neu berechnet:

| Wert der Order | Berechnung |
|---|---|
| `turnover` | Summe aus `price × amount` aller Positionen mit Status 0, 1 oder 3 (stornierte Positionen zählen nicht) |
| `commission` | Summe der Provisionen aller Positionen mit Status 0, 1 oder 3 |
| `status` | Niedrigster Status aller Positionen (eine offene Position hält die Order offen; sind alle Positionen storniert, ist die Order storniert) |

Die Neuberechnung erfolgt nur, solange die Order den Status offen, bestätigt oder storniert hat. **Bereits ausgezahlte Orders (Status 3) werden nicht mehr verändert.**

## 📤 Antwort

Die Antwort enthält die gespeicherten Positionen mit ihren aktuellen Werten (bei einer Liste als Array, bei einem einzelnen Objekt als Objekt).

Bei einer Liste werden Positionen, die nicht gefunden wurden oder ungültige Werte enthalten, übersprungen und fehlen in der Antwort – die übrigen Positionen werden trotzdem gespeichert. Bei einem einzelnen Objekt antwortet der Webservice in diesem Fall mit einem Fehler.

## 📘 Hinweise

- **Teilretoure:** Menge reduzieren (`amount`) oder die betroffene Position stornieren (`status: 2`) – Bestellwert und Provision der Order passen sich automatisch an.
- **Komplettstorno:** Alle Positionen auf `status: 2` setzen, die Order wird dann ebenfalls storniert.
- **Positions-IDs:** Kommen aus der Antwort von *Create / easy.affiliate REST-API (Baskets)* oder per `GET` auf denselben Endpunkt.