19.2 Credit Card and Shipping Instructions

When a user finishes adding items to his cart, he usually proceeds to a purchase. In the winestore, the first step after clicking on the Make Purchase button is entering credit card details and optional shipping instructions.

The first steps of the ordering process are encapsulated in the order/order-step1.php and order/order-step2.php scripts shown in Example 19-1 and Example 19-2 respectively. The order/order-step1.php script collects credit card details and delivery instructions, and the order/order-step2.php script validates these and writes them to the orders table if they're valid. On validation failure, order/order-step1.php is re-requested and error messages are displayed above the data entry widgets and the widgets are repopulated with the erroneous data.

The scripts are implemented using the same approach as the customer management processes discussed in Chapter 17. The winestoreFormTemplate class that's described in Chapter 16 is used to display the form, and two session arrays are used to manage previously-entered data and error messages. The validation of credit card details is performed by functions that are discussed in detail in Chapter 9, and stored in the validate.inc include file that's listed in Chapter 16.

The credit card number is stored unencrypted. You can encrypt it using the two-way mcrypt library functions, which aren't installed on most platforms by default and are briefly discussed in Chapter 9. These functions are discussed at http://www.php.net/manual/en/ref.mcrypt.php.

Example 19-1. The order/order-step1.php credit card and delivery details form

// This script allows a user to enter their credit card number

// and delivery instructions.

// The user must be logged in to view it.

require_once "../includes/template.inc";

require_once "../includes/winestore.inc";

require_once "../includes/authenticate.inc";


session_start( );

// Check the user is properly logged in


// Takes form heading, instructions, action, formVars name, and

// formErrors name as parameters

$template = new winestoreFormTemplate("finalize Your Order",

            "Please enter your SurchargeCard details " .

            "(Try: 8000000000001001 ) and delivery instructions.",

            S_ORDER_2, "ccFormVars", "ccErrors");

// Create the credit card widgets

$template->mandatoryWidget("creditcard", "SurchargeCard:", 16);

$template->mandatoryWidget("expirydate", "Expiry Date (mm/yy):", 5);

$template->optionalWidget("instructions", "Delivery Instructions:", 128);

$template->showWinestore(SHOW_ALL, B_SHOW_CART | B_HOME);


Example 19-2. The order/order-step2.php credit card validation and writing script

require_once "DB.php";

require_once "../includes/winestore.inc";

require_once "../includes/authenticate.inc";

require_once "../includes/validate.inc";


session_start( );

// Connect to a authenticated session


// Check that the cart isn't empty

if (!isset($_SESSION["order_no"]))


   $_SESSION["message"] = "Your cart is empty!";

   header("Location: " . S_SHOWCART);



$connection = DB::connect($dsn, true);

if (DB::isError($connection))

   trigger_error($connection->getMessage( ), E_USER_ERROR);

// Register an error array - just in case!

$_SESSION["ccErrors"] = array( );

// Set up a formVars array for the POST variables

$_SESSION["ccFormVars"] = array( );

foreach($_POST as $varname => $value)

   $_SESSION["ccFormVars"]["{$varname}"] =

     pearclean($_POST, $varname, 128, $connection);

// Check if mandatory credit card entered

if (checkMandatory("creditcard", "SurchargeCard",

              "ccErrors", "ccFormVars"))

   // Validate credit card using Luhn algorithm

   checkCard("creditcard", "ccErrors", "ccFormVars");

// Check if mandatory credit card expiry entered

if (checkMandatory("expirydate", "expiry date",

              "ccErrors", "ccFormVars"))

   // Validate credit card expiry date

   checkExpiry("expirydate", "ccErrors", "ccFormVars");

// Now the script has finished the validation,

// check if there were any errors

if (count($_SESSION["ccErrors"]) > 0)


    // There are errors.  Relocate back to step #1

    header("Location: " . S_ORDER_1);



// OK to update the order

$query = "UPDATE orders SET

          creditcard = '{$_SESSION["ccFormVars"]["creditcard"]}',

          expirydate = '{$_SESSION["ccFormVars"]["expirydate"]}',

          instructions = '{$_SESSION["ccFormVars"]["instructions"]}'

          WHERE cust_id = -1 AND

                order_id = {$_SESSION["order_no"]}";

$result = $connection->query($query);

if (DB::isError($result))

   trigger_error($result->getMessage( ), E_USER_ERROR);

// Clear the formVars so a future <form> is blank



// Relocate to the order processing

header("Location: " . S_ORDER_3);