Zum Hauptinhalt springen

Wie binde ich einen Shop an die API des K3s an?

Normalerweise wird für die Anbindung des Konfigurators an einen Shop ein Plugin im Shop installiert. Dieses stellt eine Schnittstelle bereit, auf die der K3 zugreifen kann. Damit wird dann die Shop-Anbindung realisiert.

Für die individuelle Anbindung an eigene Shops oder andere Backend-Systeme kann diese API ebenfalls verwendet werden. Dazu müssen Shop-seitig in einem Plugin die folgenden Endpunkte implementiert werden:

Authentifikation

Das Plugin ruft API-Methoden des K3 auf. Dafür muss es sich authentifizieren können. Ebenso sollten die Endpunkte des Plugins (Ausnahme: Warenkorb) nicht offen zugänglich sein.

Aus diesem Grund werden K3 und Plugin zunächst miteinander verbunden. Dabei wird das plugin vom K3 aus provisioniert: Ein Token für die Benutzung der K3-API sowie ein Secret zur Absicherung der Plugin API werden dem Plugin vom K3 mitgeteilt. Als Antwort übermittelt das Plugin dem K3 die URLs seiner API-Endpunkte (denn die können bei jedem Shop-System anders sein). Dazu ruft der K3 eine feste URL des Plugins per POST Request auf.

POST <URL>

Die URL muss in den Einstellungen des Konfigurators im K3 angegeben werden. Folgende Parameter werden übertragen:

  • token ein K3 API Token im Klartext, dass das Plugin bei Aufrufen der API angeben muss.
  • secret ein zufälliger String, den der K3 bei Aufrufen des Plugins im Header X-Secret angibt. Das Plugin sollte prüfen, ob das Secret stimnmt.

Die folgenden Werte müssen in einem JSON zurückgeliefert werden:

  • cart URL der Warenkorb-API
  • articles URL der Artikel-API

Auch dieser Aufruf muss mit dem secret gesichert sein, sobald eines im Plugin gesetzt ist. Es muss also das alte secret im Header X-Secret gesetzt sein, wenn ein neues gesetzt werden soll.

Wenn dies implementiert ist, kann man sich vom K3 aus bereits verbinden.

Artikel & Preise

Unter einer definierten URL stellt das Plugin einen Endpunkt zur Verfügung, mit dem alle Artikel geliefert werden.

GET <articles>

ermittelt das Plugin alle relevanten Artikel und deren Preise in JSON als Array mit folgenden Einträgen:

  • no Artikelnummer
  • name Name
  • description Beschreibung
  • category Kategorie (als Text)
  • deliveryTime (integer, optional): Zahl der Tage bis zur Lieferung
  • stockQty (number, optional): aktueller Lagerbestand
  • prices (array) mit folgenden Einträgen (wie Artikelpreis im K3):
    • price (number): Der Betrag des Preises
    • currency (String, optional): Die Währung des Preises (derzeit nicht verwendet)
    • unit (String, optional): Die Einheit des Preises (derzeit nicht verwendet)
    • sort (number, default 0): Priorität des Preises bei mehreren Gültigen
    • displayOnly (string, optional): Nur, wenn dieser Wert NULL ist, wird der Preis zur Preisberechnung herangezogen. Ansonsten können das z.B Streichpreise sein. Die Art wird dann durch den Inhalt dieses Feldes festgelegt, z.B. 'streich'.
    • fromDate (datetime, optional): Beginn des gültigen Zeitraumes - NULL: schon immer.
    • toDate (datetime, optional): End des gültigen Zeitraumes - NULL: bis in alle Ewigkeit.
    • fromQty (number, optional): Minimal gültig Anzahl (Mengenrabatt) - NULL: ab 0.
    • toQty (number, optional): Maximal gültig Anzahl (Mengenrabatt) - NULL: beliebig viele.
    • toQty (number, optional): Maximal gültig Anzahl (Mengenrabatt) - NULL: beliebig viele.
    • type (string, optional='fixed'): kann einen der folgenden Werte annehmen:
      • fixed: Festpreis
      • surcharge: Aufschlag - der Artikel wird dem Kunden gezeigt, sein Preis ist der Aufschlag auf die Summe aller Fixpreise
      • surchargeHidden: versteckter Aufschlag - der Artikel wird dem Kunden nicht gezeigt, alle Fixpreise sind um den Aufschlag erhöht.

Im einfachsten Fall liefert das Plugin ein solches Dokument:

[
{
"no":"ART_0001",
"name": "Erster Artikel",
"description": "Ist länger…",
"prices": [
{"price":123.34}
],
},
...
]

Dieser Aufruf ist mit dem secret gesichert.

Warenkorb

Unter einer definierten URL stellt das Plugin einen Endpunkt zur Verfügung, mit dem eine Konfiguration in den Warenkorb gelegt werden kann. Nach Aufruf von

GET <cart>?cfg={code}

fragt das Plugin beim K3 die Shop-API ab. Die erhaltenen Daten trägt es dann in den Warenkorb des aktuellen Nutzers ein. Daher muss dieser Endpunkt aus dem Frontend aufgerufen werden.

Wie die Konfiguration im Warenkorb abgelegt wird, ist Sache des Plugins. Mehrere Arten sind denkbar, ggf. kann das am Plugin eingestellt werden:

  • Jeder Artikel der Stückliste der Konfiguration wird einzeln in den Warenkorb gelegt.
  • Es wird für jede Konfiguration ein neuer Artikel mit Name, Beschreibung, Preis und Bild angelegt und in den Warenkorb gelegt.
  • Es wird ein bestimmter Artikel in den Warenkorb gelegt und die Daten zur Konfiguration (Beschreibung, Preis, Bild, Code) in Metadaten zur Warenkorbposition abgelegt.
  • Ggf verfügt der Shop über ein Set-Feature, kann wird ein Set in den Warenkorb gelegt mit den Artikeln der Stückliste darin.

In allen Fällen sollte ein Rücksprung vom Warenkorb in den Konfigurator mit der Konfiguration möglich sein.

Der Endpunkt kann direkt, zB in einem neuen Tab, geöffnet werden: Er liefert ein HTTP-Redirect zum Warenkorb zurück. Damit umgehen wir mögliche CORS Probleme beim Shop.

Dieser Aufruf ist nicht mit dem secret gesichert.

K3 Shop API

Dieser Endpunkt wird vom K3 bereitgestellt und vom Shop-Plugin aufgerufen:

GET https://k3-api.objectcode.de/api/v1.0/cfg/{cfg}/shop

Da beim Ergebnis u.U. Kundendaten mitkommen, ist Authentifizierung erforderlich: Dazu wird dieser Header mit dem in der Authentifikation gelieferten K3 API Token gesetzt:

Authorization: Bearer TOKEN

Parameter

  • cfg (string): Der Code der Konfiguration

Ergebnis

  • code (string): Der Code der Konfiguration
  • app (string): Der Name des Konfigurators
  • price (number): Der Gesamtpreis
  • description (string): Eine Beschreibung der Nutzerauswahlen - in HTML
  • image (string, optional): URL des Bildes der Konfiguration
  • customer (object, optional): Kundendaten - normalerweise im Shopkontext nicht erfasst.
  • variables (optional): Produktmerkmale, sollten möglichst als Metadaten an der Warenkorbposition abgelegt werden.
    • variable: Merkmal - dasselbe Merkmal kann u.U. öfter auftauchen, wenn es ein Multiselect ist.
      • id: interne ID, möglichst nicht nutzen
      • key: kann im Entwickler-Modus am Merkmal gesetzt werden
      • label: Name der Variable
    • value: Vom Nutzer eingegebener oder ausgewählter Wert
    • selected: Die vom Nutzer direkt oder indirekt ausgewählte Option (bei Zahlen z.B. u.U. das Zahlenintervall)
      • id: interne ID, möglichst nicht nutzen
      • key: kann im Entwickler-Modus am Wert gesetzt werden
      • label: Name des Wertes
    • variables: Falls dieser Merkmalswert für sich genommen konfiguriert werden kann (bei einer Teile-Liste), findet sich hier eine Merkmalliste, eine Ebene tiefer. Das kann beliebig tief verschachtelt sein.
  • bom (object): Stückliste, aufbereitet:
    • qty (number): Menge
    • article (string): Artikelnummer
    • main (boolean, optional): nur ein Artikel darf main==true haben. Falls der Shop das erlaubt, wird dieser Artikel (mit seiner Anzahl, die normalerweise 1 ist) in den Warenkorb gelegt und alle anderen als Unterartikel darunter gelegt.
  • files (Liste, optional): Dateien zur Konfiguration
    • key: Ein Namensschlüssel für die Datei, z.B. 'camera_1' oder 'logo', kann mehrdeutig sein
    • filename: Dateiname beim Upload
    • url: URL der Datei

Beispiel:

{
"code": "TG7DTPR9CP",
"app": "Chair",
"price": 323,
"customer": {
"address": null,
"dataPrivacy": "Die Datenschutzhinweise habe ich zur Kenntnis genommen und akzeptiere sie.",
"name": "Mustermann",
"email": "mustermann@test.test",
"phone": null,
"remark": null,
"company": null,
"taxID": null,
"checkboxAccepted": true
},
"variables": [
{
"variable": {
"id": 31,
"key": null,
"label": "Rest Leg"
},
"value": "Ohne Rest leg",
"selected": {
"id": 91,
"key": null,
"value": null,
"label": "Ohne Rest leg"
}
},
{
"variable": {
"id": 32,
"key": null,
"label": "Lederfarbe"
},
"value": "#dec7c7",
"selected": {
"id": 93,
"key": null,
"value": "#dec7c7",
"label": "Grau"
}
}
],
"bom": [
{
"article": "Test2",
"qty": 1
}
],
"files": [
{
"key": "camera_0",
"filename": "blob",
"url": "http://k3.objectcode.de/data/client/2ee94f75-2a17-45d0-a17d-05ac99007499/app/3771b7e2-a799-4e32-93cc-bfb247116e1b/cfg/TG7DTPR9CP/hO0y2HhCv3RGLCeBeIzFx8mbCXkfdqak9yF12PqU.png"
},
{
"key": "camera_1",
"filename": "blob",
"url": "http://k3.objectcode.de/data/client/2ee94f75-2a17-45d0-a17d-05ac99007499/app/3771b7e2-a799-4e32-93cc-bfb247116e1b/cfg/TG7DTPR9CP/hRDYMMJKBeOo4XclWsimGIQhnmVfmcJIBNqPB0gB.png"
}
],
"image": "http://k3.objectcode.de/data/client/2ee94f75-2a17-45d0-a17d-05ac99007499/app/3771b7e2-a799-4e32-93cc-bfb247116e1b/cfg/TG7DTPR9CP/hO0y2HhCv3RGLCeBeIzFx8mbCXkfdqak9yF12PqU.png"
}

Bestellung

Wenn ein Warenkorb bestellt wird, ruft das Plugin die Konfigurations-API auf. Der Status der Konfiguration wird auf ordered gesetzt.


PUT https://k3-api.objectcode.de/api/v1.0/cfg/{cfg}/state

Speichert eine Konfigurationsänderung. Auch hier ist natürlich Authentifikation erforderlich.

Parameter

  • cfg (string): Der Code der Konfiguration

Body

  • state (string): Eines von: draft, basket, quoted, ordered

Programmatische Warenkorb-Anbindung bei Iframe

Wenn der Konfigurator bereits in einem IFrame in den Shop eingebettet ist, ist das Öffnen des Warenkorbs in einem neuen Tab ggf. nicht gewünscht.

In diesem Fall kann dem Shop die Konfiguration unsichtbar für den Benutzer übergeben werden.

  • Klicken Sie auf das Stift-Symbol an dem Block, der Preis und Bestellen-Knöpfe enthält
  • Nehmen Sie den Haken bei An Shop senden heraus
  • Setzen Sie den Haken bei JavaScript Event senden

Nun wird, sobald der Nutzer den Knopf drückt, die Konfiguration gespeichert (dabei der Konfigurations-Code erzeugt) und dann ein JavaScript-Event an den umgebenden Frame gesendet, der den Konfigurations-Code enthält.

Im umgebenden Frame muss nun folgender Code eingefügt werden:

  window.addEventListener("message", function (event) {
if(event.data.type == "K3ConfigurationSaved"){
console.log("Received message: " + event.data.code);
// hier den Event bearbeiten. Den Konfigurationscode findet man in: event.data.code
}
}, false);

Der Shop sollte nun mit der Shop API oben die Konfigurationsdaten abrufen und in den Warenkorb legen.