Bessa Direkt Integration API

Bessa Direkt Integration API

Die Bessa Direkt Integration wird für die Digitale Kundenbindung benötigt und übermittelt Rechnungsinformationen an das Bessa System. Weiters kann über die Direkt Integration der Einlöse Prozess von Punkte und Stempelkarten vereinfacht werden.

Sammeln

Die Kasse muss die Rechnungsposition an den Bessa Server senden über eine REST Schnittstelle (siehe REST API Dokumentation). Die Rechnungsposition werden am Server gespeichert.

  1. Variante: Klassischer Rechnungsscan
    Kunde scannt eine Rechnung mit Hilfe des QR-Codes. Über die Rechnungspositionen werden ihm die korrekten Artikel aufgebucht.

  2. Variante: Kasse scannt App
    Jeder Benutzer der Bessa App bekommt eine ID zugeordnet. Die Kasse scannt den Kunden-QR-Code während der Bestellung. Die Kasse speichert diese ID und hinterlegt sie bei den Rechnungspositionen welche auf den Bessa Server geschickt werden. (siehe REST API Dokumentation).

  3. Variante: Kundenkarte (digital oder als echte Plastik Kundenkarte)
    Jeder Benutzer der Bessa App oder Plastikkartenbesitzer bekommt eine Kundennummer zugeordnet. Diese Kundennummer ist eine Zeichenkette (größer als 10 Zeichen). Mit dieser kann unsere API den Kunden beim Zahlvorgang Punkte oder Stempel aufbuchen oder auch diese beim Zahlvorgang einlösen. (siehe REST API Dokumentation).

Die Position werden dann als gesammelt markiert und sind durch einen Scan der Rechnung nicht mehr sammelbar. Der Benutzer bekommt eine Push-Notification auf sein Gerät bzw. wenn er die Oberfläche neu lädt werden ihm die gesammelten Punkte angezeigt.

Einlösen mit APP

Diese Szenario geht davon aus das der Kunde schon Punkte gesammelt hat die er einlösen kann.

  1. Schritt - (App)
    Der Kunde öffnet die Bessa App und löst die Karte ein. Das öffnet in der App eine entsprechende Oberfläche in welcher ein Einlöse-QR-Code angezeigt wird.

  2. Schritt - (Kasse)
    Die Kasse scannt dann den im Schritt 1 erwähnten QR-Code und sendet den Code an den Bessa Server.

  3. Schritt - (Server)
    Der Server prüft ob dieser Code schon verwendet wurde, falls er noch nicht verwendet wurde, wird er nun als verwendet markiert. Der Kasse wird mitgeteilt welche PLUs eingelöst werden können. Ein weiteres Ausführen führt zu einem Fehlerfall (z.B.: Code schon eingelöst.)

  4. Schritt - (Kasse)
    Diese nimmt den eingelösten Code entgegen und bucht ihn mit der entsprechenden Bewegungsart als Rechnungsposition ein.

Einlösen mit Kundenkarte

Diese Szenario geht davon aus das der Kunde schon Punkte gesammelt hat die er einlösen kann.

  1. Schritt - (Kundenkarte)
    Der Kunde zeigt an der Kasse seine Karte her.

  2. Schritt - (Kasse)
    Die Kasse scannt dann den im Schritt 1 erwähnten QR-Code oder Bar-Code und sendet den Code an den Bessa Server, dieser gibt dann für diesen Kunden verfügbare Rabatte zurück.

  3. Schritt - (Kasse)
    In dem Server Ergebnis können mehr als eine Rabattaktion drin sein, die Kasse muss dann die gewünschte Aktion auswählen. Sollte nur eine Rabattaktion vorhanden sein, kann die Kasse diese sofort auswählen ohne eine Auswahl treffen zu müssen.

  4. Schritt - (Server)
    Der Server prüft ob dieser Code schon verwendet wurde, falls er noch nicht verwendet wurde, wird er nun als verwendet markiert. Der Kasse wird mitgeteilt welche PLUs eingelöst, bzw. ob ein Rabatt eingelöst werden kann. Ein weiteres Ausführen führt zu einem Fehlerfall (z.B.: Code schon eingelöst.)

  5. Schritt - (Kasse)
    Diese nimmt den eingelösten Code entgegen und bucht ihn mit der entsprechenden Bewegungsart als Rechnungsposition ein.

REST API - Dokumentation

Für den oben erwähnten Ablauf stehen folgenden REST API Routen zur Verfügung.

Authorization

Authorization läuft über ein Token im Header, mit einer maximalen Länge von 40 chars.

Live-Api: https://api.bessa.app/

Test-Api: https://stg.bessa.app/

Health Check

Diese Route prüft ob die Kassa online ist. Sollte alle 20 sec aufgerufen werden.

Request

curl -X "POST" "https://api.bessa.app/v1/systems/health/" \ -H 'Authorization: Token <dein-token>' \ -H 'Content-Type: application/json; charset=utf-8' \ -d $'{ "cash_box": "<deine-cashbox-id>" }'

Request Body

Name

DataType

Nullable

Description

Name

DataType

Nullable

Description

cash_box

string

false

Die Id der Kasse die über ihren Zustand berichtet

Response Code

Code

Description

Code

Description

200

Success

401

Invalid Token

404

No valid cash_box

 

Kundenkarten Daten Synchronisieren

Sollte der Kassenbenutzer auch eine Bessa Whitelabel App haben, kann man die Kundenkarten Detailinformationen auch mit Bessa abgleichen, dadurch sieht der Kunde seine Kundenkarte in seiner Whitelabel App.

Folgender Request muss abgesendet werden.

Request

curl -X "POST" "https://api.bessa.app/v1/web/pos/customers/" \ -H 'Authorization: Token <dein-token>' \ -H 'Content-Type: application/json; charset=utf-8' \ -d $'{ "external_id": <kundenkarten_id>, "first_name": "Max", "last_name': "Mustermann", "company_name": "", "phone": "+43650987", "email": 'max.mustermann@bessa.app', "tax_id": "" }'

Request Body

Name

DataType

Max-Length

Nullable

Description

Name

DataType

Max-Length

Nullable

Description

external_id

string

64

false

Kundenkarten ID

first_name

string

256

false

Vorname des Kunden.

last_name

string

256

false

Nachname des Kunden, kann leer sein ""

company_name

string

256

false

Firmenname des Kunden, kann leer sein ""

phone

string

15

false

Telefonnummer des Kunden, kann leer sein ""

email

string

254

false

E-Mail des Kunden, kann leer sein ""

tax_id

string

256

false

Steuernummer des Kunden, kann leer sein ""

Response Code

Code

Description

Code

Description

201

Success

400

Invalid Data, please check the error message.

401

Invalid Token

Kundenkarten Daten laden

Der Kunde hat eine Kundekarte und mit dieser Punkte gesammelt um zu erfahren welche Aktionen dieser sich ersammelt hat muss folgender Request abgesendet werden. Die customer_card_id kann aber auch einen gescannten QR-Code enthalten und zu diesem Informationen zurückgeben.

curl -X "GET" "https://api.bessa.app/v1/​/web​/pos​/cards​/redeem​/{customer_card_id}​/" \ -H 'Authorization: Token <dein-token>' \ -H 'Accept: application/json; charset=utf-8'

Es folgen 2 Beispiele für das laden von Daten über die Redeem Info Route. Als erstes Beispiel wird das Ergebnis einer Kundenkarte angezeigt und als zweites Beispiel wird eine Artikel Rabattaktion gezeigt.

Das folgende Beispiel zeigt die einlösbaren Aktionen die ein Kunde über die Kundenkarte gesammelt hat. Er bekommt als Ergebnis 2 Aktionen zurück. Das erste Ergebnis ist eine Sammelkarte mit einlösbaren Aktionen zu sehen im children array. Das zweite Ergebnis ist ein einmal Rabatt der Neukunden gewährt wird. Der Kunde muss an der Kasse auswählen was er eingelöst haben will.

[ { "card": { "image_thumbnail": null, "hash_id": "ac_JQ", "uuid": "98eec0a5-4461-44b0-aa58-22f4cdf0a58b", "image": null, "title": "Bier König Sammelkarte", "subtitle": "Sammele Punkte und löse sie gegen unsere Aktionen ein.", "details": "", "card_type": 0, "bonus_type": 0, "bonus_value": "99999999.99", "bonus_usage": 2, "minimum_value": "0.00", "article_number": [], "children": [ { "image_thumbnail": null, "hash_id": "cr_JQ:ac_zG:rb_oV4EG", "uuid": "607b7587-68b6-4310-a7d8-9165aa109904", "image": null, "title": "5% Rabatt", "subtitle": "für 50 Punkte bekommst du 5% Rabatt", "details": "", "bonus_type": 2, "bonus_value": "5.00", "bonus_usage": 1, "minimum_value": "50.00", "article_number": null }, { "image_thumbnail": null, "hash_id": "cr_JQ:ac_8y:rb_oV4EG", "uuid": "2d86b745-6df9-4796-a0ad-fe445ba4f022", "image": null, "title": "Mega Rabatt", "subtitle": "für 150 Punkte bekommst du 17% Rabatt", "details": "", "bonus_type": 2, "bonus_value": "15.00", "bonus_usage": 1, "minimum_value": "100.00", "article_number": null } ] }, "hash_id": "cr_JQ", "uuid": "abb62e6c-77e9-4c4c-b349-ffbca62b76fb", "collected": "900.00", "redeemed": false }, { "card": { "image_thumbnail": null, "hash_id": "ac_Ly", "uuid": "fae6c054-7ab8-4b36-8769-0e759cdc97d7", "image": null, "title": "Bier König Einmalrabatt", "subtitle": "", "details": "10 Euro für deinen ersten Einkauf.", "card_type": 0, "bonus_type": 1, "bonus_value": "10.00", "bonus_usage": 2, "minimum_value": "0.00", "article_number": [ "ART001" ], "children": [] }, "hash_id": "cr_Bv", "uuid": "6fda51b7-5f63-4d13-8b31-6f8edbca9367", "collected": "10.00", "redeemed": false } ]

 

Das folgende Beispiel, gibt eine Artikel Rabatt Aktion zurück. Da nur ein Element zurückgegeben wird kann die Kasse diesen Rabatt sofort einlösen (siehe hier).

[ { "card": { "image_thumbnail": null, "hash_id": "ac_dP", "uuid": "e3fc7c38-b62c-40a8-a8e5-5043011496c7", "image": null, "title": "Bier König Sammelkarte", "subtitle": "Sammele Punkte und löse sie gegen Artikel ein.", "details": "Mit dieser Karte kannst du Punkte sammeln und gegen Artikel an unserer Kasse einschränken.", "card_type": 0, "bonus_type": 0, "bonus_value": "99999999.99", "bonus_usage": 2, "minimum_value": "0.00", "article_number": [ "12" ], "children": [] }, "hash_id": "cr_r0", "uuid": "ccbbdfa5-499c-4051-bc7c-8f8c73ecd062", "collected": "120.00", "redeemed": false } ]

Response Body (wichtige Felder)

Name

DataType

Nullable

Description

Name

DataType

Nullable

Description

hash_id

string

false

ID die eingelöst werden soll. Für einfache Rabatte.

Sollte eine card im Ergebnis sein, die das Feld children gesetzt hat, muss der Kunde aus dieser eine hash_id auswählen und einlösen.

card

card object

false

Treuepass der eingelöst werden soll, enthält alle notwendigen Detailinformationen.

Response Body Card

Name

DataType

Nullable

Description

Name

DataType

Nullable

Description

title

string

false

Titel der Karte die eingelöst werden kann. Dieser Text ist für den Kunden bestimmt.

subtitle

string

false

Sub Titel der Karte die eingelöst werden kann. Dieser Text ist für den Kunden bestimmt.

description

object

false

Detailbeschreibung der Karte. Dieser Text ist für den Kunden bestimmt.

card_type

Integer

false

Der Type der Karte, für die Kasse gibt es nur 2 Relevante Typen:

0 … Sammelpass (Artikelrabatt) → Siehe Karten Einlösen Response Body (Teil 1)

1 … Rabattkarte → Siehe Karten Einlösen Response Body (Teil 2)

2 … Gutscheinkarte → Siehe Karten Einlösen Response Body (Teil 3)

bonus_usage

Integer

false

Die Art wie der Bonus gestaltet ist.

1 => Prozent Rabatt

2 => Absoluter Rabatt

article_number

array

false

Diese Array enthält Artikel PLUs (von der Kasse) die der Kunde in der einlösen kann.

bonus_value

decimal

false

Dieses Feld enthält den Wert der eingelöst werden kann. Sollte 9999999.99 als Wert gesetzt sein, kann diese Karte nicht selbst eingelöst werden. (Die Sammelkarte selbst kann nicht eingelöst werden, wohl aber ihre Aktionen im Feld children oder eben ein Artikel.

children

array

false

Ein Array von card objects, Diese sind alle einlösbar.

Der Kunde muss eine auswählen, ist nur eine im Array kann die Auswahl entfallen.

Karte einlösen

Der Kunde löst eine Karte auf seinem Smartphone ein. Es wird ein QR-Code angezeigt welcher von der Kasse gescannt wird. Der QR-Code wird an den Server geschickt, der Server teilt der Kasse mit um welche Art von Einlösung es sich handelt.

Pro QR-Code handelt es sich um verschiedene Rabatte.

Artikel: Ist ein Artikel im QR-Code kodiert wird immer der Artikel zu 100% eingelöst wird. Es wir davon ausgegangen dass der erste übereinstimmende Artikel der auf der Rechnung auf Bessa gebucht wird. Sollte der Kunde einen anderen Artikel abgebucht haben wollen, muss dieser zuvor rausgesplittet werden.

Rabatt: Ein Standard Rabatt zB. 10% oder 10 Euro. Die Felder discount und usage werden hier verwendet.

Request

curl -X "POST" "https://api.bessa.app/v1/web/pos/cards/redeem/" \ -H 'Authorization: Token <dein-token>' \ -H 'Content-Type: application/json; charset=utf-8' \ -d $'{ "qr_code": "<redeemable-card-qr-code or card-hash-id>", }'

 

Request Body

Name

DataType

Nullable

Description

Name

DataType

Nullable

Description

qr_code

string

false

QR-Code welcher vom Personal gescannt wurde. Bei einer Direkt Integration, ist es die hash_id der einzulösende Karte.

Response Body

Der Kasse wird mitgeteilt welche PLUs, Rabatte oder Gutscheine eingelöst werden können. Hier 2 Beispiele:

{ "card_title": "Bier König Punktekarte", "article_numbers": ["<1. plu>", "<2. plu>"] }
{ "card_title": "Bier König Rabatt", "usage": 1, "discount": "10.00" }

Response Code

Code

Description

Code

Description

200

Success

400

Already used, Card not full, Card not found

401

Invalid Token

Response Structure

Name

DataType

Nullable

Description

Name

DataType

Nullable

Description

article_numbers

Array<string>

false

Optionales Feld, PLUs die eingelöst werden können max 10 * 50 char als Array<string>

card_title

String

false

Titel der eingelösten Karte.

usage

Integer

false

Optionales Feld, Die Art des Rabatts: 1 => Prozent, 2 => Dezimal (Absolutwert)

discount

Decimal

false

Optionales Feld, Wert für die Rabattberechnung hängt von vom Feld usage ab

Einlösen abbrechen

Der Kunde hat eine Karte eingelöst, der QR Code wurde bereits von der Kasse gescannt. Jetzt stellt sich heraus dieser Code wurde fälschlicherweise eingelöst. Damit kann das Einlösen rückgängig gemacht werden.

Request

curl -X "POST" "https://api.bessa.app/v1/web/pos/cards/redeem/cancel/" \ -H 'Authorization: Token <dein-token>' \ -H 'Content-Type: application/json; charset=utf-8' \ -d $'{ "qr_code": "<redeemable-card-qr-code>" }'

Request Body

Name

DataType

Nullable

Description

Name

DataType

Nullable

Description

qr_code

string

false

QR-Code welcher vom Personal gescannt wurde

Response Code

Code

Description

Code

Description

200

Success

400

Already cancelled, not redeemed yet, not found

401

Invalid Token

Upload Phantom Bestellung/Rechnung

Immer wenn eine Rechnung erstellt wird muss die Kasse die Rechnungen inkl. der Positionen auf der Rechnung nach folgendem Schema an den Server schicken.

## Request curl -X "POST" "https://api.bessa.app/v1/web/pos/invoice/" \ -H 'Authorization: Token <dein-token>' \ -H 'Content-Type: text/plain; charset=utf-8' \ -d $'{ "cash_box": "<deine-cashbox-id>" "qr_code": "_R1-AT1_DEMO-KASSEN-ID_162_2019...+zA==", "user": "<user id oder customer_card_id>", "table": "12-12", "invoice_number": "140", "invoice_waiter": "101", "invoice_timestamp": 1568619900, "payment_type": "Bar", "positions": [ { "receipt_number": "181", "article_number": "260", "article_name": "Vini Bianco 0,1", "article_group": 2, "amount": 100, "timestamp": 1568619900, "vat": 2000, "subtotal": 208, "total": 250, "price": 250, "waiter": "101", "position_type": "BON", "food_type": "Getränk", "sequence_number": 12, }, ... ... ]}'

Request Body

Name

DataType

Max-Length

Nullable

Description

Name

DataType

Max-Length

Nullable

Description

cash_box

string

128

false

Deine Kassen id, es kann mehrere in einer Filiale geben

work_station

sting

64

false

Sollte es mehrere Kassen im Verbund geben wird hier die ID der spezifischen Workstation übertragen

qr_code

string

4296

false

QR-Code der Rechnung

user

string

128

true

Die ID des Kunden zu dem die Rechnung gehört. Null wenn die ID nicht gescannt wurde vom Personal während der Bestellung. Es kann auch Kundenkarte gescannt werden und in diesem Feld übertragen werden. Kundenkarten müssen in folgendem Format übertragen werden ext_<kundenkarten_id>.

table

string

64

true

Der Tisch zu dem diese Rechnung gehört

invoice_number

string

128

false

Die Rechnungsnummer

invoice_waiter

string

64

false

Der Kellner der die Rechnung erstellt hat

invoice_timestamp

long

-

false

Unix-Timestamp, in Sekunden seit 1970, Beispiel: 1545730073. Der Zeitpunkt and dem die Rechnung erstellt wurde.

payment_type

string

16

true

Bar, Visa, Treuepass, usw. wenn Null oder nicht im Body wird Bar verwendet.

discounted

boolean

-

false

Gibt es für diese Rechnungen einen Discount, kann dieses Flag gesetzt werden. Das verhindert das Der Kunde diese Rechnung nochmal zum Punkte/Stempel sammeln verwenden kannst.