Home > Bezahlgeräte > Unterstützte Bezahlgeräte > Dialogfenster zur Bezahlsimulation (zum Testen) > Tutorial zum ScriptDevice

Tutorial zum Scriptmodus

Bitte verwenden Sie zum besseren Verständnis dieses Tutorials auch die Dokumentation für das SiteKiosk Object Model.

Schritt 1: Grundsätzliches und Datenbankstruktur
Schritt 2: Serverseitige Scripte und Entwicklung des notwendigen PHP Scripts
Schritt 3: Erstellung der notwendigen Benutzer-Dialoge und Überblick über das ScriptDevice
Schritt 4: Erstellung der notwendigen Javascripte (SiteKiosk Object Model)
Schritt 5: Umsetzungsmöglichkeiten und Erweiterungen


1. Schritt 1: Grundsätzliches und Datenbankstruktur
1.1 Ziel dieses Tutorials / Voraussetzungen
Das Ziel dieses Tutorials ist es, in möglichst einfachen Schritten zur Erstellung eines eigenen Server-Konto-basierenden Payment Module Bezahlgerätes zu gelangen.
Wir werden dabei auf die freien Werkzeuge MySQL, phpMyAdmin und einen Webserver mit PHP Unterstützung (PHP Version >= 4.1.0) zurückgreifen. Wir gehen in diesem Beispiel davon aus, dass die Server konfiguriert und lauffähig sind. Des Weiteren wird die SiteKiosk Version 5.0.32 (oder höher) benötigt (gibt es hier zum kostenlosen Download).

Wir setzten in diesem Tutorial Grundwissen in PHP und SQL, sowie fundierte Kenntnisse in HTML und JavaScript voraus (außerdem kann es nicht schaden, vorher schon einmal mit dem SiteKiosk Object Model experimentiert zu haben).

Wir wenden uns zunächst der Aufgabe und der Struktur dieses Gerätes zu.
1.2 Zieldefinition (Was wollen wir?)
Wir wollen ein Bezahlgerät erschaffen, welches den Benutzer dazu auffordert, seinen Namen nebst Passwort in einem Dialog einzugeben.
Der Dialog wird daraufhin einen Server kontaktieren und den aktuellen Kontostand sowie einige benutzerspezifische Daten, so wie z.B. der komplette Name und eine eigene Startseite für den Benutzer, SiteKiosk übermitteln.
Der Dialog kontaktiert den Server mit dem neuen HTTP-Post Objekt aus dem SiteKiosk Object Model.
1.3 Anlegen der Datenbank-Struktur
Fangen wir mit der Datenbank, die hinter unserem Bezahlgerät steht, an.
Wir werden versuchen, die Tabellen so einfach wie möglich zu halten.
Zuerst legen wir eine Datenbank mittels phpMyAdmin an und geben ihr den passenden Namen "NoCoinSys".
Natürlich kann man den Namen frei wählen, allerdings muss man dann nachher bei den Beispielen aufpassen, nicht in die falsche Datenbank oder Tabelle zu gelangen.

Table: ncs_user - Benutzerdaten

CREATE TABLE ncs_user (
   pk int(11) NOT NULL auto_increment,
   name varchar(80) default NULL,
   last_name varchar(80) NOT NULL default '',
   login_id varchar(30) NOT NULL default '',
   password varchar(30) NOT NUll default '',
   startpage varchar(255) default NULL,
   PRIMARY KEY (pk),
   UNIQUE KEY pk(pk)
);

Die Tabelle "ncs_user" enthält unsere Benutzerdaten. Der SQL-Befehl kann ganz unkompliziert in phpMyAdmin im SQL-Feld eingeben werden.
Wir werden zum Login-Vorgang die "login_id" sowie das Feld "password" abfragen und SiteKiosk - wenn der Benutzer vorhanden ist - danach den kompletten Namen und die eingetragene Startseite übermitteln, dazu mehr im zweiten Teil des Tutorials.

Table: ncs_account - Benutzerkonto

CREATE TABLE ncs_account (
   pk int(11) NOT NULL default '0',
   value float NOT NULL default '0',
   PRIMARY KEY (pk),
   UNIQUE KEY pk(pk)
);

Das Benutzerkonto zeigt mit seinem Attribut "pk" auf das Attribut "pk" der Benutzerdaten.
Im Attribut "value" steht der eigentliche Kontostand unseres Benutzers - hierbei muss man beachten, dass SiteKiosk den Kontostand immer mit 4 Nachkommastellen übergibt, welches eine höhere Genauigkeit der Transaktionen gewährleistet.

Wir sind uns nun über die Struktur im Klaren und haben die Datenbank soweit aufgesetzt. Der Benutzer wird nachher die Möglichkeit haben, eine Startseite auf dem Server zu speichern, die er sich dann von unserem Terminal anschauen kann. Des Weiteren hat er einen eigenen Account, in dem sein aktuelles Guthaben gespeichert wird.


2. Schritt 2: Serverseitige Scripte und Entwicklung des notwendigen PHP Scripts
2.1 Zieldefinition für Schritt 2
In diesem Teil des Tutorials wollen wir ein PHP Script erstellen, welches die vom Terminal gesendeten Benutzerdaten überprüft und ggf. erweiterte Benutzerdaten zurück schickt oder einen Fehler ausgibt.
Da man mittels JavaScript nachher einfach die ausgegebene Seite analysieren kann, werden die zurückgegebenen Werte mit dem Pipe-Symbol "|" voneinander getrennt.

Um es dem JavaScript einfach zu machen, werden wir eine Fehlernummer (negative Zahlen) bei erfolglosem Einlogg-Versuch als ersten Wert zurückgeben. Wenn das einloggen erfolgreich war, wird dort eine Positive Zahl stehen, z.B.

Ein Beispiel-Rückgabewert vom Server

1|Authentication successful|50|John|Doe|http://www.sitekiosk.de/

Der Wert ist wie folgt aufgegliedert:
Fehlernummer|Nachricht|Guthaben|Vorname|Nachname|Startseite
Damit wird es dem JavaScript nachher möglich sein, den Account zu initialisieren. Wenn der Login-Versuch fehlgeschlagen ist, lassen wir alles hinter "Nachricht" weg und die "Fehlernummer" ist negativ.
2.2 Das PHP-Script
Wenden wir uns nun also dem PHP Script zu.
Zu allererst müssen wir die Datenbank initialisieren - das geschieht mit den Befehlen

mySQL Initialisierung

$link = mysql_connect("SQLServerURL", "SQLUser", "SQLPassword");
mysql_select_db("NoCoinSys");

"SQLServerURL", "SQLBenutzer" und "SQLPasswort" müssen noch auf die Einstellungen des Servers angepasst werden.
Damit wäre das erledigt und wir können uns dem eigentlichen Problem widmen; die vom Benutzer eingegebenen Informationen und vom Script versendeten Felder müssen nun überprüft werden.
Das erledigen wir mittels einer SQL-Abfrage, die uns direkt den Benutzernamen und das Passwort aus der Tabelle "ncs_user" auswählt.

Überprüfung des übermittelten Accounts

$sql = "SELECT * FROM ncs_user WHERE
      login_id='" . $_POST["login_name"] . "' AND
      password='" . $_POST["login_password"] . "'";
$res = mysql_query($sql);

"$_POST["login_name"]" und "$_POST["login_password"]" werden wir mittels unseres JavaScriptes an diese Seite posten.
Wir müssen nun also nur noch die Anzahl der Datensätze von "$res" überprüfen und wissen somit, ob dieser Benutzer existiert und das richtige Passwort angegeben hat oder nicht:

Übermittlung der Benutzerdaten (ggf. eines Fehlers)

if (@mysql_num_rows($res) == 1)
{
      $userobj = mysql_fetch_object($res);
      $sql = "SELECT * FROM ncs_account
            WHERE pk='" . $userobj->pk . "'";
      $res = mysql_query($sql);
      if (@mysql_num_rows($res) == 1)
      {
            $accountobj = mysql_fetch_object($res);
            print "1|Authentication successful|"
                  . $accountobj->value . "|"
                  . $userobj->name . "|"
                  . $userobj->last_name . "|"
                  . $userobj->startpage;
      }
      else
            print "-3|Error: No account found";
}
else
      print "-2|Error: Authentication unsuccessful";

So, ein bisschen viel auf einen Schlag, aber wir werden sehen wofür das alles gut ist.
In Zeile 1 wird, wie oben schon angedeutet, die Anzahl der Datensätze überprüft, die exakt eins sein muss, damit wir einen gültigen Benutzer haben.
Das "@"-Zeichen vor dem Befehl unterdrückt nur etwaige Fehlermeldungen von PHP, die unser JavaScript durcheinander bringen könnten.

Danach, in Zeile 3, packen wir in die Variable "$userobj" die Daten dieses einen Benutzers und setzen in der nächsten Zeile die SQL-Abfrage auf, die uns unseren Account aus der richtigen Tabelle holt. Die beiden Attribute namens "pk" müssen also in beiden Tabellen für einen Benutzer dieselben sein.
Die Überprüfung der Anzahl der Datensätze bleibt wie gehabt, auch für den Account. Wenn wir bis hierhin erfolgreich waren, können wir sagen, dass der Benutzer existiert und einen Kontostand hat, den wir jetzt dem Script übermitteln.

print "1|Authentication successful|"
      . $accountobj->value . "|"
      . $userobj->name . "|"
      . $userobj->last_name . "|"
      . $userobj->startpage;

Das entspricht dem Format, welches wir vorher festgelegt haben. Und genau diese Zeile können wir später im Script auswerten.
Die Fehlerbehandlung ist nach diesem Format damit denkbar einfach: es wird eine Zeile ausgegeben, die den Fehlercode und die Fehlernummer (negativ) enthält. Z.B.:

print "-3|Error: No account found";

2.3 Einbinden der "SetMoney" Funktion
Schauen wir uns das Script noch einmal genauer an. Was kann es bis jetzt?
Wir können der Seite die Login-Daten übermitteln und bekommen dafür als Gegenleistung den kompletten Namen sowie den Kontostand und die Startseite. Nun funktionieren Payment Module-Geräte aber nicht so einfach, außerdem fehlt uns im Moment noch die Möglichkeit, einen neuen Kontostand zu setzen. Bei einem serverseitigen Gerät kann es ja auch z.B. vorkommen, dass die Verbindung vor dem Ausloggen unterbrochen wird und sich somit der Kontostand seit dem Einloggen auf dem Server nicht ändern würde.

Um das zu verhindern, gibt es die minütlich abbuchenden Geräte in SiteKiosk. Diese Geräte haben einen eigenen Kontostand innerhalb von SiteKiosk, buchen einmal pro Minute einen Betrag vom (externen-)Konto ab und setzen somit den Server-Kontostand auf den neuen Wert. Damit sind die Verluste bei einem Komplettausfall so gering wie möglich.
Wir bräuchten also eine Funktion in diesem Script, die uns den Kontostand auf dem Server setzt.
Dafür müssten wir das Script ein klein wenig umschreiben, da im Moment ja bei jedem Aufruf ein Login vorausgesetzt wird.

Damit wir den Fall zwischen normalem Login sowie der SetMoney Funktion unterscheiden können, fügen wir ein weiteres Feld der vom JavaScript geposteten Form an, an dem wir feststellen können, was für eine Aktion gerade vom Script ausgelöst wurde.
Nennen wir sie mal "action". Nun müssen wir nur noch vor dem Zurücksenden der Benutzerdaten eine weitere "if"-Bedingung einfügen, die eben dieses überprüft:

[...]
      $sql = "SELECT * FROM ncs_account
            WHERE pk='" . $userobj->pk . "'";
      $res = mysql_query($sql);
      if (@mysql_num_rows($res) == 1)
      {
            if ($_POST["action"] == "login")
            {
                  $accountobj = mysql_fetch_object($res);
                  print "1|Authentication successful|"
                        . $accountobj->value . "|"
                        . $userobj->name . "|"
                        . $userobj->last_name . "|"
                        . $userobj->startpage;
            }
[...]

Und den Fall abfragen, dass der Benutzer einfach nur seinen neuen Kontostand setzen will:

[...]
      else if ($_POST["action"] == "setmoney")
      {
            $sql = "UPDATE $accountable SET value='" .
                  ereg_replace(",", ".", $_POST["MoneyBack"]).
                        "' WHERE pk='" . $userobj->pk . "'";
 
            $res = mysql_query($sql);
            if ($res)
                  print "1|Account successfully set|" .
                        ereg_replace(",", ".", $_POST["MoneyBack"]);
            else
                  print "-1|Error: Internal Error";
      }
[...]

Folgende Zeile hat noch Erklärungsbedarf:

ereg_replace(",", ".", $_POST["MoneyBack"])

In den meisten Script- und Programmiersprachen werden Zahlenwerte mit einem "." gespeichert, die Funktionen des Payment Modules geben allerdings immer einen Currency Wert zurück, welcher ein Komma enthält (zumindest bei deutschen Betriebssystemen).
Diese Zeile ersetzt dieses Komma durch einen Punkt und ermöglicht so, dass der Wert in der Datenbank mittels der SQL-Abfrage gespeichert werden kann.
2.4 Résumé Schritt 2
Damit hätten wir auf der Serverseite alles nötige, um unser Benutzer-Kontensystem mittels des nun folgenden JavaScript-Teils zu betreiben.
Der Server kann jetzt dem Script die Benutzerdaten, den aktuellen Kontostand und die Startseite übermitteln. Man kann mittels der Variable "$_POST["action"]" festlegen, dass man gerne den Kontostand auf einen neuen Wert, der in der Variable "$_POST["MoneyBack"]" steht, setzen möchte.

Das komplette userpost.php Script zum Anschauen.


3. Schritt 3: Erstellung der notwendigen Benutzer-Dialoge und Überblick über das ScriptDevice
Innerhalb des SiteKiosk Browsers benötigen wir einen kleinen HTML-Dialog, welcher unsere Benutzer nach dem Namen uns Passwort fragt.
Danach werden wir das ScriptDevice näher betrachten und weiteres über die Payment Module Bezahlgeräte Logik erfahren.
3.1 Eingabedialog für die Benutzer
Fangen wir am besten mit dem HTML Dialog an.
Er muss zwei Text-INPUT Felder enthalten, einen Knopf, um die Form abzuschicken und noch ein Feld, in dem der Benutzer nachher seinen kompletten Namen lesen kann, damit er weiß, dass alles gut gelaufen ist:

HTML Login Dialog

<table style='width:100%;'>
   <tr>
      <td>
         <table>
            <tr id='trName'>
               <td style='color: white;'>Name:
               <td><input type='text' name='edtLoginName'>
            <tr id='trPW'>
               <td style='color: white;'>Password:
               <td>
                  <input type='password' name='edtLoginPassword'>
            <tr id='trOK'>
               <td colspan='2'>
                  <input type='button' value='OK' onClick='FormSubmit();'>
            <tr>
               <td style='color: white;' id='LogInfo' colspan='2'>
         </table>
      </td>
   </tr>
</table>

Damit wäre dieser Teil abgehakt. Der Benutzer hat jetzt die Möglichkeit, in diesem Dialog seinen Namen und sein Passwort einzugeben und das ganze abzuschicken.
3.2 Kurzer Überblick über das SiteKiosk ScriptDevice
SiteKiosk bietet eine umfangreiche Script Bibliothek (SiteKiosk Object Model) an, die es uns z.B. in diesem Tutorial ermöglicht, ein eigenes Payment Module Bezahlgerät zu entwickeln.
Schauen wir uns die Script und Test Geräte Funktionen und Attribute noch einmal genauer an:

ScriptDevice

DeviceName [String, read only]
Testmode [Boolean, read only]
AccountEnabled [Boolean]
Balance [Currency, read only]
Volatile [Boolean]
RetransferEnabled [Boolean]
Credit(Currency Value, Boolean bDirect)
Debit(Currency Value, Boolean bDirect)

Die ersten beiden Attribute sind für unser Beispiel nicht erforderlich. Wenden wir uns also dem Rest zu.
"AccountEnabled" setzt die Benutzung des internen Kontos des Payment Modules mit diesem Bezahlgerät. Ist er aktiviert, dann führt das Payment Module Buchungen auch mit dem Guthaben auf dem Konto unseres Gerätes aus.
"Balance" enthält den Betrag, der im Moment im ScriptDevice eingebucht ist. Nur lesbar und über die Funktionen "Credit" und "Debit" änderbar.
"Volatile" beschreibt das Verhalten des Gerätes. Ist dieser Wert wahr, dann kann sich der Kontostand des Gerätes spontan ändern, wie es in unserem Beispiel tatsächlich der Fall sein könnte, wenn z.B. die Serververbindung unterbrochen wird.
"RetransferEnabled". Steht dieser Wert auf wahr, dann wird das Gerät den Geldrückbuchvorgang selbst regeln, näheres dazu bei den Events.
"Credit" kreditiert das Konto und "Debit" debitiert demnach das Konto. Der Parameter "bDirect" gibt an, ob der Betrag direkt im Payment Module eingebucht wird, oder im Konto des Gerätes landen soll.

Folgende Events werden von dem ScriptDevice empfangen:

ScriptDevice

OnSiteCashDebit(Currency AmountPayed, Currency NewBalance)
Boolean OnCheckRetransfer(Currency Amount)
Boolean OnRetransfer(Currency Amount)

Das Event "OnSiteCashDebit" empfängt jeden Debitierungsvorgang vom Payment Module. Also wie geschaffen für unsere Zwecke, da das Payment Module einmal pro Minute abbucht und unserem Gerät so die Möglichkeit gibt, dem Server den neuen Kontostand mitzuteilen.
"OnCheckRetransfer" fragt vor dem eigentlichen Geldrückzahlvorgang die Geräte noch einmal, ob sie damit einverstanden sind - in unserem Fall spricht nichts dagegen, deswegen wird hier auch nur "return true;" zurückgegeben.
"OnRetransfer" führt danach den eigentlichen Geldrückzahlvorgang aus.

Wir brauchen auch noch die Möglichkeit dem Server unsere Anfragen zu stellen, nehmen wir dafür doch das HTTP Post Objekt.
Dieses hat den Vorteil, dass es komplett über Script läuft und man nicht umständliche Forms zusammenstellen muss. Außerdem bekommt man die ausgegebene Seite in einer Variable übergeben, welches das Objekt sehr mächtig macht.

SiteKiosk

Network()

Dieser Befehl holt unser Netzwerk-Objekt, mit dem wir ein Post-Objekt erstellen können:

SiteKiosk.Network

CreateHTTPPost()

Damit haben wir das HTTP Post-Objekt erstellt und können auf die uns dargebotenen Funktionen und Events zugreifen:

HTTP Post

AddParameter(String Name, String Value)
Submit(String strURL)
OnPostComplete(HResult Success, String ReturnValue)

"AddParameter" fügt unserer zu sendenden Form einen neuen Parameter hinzu, mit dem Namen "Name" und dem Wert "Value".
Mittels "Submit" und der gewünschten URL lässt sich dann die Form losschicken.
Das "OnPostComplete" Event wird gefeuert, sobald der Server antwortet. Wenn der Parameter "Success" größer gleich Null ist, hat die Anfrage funktioniert, bei Werten kleiner Null gab es einen Fehler (Server-Timeout o.ä.). In dem String "ReturnValue" steht die zurückgegebene Seite, die wir analysieren müssen.
3.3 Ablauf in der Praxis
Mit den obrigen Informationen haben wir alles Notwendige erfahren, um unser Script Gerät zu erstellen.
Jetzt müssen wir uns nur noch Gedanken darüber machen, was unser Gerät auf der Client Script Seite eigentlich zu tun hat und unsere Funktionen daraus definieren.

Der Benutzer soll seine Daten eingeben und die Form losschicken; damit hätten wir schon mal die Funktion "FormSubmit", die die INPUT-Felder ausliest und unser Server Script mit den nötigen Daten versorgt.
Dann schickt der Server seine Antwort nebst Benutzerdaten, unser "OnPostComplete".
Die Benutzerdaten werten wir in der Funktion "ParseReturnValues" aus.
Während der Benutzer surft, hatten wir gesagt, dass wir einmal pro Minute vom Server-Konto abbuchen wollen. Das erreichen wir, indem sich unser Script an das Event "OnSiteCashDebit" hängt und dort dem Server den geänderten Kontostand mitteilt.
Dem Benutzer wird die Möglichkeit gegeben, sich selbst auszuloggen und dadurch auf dem Server-Kontostand die angefangene Minute wieder gutzuschreiben (Event "OnRetransfer").
3.4 Résumé Schritt 3
Wir sind uns über die benötigten SiteKiosk Object Model Objekte klar geworden und haben einen groben Überblick über die Verhaltensweise von Payment Module-Geräten gewonnen. Wir wissen nun, dass es möglich ist, das Logout-Verhalten der Geräte selbst zu bestimmen und dass ein eigenes Konto für unser Bezahlgerät existiert.
Wir haben das HTTP Post Objekt kennengelernt und wissen nun, dass es im Zusammenhang mit einem Webserver ein mächtiges Werkzeug ist, um SiteKiosk zu steuern.
Unser Gerät ist nun vollständig definiert und wir können uns direkt an das Script setzen.


4. Schritt 4: Erstellung der notwendigen Javascripte (SiteKiosk Object Model) 
Wir haben nun alle notwendigen Informationen gesammelt, um uns dem letzten Teil zuzuwenden: dem JScript, welches unser Gerät steuert.
Fangen wir also gleich an.
4.1 Allgemeine Funktionen

Initialisierung

<script type='text/jscript'>
var PostObj = new Object();
var UserObj = new Object();
var ServerPage = "http://YOUR.SERVER/page.php";
 
var openposts = 0;
 
function InitDialog()
{
   window.external.InitScriptInterface();
 
   ScriptDevice.AccountEnabled = true;
   ScriptDevice.RetransferEnabled = true;
   ScriptDevice.OnCheckRetransfer = OnCheckRetransfer;
   ScriptDevice.OnRetransfer = OnRetransfer;
   ScriptDevice.OnSiteCashDebit = OnSiteCashDebit;
 
   PostObj = SiteKiosk.Network.CreateHTTPPost();
   PostObj.OnPostComplete = OnPostComplete;
}
</script>
<body onload="InitDialog();">
[...]

Für unser Beispiel brauchen wir zwei globale Objekte und zwei globale Variablen:
"PostObj" wird in InitDialog einem neuen HTTP Post Objekt zugewiesen.
In "UserObj" werden wir nach dem Einloggen unsere Benutzerdaten speichern.
"ServerPage" enthält die URL zu dem PHP Script aus Teil 2 und mit "openposts" zählen wir die Versuche, die das minütliche Abbuchen von unserem Server enthält. Bei drei erfolglosen Versuchen loggen wir den Benutzer aus, da sonst ein Missbrauch des Terminals nicht auszuschließen ist.

FormSubmit
Erinnern wir uns: Der Login Dialog hat einen Button, der beim Mausklick die Funktion "FormSubmit" aufruft:

FormSubmit()

function FormSubmit()
{
   PostObj.OnPostComplete = OnPostComplete;
   PostObj.AddParameter("login", "SiteKiosk");
   PostObj.AddParameter("action", "login");
   PostObj.AddParameter("login_name", edtLoginName.value);
   PostObj.AddParameter("login_password", edtLoginPassword.value);
 
   UserObj.name = edtLoginName.value;
   UserObj.password = edtLoginPassword.value;
 
PostObj.Submit(ServerPage);


In der ersten Zeile wird das Event noch einmal neu zugewiesen, da wir dasselbe Objekt auch für das Ausloggen sowie für das minütliche Abbuchen benutzen werden. Diese Vorgänge unterscheiden sich dahingehend, dass wir sie nicht gleich behandeln können (wenn wir das serverseitige Script noch einmal vor unserem inneren Auge revue passieren lassen, dann sehen wir, dass wir ja zwei verschiedene Arten haben, den Server anzusprechen: Login und SetMoney).
Ansonsten werden hier noch die Parameter, die wir auf dem Server auswerten, gesetzt und schlussendlich die Form an die Server URL versandt.

OnPostComplete

OnPostComplete()

function OnPostComplete(success, returnvalue)
{
   ParseReturnValue(returnvalue, false);
 
   PostObj = SiteKiosk.Network.CreateHTTPPost();
   PostObj.OnPostComplete = OnPostComplete;
}

Hier wird nur unsere Auswertungsfunktion aufgerufen und das PostObj neu initialisiert, damit eventuelle Überschneidungen ausbleiben.

ParseReturnValue
Diese Funktion wertet unsere empfangene Seite vom Server aus.
Sie wird von zwei Funktionen aufgerufen: OnPostComplete und OnREPostComplete. Beim letzteren Fall wird diese Funktion hauptsächlich zur Fehlerausgabe vom Server benutzt.
Betrachten wir nun einmal den ersten Teil der Funktion.

ParseReturnValue(value, is_retransfer)

function ParseReturnValue(value, is_retransfer)
{
   var RetArr = value.split("|");
 
   if (is_retransfer == false)
   {
      if (RetArr[2] != null)
      {
         UserObj.RetVal = RetArr[2];
         UserObj.RetName = RetArr[3];
         UserObj.RetLastName = RetArr[4];
         UserObj.RetStartPage = RetArr[5];
      }
      else
         UserObj.RetVal = 0;
   }
   else
      UserObj.RetVal = 0;
[...]

Laut der Definition unseres Rückgabewertes können wir mit "value.split("|")" den Wert in ein Array aufteilen, welches die Benutzerdaten oder den Fehler vom Server enthält.
Wenn wir keinen Logout-Vorgang haben, sondern den Fall, dass unser Benutzer sich nur einloggen möchte, müssen wir unser "UserObj" mit den Benutzerdaten aus dem Array bestücken.
Als nächstes füllen wir die Werte, die auf jeden Fall übertragen wurden, auch bei einem Fehler:

[...]
   UserObj.ReturnValue = value;
   UserObj.RetCode = parseInt(RetArr[0]);
   UserObj.RetMsg = RetArr[1];
 
   if (UserObj.RetCode < 0)
      alert(UserObj.RetMsg);
   else if (UserObj.RetVal > 0 && is_retransfer == false)
   {
      LogInfo.innerHTML = "Successfully logged in as:
"\
         + UserObj.RetName + " " + UserObj.RetLastName + "";
 
      trName.style.display = "none";
      trPW.style.display = "none";
      trOK.style.display = "none";
 
      CreditDebit(UserObj.RetVal, true);
 
      if (UserObj.RetStartPage != "")
         SiteKiosk.WindowList.MainWindow.SiteKioskWindow.\
            SiteKioskWebBrowser.Navigate(UserObj.RetStartPage, true);
   }
}

Und überprüfen dann, ob ein Fehler vorlag (Zeile 5). Ist dies gegeben, wird ein Nachrichtenkasten mit der Fehlermeldung vom Server angezeigt.
Ist dagegen alles gut gelaufen, wechseln wir von der Login-Ansicht zu dem Schriftzug, dass der Benutzer sich erfolgreich eingeloggt hat und zeigen Ihm auch noch seinen Namen.
Der übermittelte Betrag wird gutgeschrieben (Zeile 16) und im Anschluss daran zu der Startseite des Benutzers navigiert:

SiteKiosk.WindowList.MainWindow.SiteKioskWindow.\
SiteKioskWebBrowser.Navigate(UserObj.RetStartPage, true);

Diese Konstruktion mag etwas ungewöhnlich erscheinen, aber es ist die einzige Möglichkeit von einem Nicht-Skin-Fenster auf den SiteKiosk Browser zuzugreifen.

CreditDebit
Das "Herz" unseres Bezahlgerätes ist eine leicht abgewandelte Funktion des normalen, mitgelieferten Testmode-Dialoges:

CreditDebit(fValue, bCredit)

function CreditDebit(fValue, bCredit)
{
   fValue = parseFloat(fValue);
   if (bCredit)
      ScriptDevice.Credit(fValue, false);
   else
      ScriptDevice.Debit(fValue, false);
}

In der dritten Zeile wird unser String, den wir vom Server empfangen haben, in ein Float konvertiert, damit wir die interne JScript Zahl in das Payment Module einbuchen können.
Danach wird dann entweder auf das ScriptDevice Konto der Betrag gutgeschrieben oder abgezogen.

OnSiteCashDebit
Wie besprochen, lassen wir mit dieser Funktion unser Gerät einmal pro Minute den Kontostand auf dem Server aktualisieren.
Sollte dieser Vorgang dreimal hintereinander nicht funktionieren, loggen wir den Benutzer aus (Kontostand wird auf Null gesetzt) und benachrichtigen ihn, dass etwas schief gegangen ist:

OnSiteCashDebit(payedamount, newbalance)

function OnSiteCashDebit(payedamount, newbalance)
{
   if (openposts < 3)
   {
      if (UserObj.name != null)
      {
         PostObj.OnPostComplete = OnSCDPostComplete;
 
         PostObj.AddParameter("login", "SiteKiosk");
         PostObj.AddParameter("action", "setmoney");
         PostObj.AddParameter("MoneyBack", newbalance);
         PostObj.AddParameter("login_name", UserObj.name);
         PostObj.AddParameter("login_password", UserObj.password);
 
         PostObj.Submit(ServerPage);
 
         ++openposts;
      }
      else
         return false;
   }
   else
   {
      OnREPostComplete(true, "");
      ScriptDevice.Debit(ScriptDevice.Balance, false);
      alert("The server timed out, please call\
         support personell!");
      openposts = 0;
   }
}

Im ersten Teil wird dem PostObj eine neue Funktion zugewiesen, die beim Beenden des Sendevorgangs aufgerufen werden soll: OnSCDPostComplete, die eigentlich nur den Zähler der offenen posts pro Rückgabewert dekrementiert.
Weiterhin wird dem Server mit dem Parameter "action" vom PostObj, der auf "setmoney" steht, gesagt, dass wir unser Guthaben auf dem Serverkonto setzen wollen.
Nach dem Absenden wird dann der Zähler um eins erhöht, damit wir bei dem nächsten Abbuchungsvorgang genau testen können, wie viele Posts noch nicht zurückgekommen sind.
Danach, im zweiten Teil, wissen wir, dass irgendwas mit dem Server nicht funktioniert und loggen den Benutzer deshalb über den Aufruf der Funktion OnREPostComplete aus, ziehen das aktuelle Guthaben ab und benachrichtigen ihn über den Missstand.

OnSCDPostComplete

OnSCDPostComplete(success, returnvalue)

function OnSCDPostComplete(success, returnvalue)
{
   openposts--;
}

4.2
Ausloggen-Vorgang

Damit wären wir auch schon beim letzten Teil: unser Bezahlgerät muss das Ausloggen selbst in die Hand nehmen und dem Server das genaue Restguthaben übermitteln.

OnCheckRetransfer
Wie wir in der Theorie gelernt haben, muss unser Bezahlgerät beim Logout Vorgang auf zwei Events reagieren: OnCheckRetransfer und OnRetransfer.
OnCheckRetransfer ist denkbar einfach. Wenn das Gerät mit dem Logout Vorgang einverstanden ist, wird "true" zurückgegeben, wenn nicht "false". Das ermöglicht eine bessere Überprüfung und das Unterbrechen des Logout-Vorgangs.
Unser Gerät ist immer mit dem Ausloggen einverstanden:

OnCheckRetransfer(amount)

function OnCheckRetransfer(amount)
{
   return true;
}

OnRetransfer
Nach erfolgreicher Überprüfung folgt der eigentliche Logout-Vorgang. Die Serverantwort wollen wir wieder in einer anderen Funktion behandeln: OnREPostComplete.
Danach setzen wir mittels der Serverfunktion "setmoney" den Kontostand auf das übrig gebliebene Geld:

OnRetransfer(amount)

function OnRetransfer(amount)
{
   PostObj.OnPostComplete = OnREPostComplete;
 
   PostObj.AddParameter("login", "SiteKiosk");
   PostObj.AddParameter("action", "setmoney");
   PostObj.AddParameter("MoneyBack", ScriptDevice.Balance + amount);
   PostObj.AddParameter("login_name", UserObj.name);
   PostObj.AddParameter("login_password", UserObj.password);
 
   PostObj.Submit(ServerPage);
 
   ScriptDevice.Debit(ScriptDevice.Balance, false);
 
   return true;
}

Dann wird in Zeile 11 die Form gesendet und der Benutzer ausgeloggt, indem wir das Konto von unserem Gerät auf Null setzen.
Diese Funktion muss "true" zurückgeben, damit SiteKiosk Bescheid weiß, dass wir erfolgreich beim Ausloggen waren.

OnREPostComplete
Hier reagieren wir darauf, dass unser Logout-Vorgang erfolgreich war (Server hat geantwortet). Wir initialisieren unsere Objekte neu und stellen dem Benutzer wieder die Möglichkeit zur Verfügung, dass er sich einloggen kann:

OnREPostComplete(success, value)

function OnREPostComplete(success, returnvalue)
{
   ParseReturnValue(returnvalue, true);
 
   PostObj = SiteKiosk.Network.CreateHTTPPost();
   PostObj.OnPostComplete = OnPostComplete;
 
   edtLoginName.value = "";
   edtLoginPassword.value = "";
   LogInfo.innerHTML = "";
   UserObj = new Object();
 
   trName.style.display = "block";
   trPW.style.display = "block";
   trOK.style.display = "block";
}

In Zeile 3 rufen wir wieder ParseReturnValue auf, damit eventuelle Fehler vom Server ausgegeben werden.
Danach werden die Variablen zurückgesetzt und die Tabelle zum Einloggen wieder auf den Anfangsstand gebracht.
4.3 Résumé Schritt 4
Wir haben nun ein komplett funktionierendes Payment Module Bezahlgerät entwickelt.
Es reagiert auf die gegebenen Events, bucht also einmal pro Minute den vom Payment Module vorgegebenen Betrag ab und lässt den Benutzer selbst entscheiden, wann er sich ausloggen will.
Im Falle eines Serverausfalls wird der Benutzer benachrichtigt und vorerst ausgeloggt.

Die komplette ServerPayed Beispiel-HTML-Seite gibt es hier.

Es gibt natürlich verschiedene Ansätze, diesen Dialog in SiteKiosk einzubauen.

5. Schritt 5: Umsetzungsmöglichkeiten und Erweiterungen
5.1 Viele Wege führen nach Rom
Bei unseren Tests haben wir der Einfachheit halber den Script & Test Gerät Dialog genommen (wird in der Skin Definition festgelegt), um das Gerät zu implementieren.
Dieser Dialog hat den Vorteil, dass er die ganze Zeit über angezeigt wird und man sich so keine Gedanken über das Speichern der Benutzerdaten machen muss.
Es gibt aber noch verschiedene andere Wege in SiteKiosk dasselbe zu erreichen.
So könnte man z.B. aus dem Skin heraus einen Dialog aufrufen, der genau dasselbe macht. Man müsste dann nur über die Dialogfunktion "AttachDispatch" (siehe SiteKiosk Object Model Dokumentation) unser "UserObj" dem Dialog übergeben und hätte somit nachher die Benutzerdaten im Skin und könnte darauf dann dort reagieren.
Vorstellbar ist auch, dass man aus dem Payment Module-Bezahldialog einen Dialog öffnet oder selbst den Dialog als Eingabemaske benutzt, der Fantasie sind hier wenig Grenzen gesetzt.
5.2 Mögliche Erweiterungen
Das HTTP Post Objekt sieht komplett so aus:

HTTP Post Object

String Referer;
AddParameter(String Name, String Value);
SetAuthInfo(String Name, String Password);
Submit(String bstrURL);
Abort();
 
OnPostComplete(HResult Success, String ReturnValue);

Diese Architektur erlaubt gewisse Möglichkeiten. Es wäre z.B. denkbar, dass man seinen Server nur via HTTPS anspricht und mit Passwortabfrage versieht (dazu müsste man dann im Script "ScriptDevice.SetAuthInfo(BENUTZER, PASSWORT)" aufrufen).
Das wäre ein großer Sicherheitsvorteil, da auf dem beschriebenen Weg aus dem Tutorial sich sonst vielleicht jemand in die Verbindung einklinken könnte und somit seinen eigenen Kontostand verändern könnte (was sehr unwahrscheinlich ist - erst einmal müsste der User aus SiteKiosk herauskommen oder irgendwie die Dateien auf dem Terminal lesen können - aber man kann nie wissen...).

Als weitere Sicherheitsmaßnahme könnte man in dem serverseitigen Script überprüfen, ob der zu setzende Kontostand größer als der letzte Kontostand ist und wenn dies der Fall ist, die Buchung nicht durchführen.

Schauen wir uns das ScriptDevice auch einmal komplett an:

ScriptDevice

DeviceName [String, read only]
Testmode [Boolean, read only]
AccountEnabled [Boolean]
Balance [Currency, read only]
Volatile [Boolean]
RetransferEnabled [Boolean]
Credit(Currency Value, Boolean bDirect)
Debit(Currency Value, Boolean bDirect)
 
OnSiteCashDebit(Currency AmountPayed, Currency NewBalance);
Boolean OnCheckRetransfer(Currency Amount);
Boolean OnRetransfer(Currency Amount);
Boolean OnLogoutButtonPressed();
OnPropertyChange();
OnBalanceChange(Currency NewBalance);

Wie wir sehen sind ein paar Events hinzugekommen, von denen vorher nicht die Rede war.
"OnLogoutButtonPressed" wird direkt nachdem der Benutzer auf den Logout Button gedrückt hat aufgerufen, noch vor dem Rückbuchvorgang.
"OnPropertyChange" - Eins der folgenden Attribute hat sich geändert: AccountEnabled, RetransferEnabled oder Volatile.
Wenn "OnBalanceChange" gefeuert wird, hat sich der interne Kontostand geändert.

Wir hoffen, dieses Tutorial hat Ihnen einen guten Überblick über die neuen Scriptfunktionen gegeben.



Nach oben