> ## Documentation Index
> Fetch the complete documentation index at: https://dokumentation.websale.de/llms.txt
> Use this file to discover all available pages before exploring further.

# WS-REST-OrderManagement

> Bidirektionale REST-Schnittstelle, über die der Shop Bestellungen, PDF-Dateien, Lagerbestände und Kundendaten vom ERP-System anfordert und Stornos und Retouren zurückmeldet.

Mit WS-REST-OrderManagement fordert der Shop Daten in Echtzeit von Ihrem ERP-System an und zeigt sie dem Kunden direkt im Shop. Der wichtigste Anwendungsfall: dem Kunden **alle** seine Bestellungen zeigen, also auch die, die nicht im Shop entstanden sind, sondern beispielsweise über das Callcenter, per Brief oder per Fax. In der Gegenrichtung meldet der Shop Stornos und Retouren an das ERP-System zurück.

| Eigenschaft | Wert |
| - | - |
| Info | REST-basierte Schnittstelle für den bidirektionalen Datenaustausch |
| Übertragungsrichtung | ERP/Warenwirtschaft ↔ WEBSALE Shop (bidirektional) |
| Übertragungsart | REST |
| Dateiformate | JSON |

Übertragbar sind eine einzelne Bestellung oder eine Liste von Bestellungen, die letzte Shop-Bestellnummer, PDF-Dateien, der Lagerbestand eines Produkts oder einer Filiale in Echtzeit sowie allgemeine Zusatzinformationen über einen Kunden.

## Allgemeines

Im Folgenden wird eine REST-basierte Schnittstelle beschrieben, mit deren Hilfe ein WEBSALE Shop kundenspezifische Bestellungen von einem ERP-System in Echtzeit übermittelt bekommt und diese dem Kunden/Besteller im Shop anzeigt. Insbesondere dient diese Schnittstelle dazu, dem Kunden **alle** Bestellungen anzuzeigen, also auch die Bestellungen, die nicht im Shop getätigt wurden, sondern beispielsweise per Callcenter, Brief oder Fax aufgegeben wurden. Des Weiteren können dem ERP-System Stornos und Retouren übermittelt werden.

Falls das ERP-System nicht direkt über das Internet erreichbar ist, dann kann die WEBSALE AG einen VPN-Tunnel zur Verfügung stellen. Über diesen VPN-Tunnel kann das ERP-System eine sichere TCP/IP-Verbindung ins Internet herstellen.

### REST-Funktionen

Alle hier aufgelistete Funktionen werden mittels POST aufgerufen. Bei Erfolg liefert das ERP-System den Http-Code 200 zurück.

#### Übertragung einer Liste von Bestellungen (Kopf- und optionale Positionsdaten)

* Der Shop fordert eine Liste von Bestellungen vom ERP-System an.
* Das ERP-System liefert eine Liste von Bestellungen zurück.

In der Liste wird nur ein Teil der Bestelldaten übermittelt. In der Regel sind dies die Kopfdaten.

#### Übertragung einer einzelnen Bestellung (Kopf- und Positionsdaten)

* Der Shop fordert eine einzelne Bestellung vom ERP-System an.
* Das ERP-System liefert die Kopf- und alle Positionsdaten der Bestellung zurück.

#### Übertragung einer PDF-Datei

* Der Shop fordert die PDF-Datei vom ERP-System an.
* Das ERP-System liefert die PDF-Datei zurück.
* Der Shop bietet die PDF-Datei dem Kunden als Download an.

#### Storno/Retoure von einer oder mehreren Positionen

* Der Besteller storniert/retourniert eine oder mehrere Positionen.
* Der Shop sendet die Stornierung/Retoure an das ERP-System.
* Das ERP-System bestätigt die Stornierung/Retoure oder lehnt diese ab.

#### Übertragung der letzten Shop-Bestellnummer

* Der Shop fordert die letzte Shop-Bestellnummer vom ERP-System an.
* Das ERP-System liefert die letzte Shop-Bestellnummer zurück.

#### Übertragung des Lagerbestands/Filialbestandes eines einzelnen Produkts

* Der Shop fordert den Lagerbestand zu einem einzelnen Produkt an.
* Das ERP-System liefert den Lagerbestand des Produktes zurück.

#### Übertragung von allgemeinen Kundendaten

* Der Shop fordert allgemeine Kundendaten vom ERP-System an.
* Das ERP-System liefert die allgemeinen Kundendaten zurück.

### Ausschließlich verschlüsselter Abruf

Der Webservice wird ausschließlich über SSL aufgerufen. Unverschlüsselte Verbindungen müssen auf beiden Seiten (Shop/ERP-System) abgelehnt werden.

### UTF-8-Codierung

Alle Daten werden im UTF-8 Format übergeben.

## Fehler

Das ERP-System antwortet mit einem Http-Code ungleich 200, wenn es keine Daten liefern kann. Dies ist beispielsweise in den folgenden Fällen gegeben:

* falsches REST-Passwort
* unbekannte Kundennummer
* unbekannte ShopID/SubshopID
* unbekannter Typ
* interner Fehler
* etc.

Der Shop erwartet einen Fehler-Code, der vom ERP-System vorgegeben wird, und eine optionale Fehlermeldung. Aufgrund des Fehler-Codes kann der Designer dem Besteller sprachabhängige Erläuterungen/Hinweismeldungen anzeigen. Die optionale Fehlermeldung dient nicht dazu, diese dem Besteller anzuzeigen, sondern wird zur Protokollierung in der Log-Datei verwendet. Sie kann daher rein technisch sein.

Der Fehlercode muss eindeutig und in jeder Antwort einheitlich sein. Beispiel:

* 0001: falsches REST-Passwort
* 0002: unbekannte Kundennummer
* 0003: unbekannte ShopID
* 0004: unbekannte SubshopID
* 0005: unbekannter Typ
* 1000: interner Fehler X
* 1001: interner Fehler Y
* 1002: interner Fehler Z
* etc.

Liefert das ERP-System beispielsweise den Fehlercode „0002“, so könnte dem Besteller folgende Meldung angezeigt werden:

„Sehr geehrter Herr Müller,

leider liegen uns derzeit keine Informationen über Ihre Kundennummer vor. Bitte kontaktieren Sie uns unter der Telefonnummer XYZ oder benutzen Sie unser Kontaktformular (→ Link zum Kontaktformular)“

Außerdem können entsprechende (codeabhängige) Grafiken eingeblendet werden.

**Response:**

Http-Code = 400

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
  "ErrCode": 2,
  "ErrMsg": "Unbekannte Kundennummer"
}
```

## Übertragung einer Liste von Bestellungen /GetOrderList

Bei der Übertragung liefert das ERP-System dem Shop

* fest vorgegebene Daten
* beliebige Daten

zurück.

### Anfrage vom Shop für eine Liste von Bestellungen

| Parameter | Max. Länge | Erforderlich | Datentyp | Bemerkung |
| - | - | - | - | - |
| `ShopID` | 128 | ja | String | Eine eindeutige Shop-ID. Die Shop-ID wird von der WEBSALE AG vergeben. |
| `Password` | 128 | ja | String | Das REST-Passwort. Wird von der WEBSALE AG vergeben und muss vom ERP-System geprüft werden. Das ERP-System muss die Anfrage bei einem falschen Passwort ablehnen. |
| `SubshopID` | 128 | ja | String | Eine eindeutige Subshop-ID, in der die Daten angezeigt werden. |
| `CustomerSubshopIDs` | 128 je ID | ja | String-Array | Liste der gültigen Subshops des Kunden |
| `CustomerID` | 64 | ja | String | Eine eindeutige Kundennummer |
| `BillCountry` | 3 | nein | String | Rechnungsland ISO 3166 (beispielsweise DEU) des Bestellers, falls im Shop bekannt. |
| `Type` | | ja | Integer | Ein Typ, der die angeforderten Daten spezifiziert. Bei „0“ liefert das ERP-System alle Typen, die im ERP-System vorhanden sind zurück. Die einzelnen Typen sind im Shop frei konfigurierbar und werden vom ERP-System vorgegeben. Beispiel:  1: Rechnung 2: Retoure 3: Storno usw.  **Bitte beachten:**  Die Typen 1000 bis 1100 sind für interne Zwecke reserviert. |
| `MaxEntries` | | nein | Integer | Die max. Anzahl der Listeneinträge, die gesendet werden sollen. Fehlt der Parameter oder ist er „0“, dann benutzt das ERP-System einen eigenen Standardwert für die maximalen Listeneinträge. |
| `DateFrom` | 10 | nein | String    Format: JJJJ-MM-TT | Ein optionales Anfangsdatum, ab dem die Listeneinträge gesendet werden. Ob „DateFrom“ im Shop genutzt wird, lässt sich im Shop konfigurieren. |
| `DateUntil` | 10 | nein | String    Format: JJJJ-MM-TT | Ein optionales Enddatum, bis zu dem die Listeneinträge gesendet werden. Ob „DateUntil“ im Shop genutzt wird, lässt sich im Shop konfigurieren. |
| `SearchFilters` | | nein | Filter-Array | Optionale freie Suchfilter. Maximal 10 Einträge. |

#### Vom ERP-System vorgegebene freie Suchfilter

Optional können dem ERP-System bis zu 10 freie Suchfilter übergeben werden. Die möglichen Filter und die dazugehörigen Codes werden vom ERP-System vorgegeben.

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
 "SearchFilters" : [
 {
 "Code": 1,
 "Value": "FilterText"
 },
 {
 "Code": 2,
 "Value": "FilterText"
 }
 ],
 ...
}
```

| Parameter | Max. Länge | Erforderlich | Datentyp | Bemerkung |
| - | - | - | - | - |
| `Code` | 16 | ja | String | Der Code des Suchfilters. Das ERP-System gibt vor, welche Codes es unterstützt. Ein Code darf nur die Zeichen a-z, A-Z und 0-9 beinhalten. |
| `Value` | 128 | ja | String | Der Wert, nach dem gefiltert wird. Die maximale eingebbare Länge kann vom Designer eingestellt/verringert werden. |

**Anfrage /GetOrderList**

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
 "ShopID": "myshop",
 "Password": "1234567890",
 "SubshopID": "Deutsch",
 "BillCountry": "DEU",
 "CustomerID": "1001",
 "CustomerSubshopIDs": [
 "Deutsch"
 ],
 "MaxEntries": 10,
 "SearchFilters": [
 {
 "Code": "code01",
 "Value": "1"
 }
 ],
 "Type": 1,
 "DateFrom": "2020-03-02",
 "DateUntil": "2020-03-08",
}
```

### Antwort vom ERP-System

Das ERP-System liefert dem Shop fest vorgegebene und im Shop frei konfigurierbare Daten zurück.

#### Fest vorgegebene Kopfdaten

| Parameter | Max. Länge | Erforderlich | Datentyp | Bemerkung |
| - | - | - | - | - |
| `ID` | 128 | ja | String | Eindeutige ID der Bestellung, beispielsweise die Bestellnummer |
| `Type` | | ja | Integer | Ein Typ, der die gesendeten Daten spezifiziert. Der Typ wird vom ERP-System vergeben/verwaltet und ist im Shop frei konfigurierbar. Beispiel:  1: Rechnung 2: Umtausch 3: Retoure usw. |
| `FileAvailable` | | ja | Boolean | Dieser Parameter gibt an, ob zur Bestellung eine PDF-Datei (beispielsweise die Rechnung/Stornierung etc.) zur Verfügung steht. Mögliche Werte  „true“ oder „false“ |
| `ReturnsFileAvailable` | | nein | Boolean | Nur, wenn Retoure angemeldet wird.  Dieser Parameter gibt an, ob bei einer angemeldeten Retoure eine PDF-Datei (beispielsweise Retourenaufkleber etc.) zur Verfügung steht. Mögliche Werte  „true“ oder „false“ |
| `CancellationFileAvailable` | | nein | Boolean | Nur, wenn ein Storno durchgeführt wird.  Dieser Parameter gibt an, ob bei einem durchgeführten Storno eine PDF-Datei zur Verfügung steht. Mögliche Werte  „true“ oder „false“ |
| `BankTransferRefund` | | nein | Boolean | Nur bei einer möglichen Retoure/Storno.  Dieser Parameter gibt an, ob bei einer möglichen Retoure/Storno die Erstattung per Banküberweisung erfolgt und die Bankverbindung vom Besteller abgefragt werden soll. Mögliche Werte  „true“ oder „false“  Bei true kann das ERP-System dem Shop die hinterlegten Bankdaten des Kunden zusenden. Dann werden die Bank-Felder mit diesen Daten vorbelegt. |
| `RefundBankName` | 128 | nein | String | Name des Kreditinstitutes für die Erstattung |
| `RefundBankOwner` | 128 | nein | String | Kontoinhaber für die Erstattung |
| `RefundBankIBAN` | 128 | nein | String | IBAN für die Erstattung |
| `RefundBankBIC` | 128 | nein | String | BIC für die Erstattung |

#### Im Shop frei konfigurierbare Kopfdaten

Im Shop werden maximal 1000 verschiedene Kopfdaten H1...H1000 unterstützt.

Die maximale Länge eines einzelnen Datensatzes beträgt 4096 Zeichen.

Die Kopfdaten sind im Shop (optional je Typ) frei konfigurierbar.
Beispiel einer Konfigurationsdatei im Shop unabhängig des Daten-Typs:

`<HeadData>`
`H1 = Kundennummer`
`H2 = Auftragsdatum`
`H3 = Auftragsnummer`
`H4 = Rechnungsnummer`
`...`
`</HeadData>`

| Parameter | Max. Länge | Erforderlich | Datentyp | Bemerkung |
| - | - | - | - | - |
| `Name` | 5 | ja | String | Der Name des Kopfdatenfeldes  H1...H1000 |
| `Value` | 4096 je Value | ja | String | Ein oder mehrere Werte die dem Kopfdatenfeld zugeordnet sind.  **Bitte beachten:**  Dieser Parameter darf maximal 10-mal auftreten! |

#### Fest vorgegebene Positionsdaten

| Parameter | Max. Länge | Erforderlich | Datentyp | Bemerkung |
| - | - | - | - | - |
| `PositionID` | 128 | Ja | String | Eindeutige ID der Position, beispielsweise die Artikelnummer oder laufende Positionsnummer |
| `OrderQuantity` | | Ja | Integer | Bestellmenge |
| `MaxReturns` | | Ja | Integer | Maximale Stückzahl der möglichen Retouren.  0 = Keine Retoure möglich |
| `PartReturns` | | Ja | Boolean | true=Teil-Retouren möglich  false= keine Teil-Retouren möglich nur „MaxReturns“ möglich  Beispiel: MaxReturns=5 PartReturns=true → Kunde kann 1..5 Stück retournieren  Beispiel: MaxReturns=5 PartReturns=false → Kunde muss alle 5 Stück retournieren |
| `MaxCancellations` | | Ja | Integer | Maximale Stückzahl der möglichen Stornos.  0 = Kein Storno möglich |
| `PartCancellations` | | Ja | Boolean | true=Teil-Stornos möglich  false= keine Teil-Stornos möglich nur „MaxCancellations“ möglich.  Beispiel: MaxCancellations=5 PartCancellations=true → Kunde kann 1..5 Stück stornieren  Beispiel: MaxCancellations=5 PartCancellations=false → Kunde muss 5 Stück stornieren |

#### Im Shop frei konfigurierbare Positionsdaten

Im Shop werden maximal 1000 verschiedene Positionsdaten P1...P1000 unterstützt.

Die maximale Länge eines einzelnen Datensatzes beträgt 4096 Zeichen.

Die Positionsdaten sind im Shop (optional je Typ) frei konfigurierbar.

Beispiel einer Konfigurationsdatei im Shop unabhängig des Daten-Typs:

`<PositionData>`
`P1 = Artikelnummer`
`P2 = Bezeichnung`
`P3 = Farbe`
`P4 = Gewicht`
`P5 = Stückpreis`
`...`
`</PositionData>`

| Parameter | Max. Länge | Erforderlich | Datentyp | Bemerkung |
| - | - | - | - | - |
| `Name` | 5 | ja | String | Der Name des Positionsdatenfeldes  P1...P1000 |
| `Value` | 4096 je Value | ja | String | Ein oder mehrere Werte die dem Positionsdatenfeld zugeordnet sind.  **Bitte beachten:** Dieser Parameter darf maximal 10-mal auftreten! |

**Antwort /GetOrderList:**

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
[
 {
 "FileAvailable": true,
 "HeadData": [
 {
 "Name": "H1",
 "Value": "015552222"
 },
 {
 "Name": "H2",
 "Value": "10,99"
 },
 {
 "Name": "H3",
 "Value": "19,99"
 },
 ...
 ],
 "ID": "90909009909009",
 "Type": 1
 },
 ...
]
```

## Übertragung einer einzelnen Bestellung /GetOrder

### Anfrage vom Shop für eine einzelne Bestellung

| Parameter | Max. Länge | Erforderlich | Datentyp | Bemerkung |
| - | - | - | - | - |
| `ShopID` | 128 | ja | String | Eine eindeutige Shop-ID. Die Shop-ID wird von der WEBSALE AG vergeben. |
| `Password` | 128 | ja | String | Das REST-Passwort. Wird von der WEBSALE AG vergeben und muss vom ERP-System geprüft werden. Das ERP-System muss die Anfrage bei einem falschen Passwort ablehnen. |
| `SubshopID` | 128 | ja | String | Eine eindeutige Subshop-ID, in der die Bestellungen angezeigt werden. |
| `CustomerSubshopIDs` | 128 je ID | ja | String-Array | Liste der gültigen Subshops des Kunden |
| `CustomerID` | 64 | ja | String | Eine eindeutige Kundennummer |
| `BillCountry` | 3 | nein | String | Rechnungsland ISO 3166 (beispielsweise DEU) des Bestellers, falls im Shop bekannt. |
| `Type` | | ja | Integer | Dieser Wert wurde vom ERP-System in der Liste geliefert und wird hier zurückgegeben. |
| `ID` | 128 | ja | String | Dieser Wert wurde vom ERP-System in der Liste geliefert und wird hier zurückgegeben. |

**Anfrage /GetOrder:**

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
  "ShopID": "myshop",
  "Password": "1234567890",
  "BillCountry": "DEU",
  "CustomerID": "1001",
  "CustomerSubshopIDs": [
    "Deutsch"
  ],
  "ID": "90909009909009",
  "SubshopID": "Deutsch",
  "Type": 1
}
```

### Antwort vom ERP-System /GetOrder:

(Siehe auch [Kopfdaten](#Kopfdaten) und [Positionsdaten](https://websale.atlassian.net/wiki/spaces/Doku/pages/1795719453#Positionsdaten))

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
 "Type": 0,
 "ID": "90909009909009",
 "FileAvailable": true,
 "ReturnFileAvailable": false,
 "CancellationFileAvailable": false,
 "BankTransferRefund": true,
 "HeadData": [
 {
 "Name": H1,
 "Value": Kundennummer
 },
 {
 "Name": H2,
 "Value": Auftragsdatum
 },
 ...
 ],
 "Positions": [
 {
 "MaxCancellations": 0,
 "MaxReturns": 1,
 "OrderQuantity": 1,
 "PartCancellations": true,
 "PartReturns": false,
 "PositionData": [
 {
 "Name": "P1",
 "Value": "Artikelnummer"
 },
 {
 "Name": "P2",
 "Value": "Bezeichnung"
 },
 ...
 ],
 "PositionID": "p0"
 },
 {
 "MaxCancellations": 1,
 "MaxReturns": 2,
 "OrderQuantity": 2,
 "PartCancellations": true,
 "PartReturns": false,
 "PositionData": [
 {
 "Name": "P1",
 "Value": "Artikelnummer"
 }
 ],
 "PositionID": "p1"
 },
 ...
 ]
 }
```

#### Übertragung der möglichen Begründungen bei Storno/Retoure

Optional kann das ERP-System in den Kopfdaten des Auftrags die möglichen Begründungen mitliefern, die der Kunde im Shop bei einem Storno oder einer Retoure auswählen kann.

Dies überschreibt alle in der Konfiguration des Shops hinterlegten Begründungen.

* Zum Überschreiben der Storno-Begründungen muss das **CancellationReasons**-Array übertragen werden.
* Zum Überschreiben der Retoure-Begründungen muss das **ReturnReasons**-Array übertragen werden.

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
 "Type": 0,
 "ID": "90909009909009",
 "FileAvailable": true,
 "ReturnFileAvailable": false,
 "CancellationFileAvailable": false,
 "BankTransferRefund": true,
 "CancellationReasons": [
 {
 "Code": 0,
 "Text": "Ohne Begründung"
 },
 {
 "Code": 1,
 "Text": "Falsch bestellt"
 },
 ...
 ],
 "ReturnReasons": [
 {
 "Code": 0,
 "Text": "Ohne Begründung"
 },
 {
 "Code": 1,
 "Text": "Falsch bestellt"
 },
 ...
 ],
 ...
 }
```

| Parameter | Max. Länge | Erforderlich | Datentyp | Bemerkung |
| - | - | - | - | - |
| `Code` | | ja | Integer | Der Code der Begründung |
| `Text` | 1024 | ja | String | Der lesbare Text der Begründung, der im Shop zur Auswahl steht. |

## Übertragung einer PDF-Datei

Wird beispielsweise eine Rechnung per PDF angefordert, so liefert das ERP-System alle Daten einer Bestellung:

* komplette Rechnungsadresse
* komplette Lieferadresse
* alle Artikel der Bestellung
* Gesamtsumme
* Zahlungsart
* Versandart/Zusteller
* usw.

Der Shop übergibt dem ERP-System die eindeutige ID der Bestellung und den Typ, den das ERP-System in der Bestellung gesendet hat.

**Retouren**

Wird eine Retoure angemeldet, dann kann das ERP-System dem Shop eine PDF-Datei (Retourenaufkleber etc.) zur Verfügung stellen und gibt dies dem Shop in den Kopfdaten bekannt.

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
 "Type": 0,
 "ID": "90909009909009",
 "FileAvailable": true,
```

**"ReturnFileAvailable": true,**

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
 "CancellationFileAvailable": false,
 "BankTransferRefund": false,
 ...
}
```

Die PDF-Datei einer Retoure wird mit dem Typ „1001“ angefordert.

**Stornos**

Wird ein Storno durchgeführt, dann kann das ERP-System dem Shop eine PDF-Datei (Stornobestätigung etc.) zur Verfügung stellen und gibt dies dem Shop in den Kopfdaten bekannt.

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
 "Type": 0,
 "ID": "90909009909009",
 "FileAvailable": true,
 "ReturnFileAvailable": false,
```

**"CancellationFileAvailable": true,**

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
 "BankTransferRefund": false,
 ...
}
```

Die PDF-Datei eines Stornos wird mit dem Typ „1002“ angefordert.

### Anfrage vom Shop für eine einzelne Bestellung als PDF-Datei /GetFile

| Parameter | Max. Länge | Erforderlich | Datentyp | Bemerkung |
| - | - | - | - | - |
| `ShopID` | 128 | ja | String | Eine eindeutige Shop-ID. Die Shop-ID wird von der WEBSALE AG vergeben. |
| `Password` | 128 | ja | String | Das REST-Passwort. Wird von der WEBSALE AG vergeben und muss vom ERP-System geprüft werden. Das ERP-System muss die Anfrage bei einem falschen Passwort ablehnen. |
| `SubshopID` | 128 | ja | String | Eine eindeutige Subshop-ID, in der die Bestellungen angezeigt werden. |
| `CustomerSubshopIDs` | 128 je ID | ja | String-Array | Liste der gültigen Subshops des Kunden |
| `CustomerID` | 64 | ja | String | Eine eindeutige Kundennummer |
| `BillCountry` | 3 | nein | String | Rechnungsland ISO 3166 (beispielsweise DEU) des Bestellers, falls im Shop bekannt. |
| `Type` | | ja | Integer | Dieser Wert wurde vom ERP-System in der Liste geliefert und wird hier zurückgegeben.    **Bitte beachten Sie:**  Liegt ein Retouren-PDF vor und meldet der Kunde eine Retoure an, dann sendet der Shop den Typ „1001“ und fordert damit das Retouren-Dokument an. Analog wird bei einem durchgeführten Storno der Typ „1002“ übergeben. |
| `ID` | 128 | ja | String | Dieser Wert wurde vom ERP-System geliefert und wird hier zurückgegeben. |

**Anfrage /GetFile:**

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
  "BillCountry": "DEU",
  "CustomerID": "1001",
  "CustomerSubshopIDs": [
    "Deutsch"
  ],
  "ID": "90909009909009",
  "Password": "1234567890",
  "ShopID": "myshop",
  "SubshopID": "Deutsch",
  "Type": 1
}
```

### Antwort vom ERP-System als PDF-Datei /GetFile

Das ERP-System liefert folgende Daten zurück:

| Parameter | Max. Länge | Erforderlich | Datentyp | Bemerkung |
| - | - | - | - | - |
| `FileName` | 128 | ja | String | Name der PDF-Datei, beispielsweise 12345.pdf |
| `FileData` | 2 MByte | ja | String | Base64-kodierte PDF-Daten |

**Antwort vom ERP-System /GetFile:**

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
  "FileName": "1234567890.pdf",
  "FileData": "Base64-kodierte PDF-Daten"
}
```

Der Dateiname sollte vom ERP-System möglichst eindeutig generiert werden, beispielsweise aus der Rechnungsnummer und der Endung „pdf“. Er sollte keine Sonderzeichen oder Leerzeichen beinhalten.

Das Dateiformat muss nicht notwendigerweise PDF sein. Prinzipiell kann jedes Format gesendet werden, welches eine möglichst hohe Verbreitung unter den Internet-Usern hat. Derzeit ist PDF die beste Wahl.

## Storno/Retoure von Positionen einer Bestellung

Wie oben beschrieben gibt das ERP-System je Position bekannt, ob und wie viele Stücke storniert/retourniert werden können.

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
 ...
 "Positions": [
 {
 "MaxCancellations": 0,
 "MaxReturns": 2,
 "OrderQuantity": 2,
 "PartCancellations": false,
 "PartReturns": true,
 "PositionData": [
 {
 "Name": "P3",
 "Value": "asdf0000"
 }
 ],
 "PositionID": "1"
 },
 ...
```

Somit könnte ein Besteller beispielsweise die erste Position stornieren und die 2. Position retournieren, falls die 2. Position bei einer Teillieferung bereits ausgeliefert wurde.

Eine Position kann entweder storniert oder retourniert werden. Beides gleichzeitig ist nicht möglich.

**Storno je Position**
Übergibt das ERP-System den Wert „0“, dann wird kein Storno angeboten. Ansonsten wird eine

* Storno-Checkbox
* Mengeneingabefeld, falls MaxCancellations > 1
* DropDown-Liste für eine Begründung

angeboten.

**Retoure je Position**
Übergibt das ERP-System den Wert „0“, dann wird keine Retoure angeboten. Ansonsten wird eine

* Retouren-Checkbox
* Mengeneingabefeld, falls MaxReturns > 1
* DropDown-Liste für eine Begründung

angeboten.

Der Shop bietet optional zu jeder Position eine frei konfigurierbare DropDown-Liste an, mittels derer der Kunde eine Begründung angeben kann. Dem ERP-System wird hierzu ein Code übermittelt.

Beispiel für Retouren:
0=keine Begründung angegeben
1=Qualität gefällt nicht
2=Falscher Artikel geliefert
3=zu spät geliefert
etc.

Der Code und die Texte werden vom ERP-System vorgegeben und im Shop hinterlegt.

**Abfragen der Bankverbindung**
Meldet das ERP-System dem Shop, dass die Bankverbindung für die Erstattung abgefragt werden soll (BankTransferRefund=true), so werden 4 weitere Eingabefelder als Pflichtfelder

* Name der Bank
* Kontoinhaber
* IBAN
* BIC

angezeigt.

### Senden einer Retoure oder eines Stornos an das ERP-System /CancelOrder

| Parameter | Max. Länge | Erforderlich | Datentyp | Bemerkung |
| - | - | - | - | - |
| `ShopID` | 128 | ja | String | Eine eindeutige Shop-ID. Die Shop-ID wird von der WEBSALE AG vergeben. |
| `Password` | 128 | ja | String | Das REST-Passwort. Wird von der WEBSALE AG vergeben und muss vom ERP-System geprüft werden. Das ERP-System muss die Anfrage bei einem falschen Passwort ablehnen. |
| `SubshopID` | 128 | ja | String | Eine eindeutige Subshop-ID, in der die Bestellungen angezeigt werden. |
| `CustomerSubshopIDs` | 128 je ID | ja | String-Array | Liste der gültigen Subshops des Kunden |
| `CustomerID` | 64 | ja | String | Eine eindeutige Kundennummer |
| `BillCountry` | 3 | nein | String | Rechnungsland ISO 3166 (beispielsweise DEU) des Bestellers, falls im Shop bekannt. |
| `ID` | 128 | ja | String | Dieser Wert wurde vom ERP-System für die Bestellung übergeben und wird hier zurückgegeben. |
| `PositionID` | 128 | ja | String | Dieser Wert wurde vom ERP-System für die Position übergeben und wird hier zurückgegeben. |
| `CancelType` | | ja | Integer | 1=Storno  2=Retoure |
| `Quantity` | | Ja | Integer | Menge/Stückzahl pro Position, die retourniert/storniert werden soll. |
| `ReasonCode` | | Nein | Integer | Code der Begründung. |
| `RefundBankName` | 128 | nein | String | Name des Kreditinstitutes, falls die Erstattung per Banküberweisung erfolgt |
| `RefundBankOwner` | 128 | nein | String | Kontoinhaber, falls die Erstattung per Banküberweisung erfolgt |
| `RefundBankIBAN` | 128 | nein | String | IBAN, falls die Erstattung per Banküberweisung erfolgt |
| `RefundBankBIC` | 128 | nein | String | BIC, falls die Erstattung per Banküberweisung erfolgt |

**Anfrage /CancelOrder:**

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
 "ShopID": "myshop",
 "Password": "1234567890",
 "SubshopID": "Deutsch",
 "BillCountry": "DEU",
 "CustomerID": "1001",
 "CustomerSubshopIDs": [
 "Deutsch"
 ],
 "ID": "90909009909009",
 "RefundBankBIC": "BIC",
 "RefundBankIBAN": "IBAN",
 "RefundBankName": "Bankname",
 "RefundBankOwner": "Kontoinhaber",
 "Positions": [
 {
 "PositionID": "1",
 "CancelType": 1,
 "ReasonCode": 0,
 "Quantity": 1
 },
 ...
 ]
}
```

**Bitte beachten Sie:**
Es werden nur die Positionen an das ERP-System gesendet, die storniert/retourniert werden sollen.

### Antwort vom ERP-System /CancelOrder

Das ERP-System liefert alle Daten (Kopf- und alle Positionsdaten) der Bestellung zurück.

**Zusätzliche Kopfdaten**
In den Kopfdaten kann das ERP-System jetzt und in späteren Anfragen zu dieser Bestellung mitteilen, dass eine Retouren-PDF-Datei, bzw. Storno-PDF-Datei abgeholt werden kann.

| Parameter | Max. Länge | Erforderlich | Datentyp | Bemerkung |
| - | - | - | - | - |
| `ReturnsFileAvailable` | | nein | Boolean | Nur, wenn Retoure angemeldet wurde.  Dieser Parameter gibt an, ob bei einer angemeldeten Retoure eine PDF-Datei (beispielsweise Retourenaufkleber etc.) zur Verfügung steht. Mögliche Werte  „true“ oder „false“ |
| `CancellationFileAvailable` | | nein | Boolean | Nur, wenn ein Storno durchgeführt wurde.  Dieser Parameter gibt an, ob bei einem durchgeführten Storno eine PDF-Datei zur Verfügung steht. Mögliche Werte  „true“ oder „false“ |

**Zusätzliche Positionsdaten**
Das ERP-System meldet für jede Position, welche Aktion durchgeführt wurde und ob die Aktion erfolgreich bzw. nicht erfolgreich war. Diese Werte sollten nur einmal gesendet werden. Bei späteren Anfragen sollten diese dann entfallen.

| Parameter | Max. Länge | Erforderlich | Datentyp | Bemerkung |
| - | - | - | - | - |
| `CancelType` | | nein | Integer | 1=Storno 2=Retoure |
| `CancelErrCode` | | nein | Integer | Ein Fehlercode 0: Alles OK  >0: Fehler (wird vom ERP-System verwaltet) |
| `CancelErrMsg` | 1024 | nein | String | Eine optionale Fehlermeldung vom ERP-System |

**Bitte beachten Sie:**
Wurde eine Position erfolgreich retourniert, so muss das ERP-System die Werte für

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
"MaxReturns": 0,
"PartReturns": false,
```

in dieser Antwort (und allen späteren Antworten) entsprechend anpassen, damit der Besteller nicht erneut retournieren kann. Das gleiche gilt für eine erfolgreiche Stornierung.

Außerdem sollte das ERP-System ab diesem Zeitpunkt das Datum und die Uhrzeit der Stornierung/Retoure übergeben, damit diese Informationen dem Besteller bei späteren Abfragen angezeigt werden können.

**Antwort /CancelOrder (Beispiel: Besteller hat 2. Position storniert und 3. Position retourniert):**

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
 "Type": 0,
 "BankTransferRefund": true,
 "FileAvailable": true,
 "ID": "90909009909009",
 "HeadData": [
 {
 "Name": "H1",
 "Value": "Kundennummer"
 },
 ...
 ],
 "Positions": [
 {
 "MaxCancellations": 2,
 "MaxReturns": 0,
 "OrderQuantity": 2,
 "PartCancellations": true,
 "PartReturns": false,
 "PositionData": [
 {
 "Name": "P1",
 "Value": "Artikelnummer”
 },
 ...
 ],
 "PositionID": "1"
 },
 {
 "MaxCancellations": 0,
 "MaxReturns": 0,
 "OrderQuantity": 1,
 "PartCancellations": false,
 "PartReturns": false,
 "CancelType": 1,
 "CancelErrCode": 0,
 "CancelErrMsg": "Position erfolgreich storniert",
 "PositionData": [
 {
 "Name": "P1",
 "Value": "Artikelnummer"
 },
 ...
 ],
"PositionID": "2” },
 {
 "MaxCancellations": 0,
 "MaxReturns": 0,
 "OrderQuantity": 2,
 "PartCancellations": false,
 "PartReturns": false,
 "CancelType": 2,
 "CancelErrCode": 0,
 "CancelErrMsg": "Retoure erfolgreich angemeldet",
 "PositionData": [
 {
 "Name": "P3",
 "Value": "asdf0003"
 }
 ],
 "PositionID": "3"
 },
 ...
 ]
}
```

## Übertragung der letzten Shop-Bestellnummer /GetLastOrderNumber

Damit der Shop die Bestellungen anzeigen kann, die noch nicht in das ERP-System importiert wurden, ist es erforderlich, dass das ERP-System dem Shop die letzte Shop-Bestellnummer mitteilt, welches das ERP-System importiert hat bzw. dem ERP-System bekannt ist.

Die Anfrage des Shops enthält folgende Parameter:

| Parameter | Max. Länge | Erforderlich | Datentyp | Bemerkung |
| - | - | - | - | - |
| `ShopID` | 128 | ja | String | Eine eindeutige Shop-ID. Die Shop-ID wird von der WEBSALE AG vergeben. |
| `Password` | 128 | ja | String | Das REST-Passwort. Wird von der WEBSALE AG vergeben und muss vom ERP-System geprüft werden. Das ERP-System muss die Anfrage bei einem falschen Passwort ablehnen. |
| `SubshopID` | 128 | ja | String | Eine eindeutige Subshop-ID, in der die Bestellungen angezeigt werden. |
| `CustomerSubshopIDs` | 128  je ID | ja | String-Array | Liste der gültigen Subshops des Kunden |
| `CustomerID` | 64 | ja | String | Eine eindeutige Kundennummer |
| `BillCountry` | 3 | nein | String | Rechnungsland ISO 3166 (beispielsweise DEU) des Bestellers, falls im Shop bekannt. |

**Anfrage vom Shop /GetLastOrderNumber:**

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
  "ShopID": "myshop",
  "Password": "1234567890",
  "SubshopID": "Deutsch",
  "BillCountry": "DEU",
  "CustomerID": "1001",
  "CustomerSubshopIDs": [
    "Deutsch"
  ]
}
```

### Antwort vom ERP-System für die letzte Shop-Bestellnummer /GetLastOrderNumber

Das ERP-System liefert folgende Daten zurück:

| Parameter | Max. Länge | Erforderlich | Datentyp | Bemerkung |
| - | - | - | - | - |
| `LastOrderNumber` | 64 | ja | String | Shop-Bestellnummer |

**Antwort vom ERP-System /GetLastOrderNumber:**

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
  "LastOrderNumber": "1234567890"
}
```

## Abfrage eines einzelnen Lagerbestandes (einer Filiale) /GetStockAmount

Diese Funktion eignet sich für die Abfrage in Echtzeit, ob ein Produkt in einer ausgewählten Filiale verfügbar ist.

Die Anfrage des Shops enthält folgende Parameter:

| Parameter | Max. Länge | Erforderlich | Datentyp | Bemerkung |
| - | - | - | - | - |
| `ShopID` | 128 | ja | String | Eine eindeutige Shop-ID. Die Shop-ID wird von der WEBSALE AG vergeben. |
| `Password` | 128 | ja | String | Das REST-Passwort. Wird von der WEBSALE AG vergeben und muss vom ERP-System geprüft werden. Das ERP-System muss die Anfrage bei einem falschen Passwort ablehnen. |
| `SubshopID` | 128 | ja | String | Eine eindeutige Subshop-ID |
| `ProductNumber` | 64 | ja | String | Artikelnummer |
| `BranchID` | 64 | nein | String | Optionale Filial-ID |

Die Filial-ID ist optional. Wird keine Filial-ID übergeben, dann liefert das ERP-System den Lagerbestand des Artikels bzgl. des Subshops. Wird eine Filial-ID übergeben, dann liefert das ERP-System den Lagerbestand bzgl. der Filiale.

**Anfrage vom Shop /GetStockAmount:**

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
  "ShopID": "myshop",
  "Password": "1234567890",
  "SubshopID": "Deutsch",
  "ProductNumber": "1234567",
  "BranchID": "123"
}
```

### Antwort vom ERP-System für den einzelnen Lagerbestand /GetStockAmount

Das ERP-System liefert folgende Daten zurück:

| Parameter | Max. Länge | Erforderlich | Datentyp | Bemerkung |
| - | - | - | - | - |
| `StockAmount` | | ja | Integer | Lagerbestand |

**Antwort vom ERP-System /GetStockAmount:**

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
  "StockAmount": 100
}
```

## Übertragung von allgemeinen, zusätzlichen Kundendaten /GetCommonData

Bei diesen Informationen geht es nicht um Bestelldaten, sondern um zusätzliche, frei konfigurierbare Kundendaten, wie beispielsweise die angesammelten Bonuspunkte oder die Rabatte eines Kunden bei einem Kauf.

Die Anfrage des Shops enthält folgende Parameter:

| Parameter | Max. Länge | Erforderlich | Datentyp | Bemerkung |
| - | - | - | - | - |
| `ShopID` | 128 | ja | String | Eine eindeutige Shop-ID. Die Shop-ID wird von der WEBSALE AG vergeben. |
| `Password` | 128 | ja | String | Das REST-Passwort. Wird von der WEBSALE AG vergeben und muss vom ERP-System geprüft werden. Das ERP-System muss die Anfrage bei einem falschen Passwort ablehnen. |
| `SubshopID` | 128 | ja | String | Eine eindeutige Subshop-ID |
| `CustomerSubshopIDs` | 128 je ID | ja | String-Array | Liste der gültigen Subshops des Kunden |
| `CustomerID` | 64 | ja | String | Eine eindeutige Kundennummer |
| `Type` | | nein | Integer | Die möglichen Werte legt das ERP-System fest. Ist der Typ 0, dann liefert das ERP-System alle allgemeinen Daten zurück.  **Bitte beachten:** Die Typen 1000 bis 1100 sind für interne Zwecke reserviert. |
| `BillCountry` | 3 | nein | String | Rechnungsland ISO 3166 (beispielsweise DEU) des Bestellers, falls im Shop bekannt. |

**Anfrage vom Shop /GetCommonData:**

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
  "ShopID": "myshop",
  "Password": "1234567890",
  "SubshopID": "Deutsch",
  "BillCountry": "DEU",
  "CustomerID": "1001",
  "CustomerSubshopIDs": [
    "Deutsch"
  ],
  "Type": 1
}
```

### Antwort vom ERP-System für allgemeine Daten /GetCommonData

Das ERP-System liefert im Shop frei konfigurierbare Daten zurück.

#### Im Shop frei konfigurierbare Daten:

Im Shop werden maximal 1000 verschiedene Commondaten C1...C1000 unterstützt.

Die maximale Länge eines einzelnen Datensatzes beträgt 4096 Zeichen.

Commondaten sind im Shop (optional je Typ) frei konfigurierbar.
Beispiel einer Konfigurationsdatei im Shop unabhängig des Daten-Typs:

`<CommonData>`
`C1 = Bonuspunkte`
`C2 = Kundenspezifische Rabatte nach Kalenderjahr`
`...`
`</CommonData>`

| Parameter | Max. Länge | Erforderlich | Datentyp | Bemerkung |
| - | - | - | - | - |
| `Name` | 5 | ja | String | Der Name des Commondatenfeldes  C1...C1000 |
| `Value` | 4096  je Value | ja | String | Ein oder mehrere Werte, die dem Commondatenfeld zugeordnet sind.  **Bitte beachten:** Dieser Parameter darf maximal 10-mal auftreten! |

**Antwort vom ERP-System /GetCommonData:**

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
[
{
 "Name": "C1",
 "Value": "100"
 },
 {
 "Name": "C2",
 "Value": [
 "umsatzabhängiger Kundenrabatt 2010: 5%",
 "umsatzabhängiger Kundenrabatt 2011: 12%",
 "umsatzabhängiger Kundenrabatt 2012: 5%",
 "umsatzabhängiger Kundenrabatt 2013: 12%"
 ]
 },
 ...
]
```

## Verwandte Themen

* [WS-Bestelldaten](https://dokumentation.websale.de/v8s/schnittstellen/bestellungen/ws-bestelldaten.md)
* [Kundendaten](https://dokumentation.websale.de/v8s/schnittstellen/kundendaten.md)
* [WS-SOAP-Lagerbestand](https://dokumentation.websale.de/v8s/schnittstellen/produkte-und-kategorien/ws-soap-lagerbestand.md)


## Related topics

- [Bestellungen](https://dokumentation.websale.de/v8s/schnittstellen/bestellungen.md)
- [WS-SOAP-Lagerbestand](https://dokumentation.websale.de/v8s/schnittstellen/produkte-und-kategorien/ws-soap-lagerbestand.md)
- [WS-SFTP-Produkte-Pro](https://dokumentation.websale.de/v8s/schnittstellen/produkte-und-kategorien/ws-sftp-produkte-pro.md)
- [Kundendaten](https://dokumentation.websale.de/v8s/schnittstellen/kundendaten.md)
- [Kategorien und weitere Dateien](https://dokumentation.websale.de/v8s/schnittstellen/produkte-und-kategorien/ws-sftp-produkte-pro/kategorien-und-weitere-dateien.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.