#!/usr/local/bin/perl # confirm.pl - web cgi routine to confirm the shopping cart order # # Dave Stoddard - 6/01/04 # dgs@accelix.com # # Copyright # --------- # Copyright(c) 2004, Accelix LLC. All Rights Reserved. # # Description # ----------- # This program handles the process of confirming the order with the customer # for the shopping cart system. The steps in the checkout process, and their # associated modules, are as follows: # # checkout.pl - collect shipping information for the customer's order # billing.pl - show total and collect billing information # confirm.pl - show total and confirm or cancel the order # payment.pl - process payment and provide an invoice # # This routine presents the user with two buttons -- Accept and Decline. If # they accept the order, the payment is processed in the next CGI routine. # If they decline the order, the cart is erased and a message is displayed. # # RCS Information # --------------- # $Id$ # $Log$ # # package main; use strict 'vars'; use strict 'subs'; # use warnings; # use diagnostics; # load application modules use cart; # shopping cart support routines # --------------------------- # DECLARATIONS AND PROTOTYPES # --------------------------- # local elements my %db1 = (); # database handle my %form = (); # data from form (name/value pairs) my %state = (); # state persistence data hash my %sess = (); # session id hash my %orders = (); # orders table record my %shipto = (); # shipto table record my %billto = (); # billto table record my $prev = "/cgi-bin/billing.pl"; # previous CGI program my $curr = "/cgi-bin/confirm.pl"; # this CGI program my $next = "/cgi-bin/payment.pl"; # next in the series of CGI programs # function prototypes sub DisplayConfirmPage (); # display the shipping info form sub DisplayDecline (); # display decline page sub GetOrdersRecord ($); # retrieve a orders record sub GetShiptoRecord ($); # retrieve a shipto record sub GetBilltoRecord ($); # retrieve a billto record sub KillOrder (); # kill the current order ### ### START PROGRAM ### # initialize the program %form = ReadForm (); # read the form %state = GetState (%form); # get current state data (cookies) %sess = GetSession (%form,%state); # get session information # # These are consistency checks to make sure the user is not entering the # application in a manner that is out of sequence. These checks are done # to tamper proof the system. # # make sure the orders record exists %orders = GetOrdersRecord ($sess{sessid}); if (CheckError()) { DisplayError(); ExitProgram(); } unless (%orders) { ErrorMsg ("Order master record is missing -- checkout aborted."); DisplayError(); ExitProgram(); } # make sure the shipto record exists %shipto = GetShiptoRecord ($sess{sessid}); if (CheckError()) { DisplayError(); ExitProgram(); } unless (%shipto) { ErrorMsg ("Shipping record is missing -- checkout aborted."); DisplayError(); ExitProgram(); } # make sure the billto record exists %billto = GetBilltoRecord ($sess{sessid}); if (CheckError()) { DisplayError(); ExitProgram(); } unless (%billto) { ErrorMsg ("Billing record is missing -- checkout aborted."); DisplayError(); ExitProgram(); } # use phase to determine what to do if (defined $form{phase}) { if ($form{phase} == 1) { # decline selected - show decline screen DisplayDecline (); } else { DisplayConfirmPage(); } } else { DisplayConfirmPage(); } ExitProgram (); ### End Main Program ### ### ### DisplayConfirmPage() displays the confirmation page to the customer. ### If the customer accepts, the transaction is posted. If the customer ### declines, the transaction is canceled. ### sub DisplayConfirmPage () { # output the top part of the page # SetPageSize (560,560); # SetPageName ("_xcheckout"); OutputPageTop("Confirm Your Order"); # put a heading on the page print <

Confirm Order

 
Please Confirm Your Order
 
Your order has not been placed yet. Please confirm your order by reviewing the totals below and accepting the conditions that are listed in the text that follows.
 
  Item Sub-Total: \$$orders{itemtot}  
  Sales Tax: \$$orders{tax}  
  Shipping Cost: \$$orders{shipcost}  
  Order Total: \$$orders{total}  
 
In order to place your order, you must agree to the following terms:
  1. You are at least eighteen (18) years or age or older.

  2. You have the authorization to charge the credit card you have specified for a total amount of \$$orders{total}.

  3. You have read and agree with the terms and conditions described in our ordering policies, our shipping information, and the FAQ section of our web site.

If you agree to these terms, click the button labeled "Agree" below. Your credit card will be charged and your order will be placed. If you do not agree with these terms, click the "Decline" button and your order information will be removed.
 
   
 
EOF OutputPageBottom(); return 1; } ### ### DisplayDecline() displays a decline confirmation page to the customer. ### The only action available is to close the window. ### sub DisplayDecline () { # kill the order KillOrder (); # get a new session id $sess{sessid} = NewSessionID (); # output the top part of the page SetPageSize (560,560); SetPageName ("_xcheckout"); OutputPageTop("Order Declined"); # put a heading on the page print <
 
Decline Acknowledged
 
We are sorry you have declined to accept our terms. While we value all of our customers, we must establish specific terms and conditions in order to remain in business. To protect your information, we have erased all of the data for this order from the system, including your credit card billing information.
 

 
EOF OutputPageBottom(); return 1; } ### ### GetOrdersRecord() retrieves the order record from the database. It ### returns a hash of the fields returned, or undef if an error occurs. ### Error messages are returned through the application error table. This ### function requires the session id as a parameter. ### sub GetOrdersRecord ($) { my $sessid = shift; # session id of shopping cart my %out = (); # result output hash my %db1 = (); # database connection hash my $ref = ""; # hash reference # make sure we are connected to the database unless (ConnectDatabase()) { return %out; } # obtain the connection info %db1 = GetDatabaseInfo(); # prepare the select statement $db1{sth} = $db1{dbh}->prepare (qq{ SELECT * FROM orders WHERE sessid = "$sessid" }); # check for error if ($DBI::err) { ErrorMsg ("Unable to prepare select: $DBI::err : $DBI::errstr"); return %out; } # execute the statement $db1{sth}->execute (); # check for error if ($DBI::err) { ErrorMsg ("Unable to execute select: $DBI::err : $DBI::errstr"); return %out; } # retrieve a pointer to the record hash $ref = $db1{sth}->fetchrow_hashref; # check for record not found if (!defined $ref) { return %out; } %out = %{$ref}; $db1{sth}->finish (); return %out; } ### ### GetShiptoRecord() retrieves the shipto record from the database. It ### returns a hash of the fields returned, or undef if an error occurs. ### Error messages are returned through the application error table. This ### function requires the session id as a parameter. ### ### Data from this record is used to populate new billing records. ### sub GetShiptoRecord ($) { my $sessid = shift; # session id of shopping cart my %out = (); # result output hash my %db1 = (); # database connection hash my $ref = ""; # hash reference # make sure we are connected to the database unless (ConnectDatabase()) { return %out; } # obtain the connection info %db1 = GetDatabaseInfo(); # prepare the select statement $db1{sth} = $db1{dbh}->prepare (qq{ SELECT * FROM shipto WHERE sessid = "$sessid" }); # check for error if ($DBI::err) { ErrorMsg ("Unable to prepare select: $DBI::err : $DBI::errstr"); return %out; } # execute the statement $db1{sth}->execute (); # check for error if ($DBI::err) { ErrorMsg ("Unable to execute select: $DBI::err : $DBI::errstr"); return %out; } # retrieve a pointer to the record hash $ref = $db1{sth}->fetchrow_hashref; # check for record not found if (!defined $ref) { return %out; } %out = %{$ref}; $db1{sth}->finish (); return %out; } ### ### GetBilltoRecord() retrieves the billto record from the database. It ### returns a hash of the fields returned, or undef if an error occurs. ### Error messages are returned through the application error table. This ### function requires the session id as a parameter. ### sub GetBilltoRecord ($) { my $sessid = shift; # session id of shopping cart my %out = (); # result output hash my %db1 = (); # database connection hash my $ref = ""; # hash reference # make sure we are connected to the database unless (ConnectDatabase()) { return %out; } # obtain the connection info %db1 = GetDatabaseInfo(); # prepare the select statement $db1{sth} = $db1{dbh}->prepare (qq{ SELECT * FROM billto WHERE sessid = "$sessid" }); # check for error if ($DBI::err) { ErrorMsg ("Unable to prepare select: $DBI::err : $DBI::errstr"); return %out; } # execute the statement $db1{sth}->execute (); # check for error if ($DBI::err) { ErrorMsg ("Unable to execute select: $DBI::err : $DBI::errstr"); return %out; } # retrieve a pointer to the record hash $ref = $db1{sth}->fetchrow_hashref; # check for record not found if (!defined $ref) { return %out; } %out = %{$ref}; $db1{sth}->finish (); return %out; } ### ### KillOrder() deletes all relevent records for a declined order. ### sub KillOrder () { my $rows = 0; # row counter # make sure we are connected to the database unless (ConnectDatabase()) { return 0; } # obtain the connection info %db1 = GetDatabaseInfo(); # delete the orders record $rows = $db1{dbh}->do (qq{ DELETE FROM orders WHERE sessid = "$sess{sessid}" }); # check for error if ($DBI::err) { ErrorMsg ("error: unable to delete order: $DBI::err : $DBI::errstr"); return 0; } # delete the shipping info $rows = $db1{dbh}->do (qq{ DELETE FROM shipto WHERE sessid = "$sess{sessid}" }); # check for error if ($DBI::err) { ErrorMsg ("error: unable to delete shipping info: $DBI::err : $DBI::errstr"); return 0; } # delete billing info $rows = $db1{dbh}->do (qq{ DELETE FROM billto WHERE sessid = "$sess{sessid}" }); # check for error if ($DBI::err) { ErrorMsg ("error: unable to delete billing info: $DBI::err : $DBI::errstr"); return 0; } # delete the shopping cart $rows = $db1{dbh}->do (qq{ DELETE FROM cart WHERE sessid = "$sess{sessid}" }); # check for error if ($DBI::err) { ErrorMsg ("error: unable to delete shopping cart: $DBI::err : $DBI::errstr"); return 0; } # update the session id for decline $rows = $db1{dbh}->do (qq{ UPDATE session SET attrib = "1" WHERE sessid = "$sess{sessid}" }); # check for error if ($DBI::err) { ErrorMsg ("error: unable to update session: $DBI::err : $DBI::errstr"); return 0; } return 1; }