Technischer Beitrag
Kontaktlose Transaktionen – ganz einfach
Jeder weiß, wie lästig Chipkarten sein können. Karte rein, mit dem Fuß wippen, insgeheim hoffen, dass der Chip versagt, damit man einfach durchziehen kann … Okay, das ist vielleicht etwas übertrieben. Aber Sie wissen, was gemeint ist. Standard-„Contact-EMV" frustriert Kunden (und hat so manchen Payment-App-Entwickler an den Rand der Verzweiflung gebracht), weil es langsam, komplex und fehleranfällig ist.
Mit kontaktlosem EMV ändert sich das grundlegend. Eine „Tap-and-Go"-Transaktion dauert in der Regel weniger als 500 Millisekunden und lässt sich bequem mit dem Smartphone durchführen – weit praktischer als das Heraussuchen einer Plastikkarte. Und das Beste: Auch für Entwickler ist es einfacher. Eine kontaktlose Transaktion lässt sich mit wenigen Codezeilen umsetzen – sogar komplett in JavaScript, ganz ohne Visual Studio oder Xcode. Kein Kompilierungszyklus, keine einzubindenden Bibliotheken, keine lästigen Abhängigkeiten. Schnellere Entwicklung war selten so einfach!
Betrachten Sie die folgenden 4 JavaScript-Zeilen:
Kaum zu glauben, aber diese 4 Zeilen genügen, um eine kontaktlose EMV-Transaktion mit einem der kompakten und kostengünstigen VP3300-Kartenlesegeräte von ID TECH durchzuführen (z. B. dem oben abgebildeten VP3300). Sobald diese 4 Zeilen ausgeführt wurden, halten Sie Ihr Smartphone (oder eine kontaktlose Karte) an das Lesegerät – es gibt einen Signalton aus, startet eine NFC-Kommunikation und überträgt anschließend die Transaktionsdaten (per USB).
Damit diese Codezeilen tatsächlich funktionieren, müssen Sie zunächst das Node-Skript installieren, das mit dem USB-Gerät kommuniziert (sowie Node JS selbst) – wie in meinem letzten Beitrag beschrieben. (Das ausführbare Skript zusammen mit Node selbst steht als einzelnes Archiv zum Download bereit hier.) Die oben genannten Codezeilen führen Sie am besten in Firefox oder Chrome aus, mithilfe der App hier verfügbar.
Was ist ViVOpay Explorer? Es handelt sich schlicht um eine einfache HTML-Seite mit einer JS-Konsole und einigen vorgeladenen Befehlen. Die Seite umfasst 50 Zeilen HTML und 400 Zeilen JavaScript – einschließlich der TLV-Parser-Routine, die ich in einem früheren Beitragerläutert habe. Wenn Sie ViVOpay Explorer in Chrome oder Firefox verwenden (bitte nicht im Internet Explorer), sehen Sie eine Browser-Seite, die in etwa so aussieht:
Der graue Bereich unter „Console" ist ein Live- REPL (in diesem Fall ein jQuery-Terminal), in dem Sie beliebigen JavaScript-Code in Echtzeit ausführen können. Oben rechts finden Sie Textfelder (mit „http://localhost" und „9901") neben einem Connect -Button. Ein Klick auf diesen Button veranlasst den ViVOpay Explorer, auf 127.0.0.1, Port 9901 nach einer Websocket-Verbindung zu suchen. Die untere Hälfte der Seite ist ein Protokollbereich, in dem verschiedene Statusinformationen (z. B. USB-Datenverkehrsauswertungen) in Echtzeit als Reaktion auf Befehle angezeigt werden.
Ein Klick auf das kleine Fragezeichen neben dem Dropdown-Menü öffnet ein kleines Hilfefenster, das erklärt, wie Sie den ViVOpay Explorer verwenden. Kurz zusammengefasst müssen Sie Folgendes tun:
1. Laden Sie den Node driver (11 MB großes ZIP-Archiv) herunter und entpacken Sie es auf Ihrem lokalen Windows-Rechner. (Es enthält eine Kopie von node.exe sowie Skripte und unterstützende Dateien – alles Erforderliche ist im Archiv enthalten. Versuchen Sie jedoch nicht, es unter Mac oder Linux auszuführen. Es handelt sich um einen Windows-spezifischen Build von Node.)
2. Suchen Sie im entpackten ZIP-Ordner nach start.bat und führen Sie es aus. (Lassen Sie es geöffnet. Schließen Sie das Fenster nicht.) Dadurch wird der Node-basierte Treiber gestartet, der mit USB kommuniziert, und gleichzeitig ein Websockets-Server initialisiert.
3. Schließen Sie einen VP3300-Serien-Kartenleser (UniPay III, BTPay Mini usw.) von ID TECH an Ihren USB-Anschluss an. Der Node-Treiber erkennt das Gerät automatisch und stellt eine Verbindung her.
4. Klicken Sie auf die Schaltfläche „Verbinden" (oben rechts). Unterhalb sollte die Meldung erscheinen: „Connected to the driver on port 9901." Dies bedeutet, dass Ihr Browser nun über Websockets auf Port 9901 mit dem Treiber kommuniziert. http://localhost:9901.
5. Wählen Sie den Befehl Ping reader aus dem Dropdown-Menü aus. Dadurch wird ein Skript ausgeführt, das das angeschlossene USB-Gerät anpingt.
Wenn Schritt 5 erfolgreich war, sollte auf dem Hauptbildschirm unterhalb der Konsole eine protokollierte Antwort angezeigt werden, die in etwa so aussieht:
OUT:
{
"source":"client"
"data":"5669564f74656368320018010000b3cd"
"type":"raw command"
}
IN:
{
"source":"usb"
"data":"5669564f74656368320018000000fa83″
"type":"data"
}
Dies sind die JSON-Nachrichten, die während des Pings über Websockets gesendet (an das USB-Gerät) und empfangen (vom Browser) wurden. Die maßgeschneiderten JSON-Objekte folgen einem einfachen Schema: Es gibt drei Felder – source, data und type. Bei ausgehenden Nachrichten (vom Browser zum Treiber) sollte die Eigenschaft source den Wert „client" haben; das Feld data enthält einen Hex-String, der den an das USB-Gerät gesendeten Befehl darstellt; und das Feld type enthält „raw command", um den Treiber darauf hinzuweisen, dass der Datenbefehl direkt an das USB-Gerät weitergeleitet werden soll.
Ein JSON-Objekt (oder eine beliebige andere Nachricht) vom Browser an den Treiber zu senden ist einfach. Verwenden Sie in Ihrem Browser-Code einfach socket.emit( 'echo', myObject ). Um Daten vom Treiber zu empfangen, richten Sie einfach einen Listener ein: socket.on( 'message', myListener ), wobei myListener eine anonyme Funktion sein kann, wie z. B. function( m ) { log( m ); }. Selbstverständlich sollten Sie den Listener einrichten, bevor Sie etwas an den Treiber senden. Andernfalls könnte der Treiber antworten, bevor Sie bereit sind, die Antwort entgegenzunehmen.
So starten Sie eine kontaktlose Transaktion: Strategie 1
Um den Leser in den NFC-Modus zu versetzen und eine kontaktlose Karte oder ein Wallet auszulesen, können Sie einfach den entsprechenden Firmware-Befehl (als Hex-String) übergeben:
Die erste Zeile definiert den Befehl als Zeichenkette. Informationen zur Konstruktion solcher Befehle entnehmen Sie bitte der technischen Dokumentation Ihres Lesegeräts. (Die ID TECH Dokumentation können Sie über die Download-Seite der öffentlichen ID TECH Wissensdatenbankherunterladen.) Dieser konkrete Befehl enthält einen Standardbetrag von 1,00 $ sowie ein inzwischen veraltetes Datum – der gezeigte Code ist daher (obwohl er funktioniert!) als Proof-of-Concept zu verstehen und nicht für den Produktiveinsatz geeignet. In einem produktiven Szenario würden Sie den Befehl mit dem tatsächlichen Betrag, dem aktuellen Transaktionsdatum usw. befüllen.
Die Übermittlung des Befehls an den Leser erfolgt in zwei Schritten: Zunächst senden Sie ihn über Websockets in einem JSON-Objekt an den Treiber; dieser leitet ihn dann an den USB-Leser weiter. Das Verpacken des Befehls in ein vom Treiber verarbeitbares JSON-Objekt ist denkbar einfach – siehe die zweite und dritte Zeile des obigen Codes. Die vierte Zeile sendet das Datenobjekt über den Socket.
Denken Sie auch hier daran: Bevor Sie dies ausführen, sollten Sie einen Listener (oder Callback) am Socket registrieren, damit Sie die Antwort des Lesers verarbeiten können. Das kann so einfach sein wie:
So starten Sie eine kontaktlose Transaktion: Strategie 2
Es gibt eine zweite Strategie, um die Transaktion anzustoßen. Wie bereits erwähnt, ist der Transaktionsstart ein zweistufiger Prozess:
1. Eine Nachricht vom Browser an den Treiber senden.
2. Nachricht vom Treiber an das USB-Gerät übermitteln.
Die „Nachricht" ist ein langer, komplexer Firmware-Hex-String.
Der „Treiber" ist in diesem Fall ein Node-Skript (etwa 350 Zeilen JavaScript), das im Node-Prozessbereich ausgeführt wird. Den Quellcode des Treibers finden Sie im Treiber-Ordner. Suchen Sie nach usb-websocket-shim.js.
Sie können den Treibercode problemlos so anpassen, dass er den Firmware-Befehl, der eine Transaktion auslöst, bereits als String enthält (oder als Funktion, die diesen String erzeugt). Dadurch lässt sich der Firmware-Befehl hinter einer selbst definierten API verbergen, sodass Ihre Zahlungsanwendung (hier repräsentiert durch ViVOpay Explorer) nur eine einfache Nachricht Ihrer Wahl an den Treiber senden muss, um die Transaktion zu starten.
Was bringt das? Welchen Vorteil hat es, den Firmware-Befehl im Treiber selbst zu verbergen?
Dafür gibt es meiner Meinung nach einige gute Gründe.
Erstens ist es sinnvoll, gerätespezifische Abhängigkeiten aus der Zahlungsanwendung zu entfernen und in den Gerätetreiber zu verlagern, der logisch viel näher am Gerät liegt. Überlegen Sie: Soll Ihre Zahlungsanwendung wirklich detaillierte Kenntnisse über Firmware-Befehle haben? Wäre es nicht besser, die Anwendung von Hardware-Details zu befreien? Sollte die Anwendung sich nicht auf die Geschäftslogik konzentrieren?
Zweitens ermöglicht es Ihnen, den Firmware-Befehl in den Treiber zu verlagern, eine eigene API dafür zu definieren. So können Sie eine vereinfachte API bereitstellen, die die Zahlungsanwendung direkt nutzen kann. (Siehe Beispiel unten.)
Darüber hinaus ist der Aspekt der Scope-Reduzierung zu berücksichtigen. In der Praxis sind die meisten Zahlungsanwendungen und Point-of-Sale-Systeme so konzipiert, dass die Kassen- oder Zahlungsanwendung dem Transaktionssystem kaum mehr als den Transaktionsbetrag übermittelt. Das Transaktionssystem, das mit dem Kartenlesegerät kommuniziert, liefert daraufhin einen Autorisierungscode und druckbare Beleginformationen zurück. Sensible Kartendaten gelangen dabei nie in die Zahlungsanwendung.
Im Szenario der „Scope-Reduzierung" wäre es also wünschenswert, im Treiber Code zu implementieren, der auf eingehende WebSockets-Nachrichten wie folgt reagiert:
Dies ist tatsächlich bereits in unserem Node-Treiber implementiert. (Siehe mein vorheriger Beitrag für eine Auflistung des Treibercodes.) Das bedeutet, dass wir lediglich Folgendes tun müssen, um eine kontaktlose Transaktion aus der Zahlungs-App (oder dem ViVOpay Explorer) heraus zu starten:
Im ViVOpay Explorer habe ich den gesamten erforderlichen Code (einschließlich des Codes für einen Callback, der die TLV-Daten der Transaktion analysiert und auf dem Bildschirm anzeigt) in einer Funktion namens startContactlessTransaction().
Zur Erinnerung: Weitere Informationen darüber, wie der Node-basierte Treiber die USB-Konnektivität ermöglicht, finden Sie in meinen früheren Beiträgen (Links weiter unten). Konsultieren Sie außerdem die kostenlose Downloads-Seite von ID TECH für weitere Produktdokumentation, Whitepaper, SDK-Dokumentation usw.
Um ein Evaluierungskit mit einem der Kartenlesegeräte von ID TECH zu erhalten, rufen Sie uns jederzeit unter der unten angegebenen Nummer an:
