Zum Inhalt springen
meniodevelopermenio DashboardVorschau

POS API · Legacy

API-REFERENZ

POS API · Legacy

Abgelöste POS-Dokumentation.

Archiv4 Endpunkte
Blueprint
Laut Confluence obsolet und ohne Verwendung.
BASE URLhttp://pos.dev.qnips.com/api
Grundlagen & vollständige Einführung

Mobile Payment

In der menio App sind mehrere Zahlungsdienste eingebunden, über welche eine bargeldlose Bezahlung über das Smartphone möglich ist. Dabei ist menio selbst kein Zahlungsdienstleister, sondern nur ein Mediator mit einer einheitlichen Schnittstelle zum Abwickeln einer mobilen Zahlung.

Um eine mobile Zahlung anzustoßen, muss die Kasse einen Payment Identifier (PID) generieren und einen Zahlungswunsch inkl. Währung + Betrag unter Nutzung dieser PID beim menio System einreichen. Weiterhin ist der PID als Trigger für den Start des Bezahlprozesses in der menio App (z.B. als QrCode, NFC- oder BLE-Signal) auszugeben. Sobald die App den PID erkennt, wird der Bezahlprozess gestartet. Jede Zustandsänderung des Zahlungswunsches wird an die Kasse zurückgegeben.

Zur Zeit eingebundene Zahlungsdienstleister sind:

Anbieter Zahlart Rückerstattung
kesh Prepaid nein
PayPal Postpaid nein

weitere werden folgen. blabla

Begrifflichkeiten

Zahlungswunsch (Payment)

Um eine mobile Zahlung über das Smartphone zu initiieren, muss die Kasse einen Zahlungswunsch über die menio-API in unserem System unter Nutzung eines eindeutigen Payment Identifiers (PID) einreichen. Sobald die menio-App den PID erkennt (z.B. über einen QrCode-Scan oder über ein BLE-Signal), startet sie die Bezahlfunktion auf dem Smartphone.

Ein Zahlungswunsch besteht aus folgenden Angaben:

Name Typ Bedeutung
qtid string Der Identifier der Transaktion auf welche sich dieser Zahlungswunsch bezieht
currency string Währungskennung laut ISO 4217-Spezifikation (z.B. "EUR")
total_value decimal Gesamtbetrag, der vom menio-Nutzer einzuziehen ist inkl. eventueller Trinkgelder und aller Steuer
included_vat decimal Mehrwertsteuer-Anteil im Gesamtbetrag
included_tip decimal, optional Eventuell in der Kasse eingegebenes Trinkgeldanteil im Gesamtbetrag
allowed_payment_providers string, optional Die menio App listet in der Bezahlansicht standardmäßig alle in der aktuellen Filiale eingerichteten Zahlungswege auf. Möchte die Kasse bei bestimmten Nutzern bestimmte Zahlungswege sperren, so isthier eine kommaseparierte Liste der IDs der Zahlungsproviders anzugeben, die für diesen einen Zahlungswunsch erlaubt sein sollen

Payment Identifier (PID)

Darunter ist eine von der Kassensoftware erzeugte ID gemeint, unter welcher der Zahlungswunsch im menio-Backend eingereicht und getrackt wird. Der PID kann nach beliebigem Algorithmus erzeugt werden und muss lediglich folgenden Anforderungen entsprechen:

  • kann nur aus Nummern und lateinischen Groß- und Kleinbuchstaben bestehen (keine Umlaute, keine Sonderzeichen)

  • darf minimal 5 und maximal 20 Zeichen lang sein

  • muss über die gesamte Einsatzzeit einer Kasse unter demselben QnipsPOSIdentifier eindeutig sein.

menio Transaction Identifier (QTID)

Was der PID für den Zahlungswunsch ist, ist der QTID für die Transaktion (siehe dazu Kapitel 'referenz setzen'). Damit menio im Webportal den Zahlungsvorgang mit einer Transaktion verlinkt anzeigen kann, muss ein Zahlungswunsch mit dem Transaktionsdatensatz über das Setzen des QTID-Feldes auf dem Zahlungswunsch verbunden werden.

Zustände des Zahlungswunsches (Payment.State)

Name Bedeutung
Submitted Zahlungswunsch ist im menio-System erfasst und wartet darauf, auf dem Smartphone gestartet zu werden. Ausschließlich Bezahlvorgänge in diesem Zustand können noch vom Submitter zurückgezogen werden
InProcess Sobald der User in der menio-App den Zahlungsdienstleister ausgewählt hat, sich ihm gegenüber authentifiziert hat und die App bereit ist, den Zahlungswunsch an den Zahlungsdienstleister zu übergeben, wird der Zahlungswunsch auf den Zustand 'InPayment' gesetzt und kann von der Kasse nicht mehr abgebrochen werden
CancelledByUser Wird gesetzt, wenn der Zahlungswunsch vom Nutzer in der menio-App vollständig abgebrochen wurde. Die menio-App kann diesen Zahlungswunsch allerdings wiederaufnehmen (z.B. durch erneuten Scan des QrCodes mit dem selben PID), solange der Zahlungswunsch nicht vom Submitter beendet wird oder in den Zustand Expired wechselt.
CancelledBySubmitter Wird gesetzt, wenn der Erzeuger (Submitter) des Zahlungswunsches diesen über einen DELETE-Call auf die payments-Resource explizit abbricht. Das geht nur solange der Zahlungswunsch im Zustand Submitted ist. Zahlungswünsch mit diesem Zustand können keine Bezahlfunktion in der menio-App mehr auslösen.
Succeeded Wird gesetzt, sobald der gewählte Zahlungsdienstleister uns einen erfolgreichen Geldtransfer meldet
Refunded Wird gesetzt, wenn der Erzeuger (Submitter) des Zahlungswunsches über einen expliziten POST-Call auf die Refund-Resource eine Rückerstattung beantragt und diese uns vom Zahlungsdienstleister als erfolgt gemeldet wird
Expired Jeder in unserem System erzeugte Zahlungswunsch, der nach Ablauf von 30 Minuten immer noch den Zustand Submitted hat, wird automatisch auf den Zustand Expired gesetzt und gilt ab da für die menio-App als nicht existent. Eine Wiederaufnahme des zuvor vom User abgebrochenen Zahlungswunsches verlängert diesen Timeout nicht

PaymentProviderTransactionId

menio selbst ist kein Zahlungsdienstleister, sondern eine Wallet, die unterschiedliche Zahlungsdienstleister (wie PayPal, kesh, etc.) in einer App vereint. Die eigentliche Zahlung wird also von nachgeschalteten Providern abgewickelt. Daher bekommt jeder Zahlungswunsch nach einem erfolgreichen Geldtransfer durch den vom menio-App-Nutzer gewählten Provider, eine Provider-spezifische TransaktionsID, welche wir zur besseren Nachvollziehbarkeit an den Erzeuger des Zahlungswunsches (i.d.R. die Kassensoftware) als PaymentProviderTransactionId weiterreichen.

Discounts

Eine über die menio-API initiierte Zahlung kann optional automatisch um das für die verknüpfte Transaktion evtl. errechnete menio-Cashback reduziert werden. Ist die Funktion vom Kunden gewünscht, wird menio den Zahlbetrag eines mobilen Zahlungswunsches ggf. automatisch um das für die mit dem Zahlungswunsch verknüpfte Transaktion errechnete Cashback reduzieren und den reduzierten Zahlbetrag über den Payment Provider abwickeln. Als Nachweis gegenüber dem Finanzamt für die Korrektheit des Preisnachlasses wird in dem Feld Discount die Information über das angefallene Cashback abgespeichert und auf Anfrage an die Kassensoftware ausgeliefert. Die Kasse ist dann in der Pflicht, diesen Datensatz gemäß eigener Richtlinien für angewandte Preisnachlässe als Bestandteil der Transaktion abzuspeichern.

Erzeugung des Zahlungswunsches

  1. Generieren Sie einen PaymentIdentifier (PID) , der den oben beschriebenen Kriterien entspricht und reichen Sie den Zahlungswunsch unter Nutzung dieser PID mit mindestens dem QTID, dem Betrag, der Währung und der PaymentTerminalId mit einem POST-Call auf die payments-Resource bei uns ein.

  2. Beachten Sie bitte, dass zu diesem Zeitpunkt der Transaktionsdatensatz, auf den sich der aktuelle Zahlungswunsch bezieht, schon bei uns im System hinterlegt sein sollte

  3. Damit ein QR-Code als Trigger für die Bezahlfunktion dienen kann, muss der PID eines Zahlungswunsches in den QR-Code gepackt werden. Erzeugen Sie dazu einen QrCode mit folgendem Inhalt: http:// app.qnips.com/tt/{TransactionSubmitterId}/{QTID}{PZ1}/{PID}{PZ2}, wobei:

    Name Bedeutung
    TransactionSubmitterId der Identifier, den die Kasse bei der Aktivierung am menio-Backend zugewiesen bekommen hat
    QTID menio Transaction Identifier mit dem der Transaktionsdatensatz eingereicht wurde
    PZ1 Prüfsumme für QTID, deren Berechnungslogik in Prüfzifferberechnung beschrieben ist
    PID Payment Identifer
    PZ2 Prüfsumme für PID, deren Berechnungslogik in Prüfzifferberechnung beschrieben ist

Abbruch des Zahlungswunsches

  1. Ein Zahlungswunsch kann durch die Kasse solange zurückgenommen werden, bis die menio App eine nicht mehr terminierbare Zahlungsanfrage an den vom Nutzer in der App ausgewählten Payment Provider übermittelt wurde. Um einen Zahlungswunsch durch die Kasse zurückzunehmen, führen Sie einen DELETE-Call auf die payments-Resource aus.

  2. Werten Sie hiernach unbedingt den Response aus, denn dieser enthält die Information, ob dem Abbruchwunsch entsprochen werden konnte, oder nicht, weil z.B. eine Zahlung gerade im Gange oder bereits erfolgt ist.

Zustandsabfrage zum Zahlungswunsch

Nach der Übermittlung des Zahlungswunsches muss die Kasse für jeden Zahlungswunsch eine Zustandsüberwachung implementieren, bis eines der folgenden Zustände erreicht worden ist:

  • Confirmed - Geldtransfer hat stattgefunden

  • Expired - Zahlungswunsch ist abgelaufen und wird von der menio App nie mehr verarbeitet werden

  • CancelledByUser oder CancelledBySubmitter - Zahlungswunsch wurde abgebrochen.

Liefert ein Payment Provider für eine Bezahlanweisung eine Mißerfolgsmeldung (z.B. "Konto nicht gedeckt" o.ä.), reicht menio solche Zwischenzustände bewusst nicht an die Kasse weiter. Statt dessen wird dem Nutzer in der menio App die Möglichkeit gegeben, die Bezahlung erneut, ggf. über einen anderen Zahlungsdienst zu veranlassen bis die Zahlung entweder erfolgreich durchläuft oder der Nutzer den Bezahlprozess aktiv abbricht.

Für die Zustandsüberwachung existieren grundsätzlich zwei Möglichkeiten:

  1. Eine Pull-Abfrage für einen bestimmten PID oder für eine Liste von PIDs (siehe dazu den GET-Call auf die paymentstates-Resource)

  2. Eine direkte Push-Notification über einen WebSocket. Siehe dazu Kapitel menio-Websocket. In diesem Fall wird menio bei jedem Zustandswechsel eines PIDs eine direkte Benachrichtigung an die entsprechenden Subscriber versenden, die in der Kasse nach Möglichkeit asynchron verarbeitet werden sollen.

Generell empfehlen wir für den Empfang zwei Wege zu implementieren:

  • Eine permanente Verbindung mit dem Websocket aufbauen, um asynchron auf Zahlungsbestätigungen zu warten und beim ankommen der Bestätigung eine visuell sichtbare Meldung über den Zahlungserfolg an den Kellner zu erzeugen.
  • Zusätzlich in der Kassensoftware einen Button oder Menüeintrag einbauen, mit dem über einen GET-Call aktiv der Zustand einer Zahlungsanforderung im menio System abgefragt werden kann.

Beiden Wegen ist es jedoch gemein, dass die Zustände der Zahlungswünsche in einem einheitlichen Format geliefert werden, nämlich folgendem:

Name Typ Bedeutung
payment_terminal_id string Sind in einer Filiale mehrere Plätze installiert, die mit dem selben QnipsPOSIdentifier arbeiten und über die eine Zahlung veranlasst werden kann (z.B. in einem Client-Server-Verbund), so muss für einen Zahlungswunsch ein Identifier des genauen Platzes angegeben werden, der den Zahlungswunsch angelegt hat. Dadurch kann sichergestellt werden, dass jede Zustandsmeldung zum Zahlungswunsch genau dem Platz zugeordnet werden kann, an dem der Zahlungswunsch erzeugt wurde
currency string Währungskennung laut ISO 4217-Spezifikation (z.B. "EUR")
total_value decimal Gesamtbetrag, der vom menio-Nutzer einzuziehen ist bzw. eingezogen wurde inkl. eventueller Trinkgelder und aller Steuer. ACHTUNG: Der Betrag kann nach erfolgter Zahlung größer ausfallen, als der von der Kasse eingereichte Wert, da hier u.U. ein vom menio App Nutzer bestimmtes Trinkgeld hinzukommen kann
included_vat decimal Mehrwertsteuer-Anteil im Gesamtbetrag
included_tip decimal, optional Eventuell in der Kasse eingegebenes Trinkgeldanteil im Gesamtbetrag. Ist das Trinkgeld nicht durch die Kasse angegeben, kann der menio Nutzer u.U. eigenes Trinkgeld in der menio App hinzunehmen. Daher kann der Wert hier nach erfolgter Zahlung ggf. von dem Wert abweichen, der in diesem Feld bei der Erstellung eines Zahlungswunsches angegeben wurde.
qtid string Der Identifier der Transaktion auf welche sich dieser Zahlungswunsch bezieht
state string Einer der unter Zustände des Zahlungswunsches beschriebenen Zustände
is_refundable boolean Nur gesetzt wenn state = Succeeded oder Refunded. Gibt an, ob der Betrag nach erfolgter Zahlung über den verwendeten Zahlungsdienstleisters elektronisch zurückerstattbar ist. Dies ist nicht bei allen Zahlungsdienstleistern der Fall
pp_id number Nur gesetzt wenn state = Succeeded oder Refunded. Feste, von menio vergebene Id eines Zahlungsdienstleisters (oder kurz pp für payment provider). Mögliche Werte sind: 1=PayPal, 2=kesh.
pp_transaction_id string Nur gesetzt wenn state = Succeeded oder Refunded. Das ist die ID, unter welcher der Zahlungsvorgang im System des gewählten Zahlungsdienstleisters geführt wird.
discount object Nur gesetzt wenn state = Succeeded oder Refunded. Ist vom Kunden eine direkte Verrechnung eventueller Cashbacks mit dem Zahlbetrag gewünscht, wird hier der Discount-Betrag und der Mehrwertsteueranteil darin ausgewiesen sofern die mit diesem Zahlungswunsch verknüpfte Transaktion Cashbacks erzeugt hat.

Rücküberweisung

Bei einer Rücküberweisung wird das Geld, das im Kontext einer mobilen Zahlung über das menio System auf das Empfängerkonto transferiert wurde, wieder vom Empfängerkonto abgebucht und auf das Konto des ursprünglichen Zahlers überwiesen. Damit reduziert der Zahlungsdienstleister für sich die Betrungsmöglichkeiten und kann i.d.R. somit günstigere Transaktionspreise anbieten.

Leider wird diese Möglichkeit nicht von jedem Zahlungsdienstleister unterstützt. Daher wird menio bei der Meldung einer erfolgreichen Zahlung an die Kasse immer auch die Angabe im Feld "IsRefundable" liefern, ob für diese Zahlung eine elektronische Rücküberweisung möglich ist. Speichern Sie daher bitte bei jeder ankommenden Zahlungsbestätigung diese Information und bieten Sie die Rückerstattung auf dem User Interface nur für solche Zahlungen an, bei welchen IsRefundable = true ist.

Um eine Rücküberweisung zu veranlassen, führen Sie bitte einen POST-Call auf die refunds-resource aus.

menio-Websocket

Die von uns empfohlene Variante zum Empfang der Zahlungsbestätigungen ist über einen Websocket.

„Das WebSocket-Protokoll ist ein auf TCP basierendes Netzwerk¬protokoll, das entworfen wurde, um eine bidirektionale Verbindung zwischen einer (Web-) Anwendung und einem WebSocket-Server bzw. einem Web-Server, der auch WebSockets unterstützt, herzustellen.“ - Zitat Wikipedia (http://de.wikipedia.org/wiki/WebSocket).

Ein weiterer Vorteil eines Websockets ist, dass es, obwohl das Protokoll noch sehr jung ist, eine vielzahl der Client-Libs für unterschiedlichste Programmierplattformen und Programmiersprachen gibt. Hier eine kleine Übersicht:

Unser Websocket funktioniert nach dem Publish/Subscribe-Prinzip. D.h. es bietet mehrere Kanäle an, auf denen Informationen zum Client gepusht werden sollen. Hier ist ausschließlich der Kanal „payment“ interessant. Das Websocket liegt auf „wss://pos.dev.qnips.com/qnipsws“. Nachfolgend ein einfaches Beispiel in Javascript, welches eine Subscription auf dem Payment-Kanal eingeht und auf Zahlungsbestätigungen reagiert.

qnipsWebsocket = function () {
    var ws = new WebSocket('wss://pos.dev.qnips.com/qnipsws');
    ws.onopen = function () {
        var qpIdent = "abc";
        wsPayments.send('{"subscribe":"payment", "qnipsposidentifier":"' + qpIdent + '"}');
    };

    // success
    ws.onmessage = function (evt) {
        console.log(evt.data);
    };

    // error
    ws.onerror = function (evt) {
        console.log(evt.message);
    };

    // close
    ws.onclose = function () {
        console.log('disconnected');
        // try to reconnect each 30 seconds, until connection is established 
    };
};

Der Parameter ‚evt‘ der ‚onmessage‘-Funktion ist dann wie folgt aufgebaut:

{
   „channel“:“payment“,
   „data“:{
        "payment_terminal_id":"1",
        "currency": "EUR",
        "total_value": 19.95,
        "included_tip": 1.99,
        "included_vat": 3.81,
        "qtid":"af63457485af8745655cd",
        "state":"1,2,3",
        "is_refundable":"1,2,3",
        "pp_id":1,
        "pp_transaction_id":"1f7685qwef765",
        "discount":{
            "total_discount_value": 1.19,
            "included_vat": 0.19,
        }
    }
}

Prüfsummenberechnung

Da bei Calls der menio-WebAPI-Resourcen die Parameter im Klartext übertragen werden, können auch bei hinreichender SSL-Verschlüsselung die Man-in-the-Middle-Angriffe nicht vollständig ausgeschlossen werden. Daher wird menio die Übertragung von sicherheitsrelevanten Parametern über eine Prüfsumme schützen, die unter Nutzung eines je Kassenplatz individuellen Geheimschlüssels auf der Kasse berechnet und im menio-Backend validiert wird.

Alle API-Calls mit mind. einer falsch angegebenen Prüfsumme werden abgewiesen.

Nun das Verfahren für die Bildung der Prüfsumme:

  • einen String mit Identifier + „qPnsS14 + CSSecret bilden, mit:

    Name Wert
    Identifier der Wert, für den die Prüfsumme berechnet werden soll, z.B. ein QnipsTransactionIdentifier (QTID) oder ein PaymentIdentifier (PID)
    „qPnsS14" ein konstanter String
    CSSecret der geheime Schlüssel, der je Kasse unterschiedlich ist

    Beispiel: Identifier=“123456“ und CSSecret=“af87b1“ ergeben „123456qPnsS14af87b1“

  1. Für das Ergebnis aus vorherigem Schritt einen MD5-Hash bilden.

Für den Wert aus dem oben gezeigten Beispiel („123456qPnsS14af87b1“), würde der MD5-Hash folgender sein: 1283ff82ae8e9ace636449a519d99fa9. Die ersten 6 Zeichen dieses Hash-Wertes bilden die Prüfsumme.

Für den bisherigen Beispiel wäre die Prüfsumme aslo 1283ff