# Duplikatserkennung

Orderport erkennt doppelt eingesendete Bestellungen automatisch und schützt Sie so davor, dieselbe Bestellung mehrfach an Ihr ERP zuzustellen.

## Wann greift die Duplikatserkennung?

Die Prüfung läuft **nur bei neuen Bestellungen** (`order_type = new`). Updates, Stornierungen oder Änderungen werden nie als Duplikat behandelt und immer durchgereicht.

### Entscheidungsregeln im Überblick

| Situation | Was passiert? |
|---|---|
| Gleiche Bestellnummer, erste Zusendung | Wird normal verarbeitet |
| Gleiche Bestellnummer, nochmal `new` | **409 Conflict / idempotente Antwort** – keine neue Nachricht, keine erneute Zustellung |
| Gleiche Bestellnummer, als `update` oder `delete` | Wird immer durchgereicht – kein Duplikat-Check |
| Gleiche Bestellnummer in **anderer** Pipeline | Nicht als Duplikat erkannt – jede Pipeline hat einen eigenen Nummernkreis |
| Fehlgeschlagene Bestellung erneut `new` | Wird als Duplikat behandelt, wenn die alte Nachricht nicht gelöscht wurde |

## Was zählt als identisch?

Orderport vergleicht **`external_order_id`** innerhalb derselben Pipeline. Die ID wird je nach Eingabeformat automatisch extrahiert:

- **cXML**: `OrderRequestHeader/@orderID`
- **Shopware 6**: `order.number` / `orderNumber`
- **Shopify**: `order.number`
- **WooCommerce**: `order.number`
- **EDIFACT**: `BGM` (Bestellnummer)
- **openTrans**: `ORDER_INFO.ORDER_ID`
- **Generisches JSON**: standardmäßig `order_id` – per Static-/Transform-Mapping änderbar

## Antwort-Verhalten

Die Antwort passt sich an das Eingabeformat an, damit das sendende System sie als „alles OK" interpretiert.

### JSON-Payload

```json
HTTP/1.1 409 Conflict
Content-Type: application/json

{
  "message_id": 42,
  "status": "duplicate",
  "message": "Bestellung bereits empfangen."
}
```

### cXML / XML-Payload

```xml
HTTP/1.1 200 OK

<cXML payloadID="…" timestamp="…">
  <Response>
    <Status code="409" text="Conflict">Bestellung bereits empfangen. Message-ID: 42</Status>
  </Response>
</cXML>
```

> Für cXML bleibt der HTTP-Status 200 – sonst würde Ariba/Coupa die Zustellung als Fehlschlag werten und endlos wiederholen. Der fachliche Konflikt steht im `Status`-Code.

## Wie sinnvoll ist die Erkennung?

Unterschiedliche Systeme zeigen unterschiedliches Retry-Verhalten:

- **Shopify** wiederholt einen fehlgeschlagenen Webhook bis zu **19 Mal** über ca. 48 Stunden
- **Ariba/Coupa** wiederholen cXML-Requests oft mehrfach über Minuten
- **Eigene Integrationen** haben manchmal keine Retry-Erkennung und senden einfach nochmal

Ohne Duplikatserkennung würden diese Retries zu Mehrfach-Zustellungen führen. Mit Duplikatserkennung bekommen Sie jede Bestellung in Ihrem Zielsystem genau einmal.

## Was Sie bei Duplikaten tun können

Auf der Bestellungs-Liste sehen Sie beim betroffenen Eintrag den Vermerk **"Duplikat"**. Der ursprüngliche Bestell-Eintrag bleibt unverändert – inklusive Transport-Log, Status und Payload.

Falls Sie eine Bestellung **absichtlich erneut zustellen** wollen (z. B. weil der Empfang in Ihrem ERP fehlgeschlagen ist):

1. Bestellung in der Liste öffnen
2. Auf **„Erneut zustellen"** klicken – Orderport stößt den Transport neu an, ohne eine neue `InboundMessage` anzulegen

## Technische Details

### Garantierte Idempotenz

Die Prüfung arbeitet datenbankseitig mit einem eindeutigen Schlüssel, der `Pipeline + Bestellnummer` kombiniert. Selbst wenn zwei Webhook-Zustellungen gleichzeitig eintreffen, kann nur eine von ihnen zum Erfolg führen – die zweite erhält die idempotente Duplicate-Antwort. Es gibt kein Race-Fenster.

### Audit-Log

Jedes erkannte Duplikat erzeugt einen Eintrag `inbound.duplicate_rejected` im Audit-Log. So sehen Sie unter `/settings/audit-log`, wie oft und von welchen Partnern Retries eingehen.

### Ausnahme-Fälle

- **Bestellnummer wird nicht erkannt**: Wenn Ihre Generic-JSON-Pipeline die Bestellnummer nicht in einem bekannten Feld führt, greift die Erkennung nicht. Lösung: in der Normalisierung oder im Mapping dafür sorgen, dass die Bestellnummer identifizierbar ist.
- **Leere/fehlende Bestellnummer**: Payloads ohne erkennbare Bestellnummer werden nie als Duplikat markiert – jede Einlieferung erzeugt eine neue Nachricht.

## Nächste Schritte

- [Eingangsnachrichten](/docs/inbound-messages) – Lebenszyklus und Statuswerte
- [Fehlerbehebung](/docs/fehlerbehebung) – Retry-Strategie
- [Audit-Log](/docs/audit-log) – Duplikate nachverfolgen
