Glengamoi (Forum) · AspHeute · .NET Heute (RSS-Suche) · AspxFiles (Wiki) · .NET Blogs

Keine gefakten Bestellungen mehr!

Geschrieben von: Christian Holm
Kategorie: Komponenten

This printed page brought to you by AlphaSierraPapa

Wenn man Kunden die Möglichkeit bietet, Produkte online zu bestellen, sollte man auf jeden Fall die eingegebenen Daten (Name, Emailadresse, Kreditkarteninformationen, etc.) überprüfen, bevor der Kunde die Bestellung abschicken kann. Dies erspart unnötigen Ärger über falsche Angaben die eine Bestellung wertlos machen können. Eine Abhilfe bietet die SA Check Komponente von SoftArtisans, die Ihnen bei der Validierung Ihrer Bestellformulare hilft und dabei viel Codierungsarbeit erspart.

Die Evaluierungsversion der SA Check Komponente können Sie bei SoftArtisans downloaden. 30 Tage können Sie dann die Komponente testen, ob sie Ihren Vorstellungen entspricht. Nach Ablauf der Evaluierungsperiode müssen Sie sich bei Weiterverwendung zum Kauf entschließen.

Nach dem Download der Komponente enpacken Sie das Archiv, kopieren die Dateien SACheck.dll, source.dat und Olchk32.dll in das System32 Verzeichnis des Webservers. Danach ist die Komponente mit regsvr32 SACheck.dll am Webserver zu registrieren. Und schon ist die Komponente einsatzbereit.

Für diesen Artikel habe ich ein einfaches Bestellformular vorbereitet, welches die Funktionalität der Komponente einsetzt. Der Beispielsourcecode umfaßt dabei "nur" die Erfassung der Kundendaten und Ihre Validierung. Was fehlt ist die Funktionalität des Shoppingcarts und die der Aufgabe bzw. Verarbeitung der Bestellung. Aber gerade der Teil der Erfassung und Validierung der Kundeninformationen ist besonders kritisch, und deswegen gehen wir den relevanten Teil des Sourcecodes schrittweise durch (IBuyStuff.asp):

bIsPostback = CLng(Request.ServerVariables("CONTENT_LENGTH"))
strComment = Trim(Request.Form("txtComment"))
strEmail = Trim(Request.Form("txtEmail"))
strPhone = Trim(Request.Form("txtPhone"))
strAddress = Trim(Request.Form("txtAddress"))
strFullName = Trim(Request.Form("txtFullName"))
strCardNumber= Trim(Request.Form("txtCardNumber"))
strCardType = Trim(Request.Form("selCardType"))
strExpMonth = Trim(Request.Form("expMonth"))
strExpYear = Trim(Request.Form("expYear"))

Zu Beginn speichern wir den Inhalt der CONTENT_LENGTH Servervariable in der Variable bIsPostback. Damit läßt sich feststellen, ob ein Postback zum Server stattgefunden hat oder nicht. Zusätzlich speichern wir hier die Werte der Eingabefelder aus dem Formular. Diese Werte werden dann in einem späteren Teil mit Hilfe der SA Check Komponente auf ihre Gültigkeit hin überprüft. Der Grund, warum ich dieses Auslesen schon am Anfang der Seite mache? Damit ich bei Falscheingabe dem User zumindest seine eingegebenen Daten im nun folgenden Formularteil nochmals präsentieren kann.

Daher folgt vor der Eingabevalidierung das Formular in dem der Kunde seine Daten (Name, Adresse, Kreditkarteninformationen, etc.) eingeben muß:

<form action="IBuyStuff.asp" method="post">
<table border="0">
<th colspan="2" align="left">Personal Details:</th>
<tr>
    <td width="124">
        Full Name:
    </td>
    <td>
        <input type="Text" name="txtFullName" value="<%=strFullName%>" size="37">
    </td>
</tr>
<tr>
    <td>
        Address:
    </td>
    <td>
        <textarea name="txtAddress" cols="28" rows="5"><%=strAddress%></textarea>
    </td>
...

Dies ist natürlich nur ein Sourcecodeabschnitt von den Eingabefeldern. Die restlichen sind auf ähnliche Weise formuliert. Zwecks einfacher Handhabung und als Demonstration reichen Tabellen für die Eingabefelder als Positionierungshilfen. Natürlich würde man, um auch die optische Qualität zu verbessern, CSS verwenden - dies sei aber nur nebenbei erwähnt. Als nächstes folgt die Eingabe der Zahlungsmodalitäten. Für dieses Beispiel habe ich mich alleinig für die Möglichkeit der Bezahlung per Kreditkarte entschieden, da die SA Check Komponente hier eine Vorvaliderungsmöglichkeit bietet - was genau diese alles kann, erfahren Sie etwas später.

Der folgende Sourcecode erfaßt also die Kreditkarteninformationen. Um das Beispiel etwas aufzupeppen, zeige ich mittels JavaScript bei Auswahl einer Kreditkartenfirma das jeweilig dazugehörige Logo an:

<tr valign="middle">
    <td>
        Credit Card Type:
    </td>
    <td valign="top">
        <SCRIPT LANGUAGE="JavaScript">
        <!--
        function display(selection) 
        {
        switch (selection.options[selection.selectedIndex].text)
        { 
          case "Master Card" : document.creditcard.src='images/mc.png'; break;
          case "Visa" : document.creditcard.src='images/vi.png'; break;
          case "American Express": document.creditcard.src='images/ae.png'; break;
          default : document.creditcard.src='images/nosel.png';
         }
        }
        // -->
        </SCRIPT>
        <SELECT NAME="selCardType" onChange="display(this)">
        <OPTION VALUE=""></OPTION>
        <OPTION VALUE="Master Card">Master Card</OPTION>
        <OPTION VALUE="Visa">Visa</OPTION>
        <OPTION VALUE="American Express">American Express</OPTION>
        </SELECT>
    </td>
    <td>        
        <IMG NAME="creditcard" SRC="images/nosel.png" WIDTH="100" HEIGHT="60" border="0" alt="">
    </td>
</tr>

Mittels eines Switch Statements unterscheide ich zwischen den einzelnen Kreditkartenfirmen (die angegebenen Firmen wurden natürlich rein willkürlich gewählt), die aus einer Dropdown-Listbox ausgewählt werden können. Sobald eine Auswahl vom Benutzer getätigt wurde, erscheint dann das entsprechende Symbol durch document.creditcard.src='Bild'. Dieses Statement referenziert auf den unterhalb der Dropdown befindlichen Image Tag.

Die für die Authorisierung der Kreditkarte notwendigen Informationen sind wiederum der Einfachheit halber in einer Tabelle eingebunden:

<tr>
    <td>
        Card Number:    
    </td>
    <td colspan="2">
        <input type="text" name="txtCardNumber" size="37">    
    </td>
</tr>
<tr>
    <td>
        Expiry Date:
    </td>
    <td colspan="2">
        <SELECT NAME="expMonth">
        <OPTION VALUE""></OPTION>
        <OPTION>01</OPTION>
                     ...
        </SELECT>
        / 
        <SELECT NAME="expYear">
        <OPTION VALUE""></OPTION>
        <OPTION>2001</OPTION>
                     ...
        <OPTION>2005</OPTION>
        </SELECT>
    </td>
</tr>
<tr>
    <td>
        Card Holder's Name:    
    </td>
    <td colspan="2">
        <input type="text" name="txtCardHolder" size="37">
    </td>
</tr>
<tr>
    <td align="center" colspan="3">
        <input type="submit" value="Submit Order">
    </td>
</tr>
</table>        

Diese Informationen beinhalten auch die Gültigkeit der Kreditkarte (Dropdown-Listbox), welche ebenfalls überprüft wird.

Nun, das war dann auch schon das ganze Eingabeformular - jetzt erst folgt der nötige Sourcecode, der für die Validerung zuständig ist. Beginnen wir mit der Überprüfung der Kreditkarte:

   Set SA_Check=Server.CreateObject("SMUM.XCheck.1")

    If strCardNumber <> "" AND Len(strCardNumber) = 19 Then
        strCardNumber = SA_Check.CreditCardTypeFromNumber(strCardNumber)
    Else
        Response.Write "Invalid Card Number Format!<br>"
        bError = true
    End If
    
    If (strCardType <> strCardNumber) Then
        Response.Write "Invalid Card Number!<br>"
        bError = true
    End If
    If Not (strExpMonth = "") AND Not (strExpYear = "") Then
        If (CInt(strExpMonth) <= CInt(Month(Now))) AND (CInt(strExpYear) <= CInt(Year(Now))) Then
            Response.Write "Credit Card Expired!<br>"
            bError = true
        End If    
    Else
        Response.Write "No Expiry Date!<br>"
    End If

Da wir ja nun von der SA Check Komponente Gebrauch machen, müssen wir zuerst mit Server.CreateObject ein Objekt für sie instanzieren. Wie ich vorher schon erwähnt habe, bietet die Komponente eine Art Vorvalidierung für Kreditkarten - was heißt das? Damit ist gemeint, daß die Komponente zwar die Kreditkartenfirma identifizieren kann (was natürlich schon ein Hindernis für einen Betrug darstellt), aber die restlichen 12 Stellen der Nummer bleiben unberücksichtigt. Diese enthalten ja nun die verschlüsselten Karteninhaberinformationen.

Diese Validierung erledigt die CreditCardTypeFromNumber Methode, die die 16 stellige Nummer als Eingabeparameter übernimmt und die ersten vier Stellen der Nummer überprüft. Als Rückgabewert erhält man - falls die ersten vier Stellen gültig waren - den Namen der Kreditkartenfirma. Es werden hierbei die gängigsten Firmen unterstützt.

Falls die Nummer ungültig ist, wird eine Fehlermeldung ausgegeben und eine Variable namens bError vom Variant-Subtyp Bool auf true gesetzt. Diese Art der (Vor)Authentifizierung sollte zunächst genügen, da letztendlich vor der Transaktion der Bestellung die Kreditkarte sowieso bei dem Kreditkarteninstitut authorisiert werden muß.

Im gleichen Atemzug sehen wir noch nach, ob auch die richtige Anzahl von Stellen eingegeben wurden. Dies geschieht hier mit der Len Funktion. 19 Stellen deshalb, weil ich eigenwillig die Eingabe im Format XXXX-XXXX-XXXX-XXXX verlange, also 16 Stellen für die Kreditkartennummer und drei für die Separatoren.

Weiters verifizieren wir, ob die Angaben des Benutzer auch untereinander stimmen. Ich überprüfe also die Auswahl der Firma (selCardType, select Anweisung) mit dem Ergebnis der Komponente aus der Evaluierung der ersten vier Stellen der Nummer.

Zuletzt überprüfen wir das "Ablaufdatum" der Karte, indem wir das erforderlich einzugebende Datum mit dem aktuellen Datum vergleichen. Die bloße Anwendung der Methoden Month und Year ist zugegeben etwas kühn, da die Zeitzone des Servers hier bestimmend ist. Dies könnte bei internationelem Vertrieb in drastisch unterschiedliche Zeitzonen beim Wechsel der Monate bzw. Jahr zu fälschlichen Ergebnissen führen.

Wie in den vorigen Evaluierungstufen wird auch hier je nach auftretendem Fehler eine entsprechende Meldung ausgegeben, und falls nicht schon geschehen, die Variable bError auf true gesetzt.

Um weiteren Mißbrauch zu unterbinden, überprüfen wir mit Hilfe der Komponente die Eingabe eines sinnvollen Namens. Dummy-Namen wie z.B. eine wirre Buchstabenansammlung oder den berühmten "John Doe" (samt Familienmitglieder, z.B. Jane) haben hier keine Chance:

If (SA_Check.IsValidName(strFullName)) Then
        Response.Write "Please enter your name again<br>"
        bError = true
End If

Obwohl die Komponente aus den USA stammt, sind teilweise auch Namen aus dem deutschsprachigen Raum vertreten. Der Datenbestand wird aber fortwährend erweitert - solange Ihre Kunden nicht wie in den USA unliebsame Personen heißen, aber dafür in Europa gebräuchliche Namen haben, können diese auch bestellen.

Weiters überprüfen wir noch, ob die angegebene Emailadresse gültig ist:

If Not (SA_Check.IsValidEmail(strEmail)) Then 
    	Response.Write "This is an invalid Email address<br>"
        bError = true
End If

Was vielleicht nicht so ganz ernstzunehmen scheint, ist die Überprüfung auf diverse ausfällige Bemerkungen. Damit lassen sich Bestellungen von Kunden, die gern überschwenglich ihrem Zorn freien Lauf lassen, ohne viel Aufwand annullieren - haben Sie schon oft (erbost) bestellt und nichts erhalten?:

If (SA_Check.HasProfanity(strComment)) Then
        Response.Write "Explicit language!<br>"
        bError = true
End If

Nun ist die Bestellung kurz vor dem Versenden. Sie wird abgeschickt, wenn keine Fehler in den Formularfeldern aufgetaucht sind:

If (bError) Then 
        Response.Write "No Order Submitted!"
Else
     ...
End If

In der Alternativverzweigung des if-Statements können Sie - da die Bestellung (bis jetzt) gültig erscheint - die Daten zur Bestellungsauthorisierung dem Kreditkarteninstitut übermitteln und bei abermaligem Erfolg endlich die Bestellung entgegennehmen. Dies, wie gesagt, sollte nicht Thema des Artikels sein.

Zu guter Letzt möchte ich Ihnen noch zwei Screenshots präsentieren, die jeweils nach Ausführung der ASP-Seite IBuyStuff.asp im Browserfenster angezeigt wurden:

 

Ad Screenshots - linker Hand eine vorerst gültige Bestellung. Das zweite Bild zeigt eine ungültige Bestellung mit Fehlermeldungen.

Schlußbemerkung

Die Vorteile der Komponente liegen in der einfachen Handhabung und in den umfangreichen Möglichkeiten der Validerungen - wohlgemerkt hat der Artikel nur eine bescheidene und für das Artikelbeispiel relevante Auswahl getroffen. Da der Sourcecode einfach gehalten ist, läßt er sich auch beliebig ergänzen und eben "shopping"- tauglich machen.

This printed page brought to you by AlphaSierraPapa

Download des Codes

Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20010531.zip

Verwandte Artikel

Überprüfen von HTML-Formularen mit ASP
http:/www.aspheute.com/artikel/20000522.htm
Auswertung von HTML Formularen mit ASP
http:/www.aspheute.com/artikel/20000406.htm
AutoCompletion für Web Formulare
http:/www.aspheute.com/artikel/20001121.htm
Kreditkartenüberprüfung mit ASP
http:/www.aspheute.com/artikel/20000628.htm
Mailadressen-überprüfen für Fortgeschrittene
http:/www.aspheute.com/artikel/20000822.htm
Sichere Zahlungen im Internet mit SET
http:/www.aspheute.com/artikel/20000901.htm

Links zu anderen Sites

SA Check
http://www.softartisans.com/softartisans/saxcheck.html

 

©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.