Home > Bezahlgeräte > Unterstützte Bezahlgeräte > Dialogfenster zur Bezahlsimulation (zum Testen) > Tutorial zum ScriptDevice
Tutorial zum Scriptmodus
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.
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
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