Mid-Level Example


#!/usr/bin/perl # ccbilling.pl: CGI to CCVS # Author: Brent Selch, selchb@ka.net # $Id$ use DBI; # Predefinable Variables... $dbase="foo"; $dbhost="foo.net"; $dbuser="bar"; $dbpass="baz"; $action="none"; # Use Address Verification? $USE_AVS='true'; # Output the stuff browsers need to see print "Content-type: text/html\n\n"; # Gotta use the library use CCVS; # Open a CCVS session $sess = CCVS::init("demo"); if ($sess == CV_SESS_BAD) { die "Couldn't Initialize CCVS"; } # Print out the HTML document header print "<html><head><title>Transaction Processing</title></head><body bgcolor=#FFFFFF>"; # Unmunge the input variables into sane English :) read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $VARS{$name} = $value; } # Let's get all the vars that we need now... $invoice = $VARS{'Invoice'}; $billtype = $VARS{'Amount'}; $dollaramount = $VARS{'DollarAmount'}; $cctype = $VARS{'CCType'}; $cardnum = $VARS{'CardNum'}; $cardholder = $VARS{'CardHolder'}; $username = $VARS{'Username'}; $mailprog = '/usr/sbin/sendmail'; $address = $VARS{'Address'}; $address2 = $VARS{'Address2'}; $city = $VARS{'City'}; $state = $VARS{'State'}; $zipcode = $VARS{'ZipCode'}; $uptodateaddress = $VARS{'BillingAddress'}; $billagain = $VARS{'BillAgain'}; #Munge the date into an intelligible form... #($month, $year) = split(/\//,$VARS{'ExpDate'}); #$expdate = $month."/".$year; ($foo,$bar,$y1,$y2) = split(//,$VARS{'ExpYear'}); $expdate = $VARS{'ExpMonth'}."/".$y1.$y2; # I don't feel safe doing this, since there's no mechanism # for locking the DB while I do this... # As an added measure of safety, I'll use transactnum in the ccnum # field until later... Unique id of sorts... $transactnum = "op".&get_lastrow + 1; &send_sql("INSERT INTO transact(username,invoice,ccnum,cctype,expdate,time) VALUES ('$username','$invoice','$transactnum $username','$cctype','$expdate',now())"); # Get the address if not update if ($uptodateaddress eq 'yes') { $address = &get_address($username); $zipcode = &get_zipcode($username); } # Create the CCVS session and start passing variables... if ($billtype eq "dollar") { $total = $dollaramount } elsif ($billtype eq "semiannual") { $total = "89.70" } elsif ($billtype eq "quarterly") { $total = "53.85" } else { $total = "19.95" } CCVS::new($sess, $transactnum) == CV_OK || die "Can't create invoice"; CCVS::add($sess, $transactnum, CV_ARG_AMOUNT, $total) == CV_OK || die "Can't add $billtype amount $total"; CCVS::add($sess, $transactnum, CV_ARG_CARDNUM, $cardnum) == CV_OK || die "Can't add card number"; CCVS::add($sess, $transactnum, CV_ARG_EXPDATE, $expdate) == CV_OK || die "Can't add expiration date"; if ($USE_AVS) { CCVS::add($sess, $transactnum, CV_ARG_AVS_ADDRESS, $address) == CV_OK || die "Can't add address"; CCVS::add($sess, $transactnum, CV_ARG_AVS_ZIPCODE, $zipcode) == CV_OK || die "Can't add zip code"; } CCVS::add($sess, $transactnum, CV_ARG_ACCOUNTNAME, $cardholder) == CV_OK || die "Can't add cardholder"; print "<h3> Credit card authorization in progress... <br>"; CCVS::auth($sess, $transactnum) == CV_OK || &reallydie ("Credit Card transaction failed - Please contact KA.Net at 502-992-0324 to try again."); # Loop while we wait on the transaction to processs do { sleep 1; $status = CCVS::status($sess, $transactnum); } until ($status == CV_AUTH || $status == CV_DENIED || $status == CV_REVIEW); # So now we're either Authorized, Declined, or Held for Review (eww...) # We need to unmunge the status passed from CCVS now $sessionresult = CCVS::textvalue($sess); %authresult = split / *{|} */,$sessionresult; # Now we need to print out the results... if ($status == CV_DENIED) { print "Authorization failed for invoice number $transactnum; Reason:\n", $authresult{'result_text'}, "</h3>\n"; } # Reviews are more nasty... Do we want to let them through under a certain # amount, or do we deny all CV_REVIEW as well? if ($status == CV_REVIEW) { print "Authorization under review for transactnum number $transactnum; Reason:\n", $authresult{'result_text'}, "</h3>\n"; &reviewedsale($authresult{'result_text'}); } if ($status == CV_AUTH) { print "Authorization successful - Transaction proceeding...<br>"; print "Testing authresult: acode:", $authresult{'acode'}, " Result Text: ", $authresult{'result_text'},"<br>"; $acode = $authresult{'acode'}; $resulttext = $authresult{'result_text'}; # Bill 'em (CCVS::sale($sess, $transactnum) == CV_OK) || &failedsale($authresult{'result_text'}); # Time to see if the user is frozen/chilled or not, and whether or not to # change that. $customernum = &get_custid($username); if ($customernum ne "") { $amountowed = &get_amount($customernum, $invoice); if ( $amountowed ne "" && $amountowed le $total ) { &warm($customernum, $invoice); } # Get the last 4 digits of the cc number $trunccard = &truncate_cc($cardnum); # Let 'em know that everything is done and happy :) print "<i> Transaction Completed! </i><br></h3>"; print "</h3><center><br>Thank you for your transaction.<br>"; print "Here is your receipt<br></center>"; print "Transaction $transactnum ; Username $username ;<br>"; print "$cctype card number $trunccard was billed for \$$total"; print "</body></html>"; } else { print "<i> Transaction completed with errors </i><br></h3>"; print "</h3><center><br>Thank you for your transaction.<br>"; print "Your username was not found, and has been queued for manual processing<br>"; print "Here is your receipt<br></center>"; print "Transaction $transactnum ; Username $username ;<br>"; print "$cctype card number $trunccard was billed for \$$total"; print "</body></html>"; } #Send mail notification to billing open(MAIL, "|$mailprog -t -oi") || die "Can't open $mailprog\n"; print MAIL "From: Online Payment<staff\@ka.net>\n"; print MAIL "To: billing\@ka.net\n"; print MAIL "Cc: selchb\@ka.net\n"; print MAIL "Subject: (Online Payment) Transaction number $transactnum\n\n"; print MAIL "Payment from username $username, Invoice number $invoice\n"; print MAIL "Payment placed on $cctype number $cardnum exp $expdate for \$ $total\n"; print MAIL "Here\'s the auth result: $acode\n"; print MAIL "Here\'s the result text: $resulttext\n"; if ($billagain eq 'yes') { print MAIL "\nKeep the above card on file for future billings\n\n"; } else { print MAIL "\nBill only this amount\n\n"; } if ($uptodateaddress eq 'no') { print MAIL "\n\nNew Address:\n"; print MAIL "Address 1: $address\n"; print MAIL "Address 2: $address2\n"; print MAIL "City: $city\n"; print MAIL "State: $state\n"; print MAIL "Zip: $zipcode\n"; } close(MAIL); #Send mail notification to user open(MAIL, "|$mailprog -t -oi") || die "Can't open $mailprog\n"; print MAIL "From: Online Payment<staff\@ka.net>\n"; print MAIL "To: $username\@ka.net\n"; print MAIL "Subject: (Online Payment) Transaction number $transactnum\n\n"; print MAIL "Payment from username $username, Invoice number $invoice\n"; print MAIL "Payment placed on $cctype number $trunccard for \$ $total\n"; if ($billagain eq 'yes') { print MAIL "\nKeeping the above card on file for future billings\n\n"; } else { print MAIL "\nBilling only this amount\n\n"; } if ($uptodateaddress eq 'no') { print MAIL "\n\nNew Address:\n"; print MAIL "Address 1: $address\n"; print MAIL "Address 2: $address2\n"; print MAIL "City: $city\n"; print MAIL "State: $state\n"; print MAIL "Zip: $zipcode\n"; &send_sql("UPDATE user_db SET addr_1='$address',addr_2='$address2',city='$city',state='$state',zip='$zipcode' WHERE username='$username'"); } close(MAIL); &send_sql("UPDATE transact set action='$action', amount='$total', resulttext='$resulttext', acode='$acode', ccnum='$cardnum' where ccnum='$transactnum $username'"); } # Time to clean up CCVS::done($sess); sub dbdie { print "<h1>The MySQL database is currently unavailable.<br>"; print "Your request cannot be processed, try again later.</h1>"; die "Cannot connect to SQL "; } sub send_sql { $dbr = DBI->connect("DBI:mysql:$dbase:$dbhost",$dbuser,$dbpass) || &dbdie; $str = $dbr->prepare($_[0]); $str->execute || &dbdie; $str->finish; $dbr->disconnect; } sub get_custid { $dbh = DBI->connect("DBI:mysql:$dbase:$dbhost",$dbuser,$dbpass) || &dbdie; $SQL="SELECT custid from user_db where username='$_[0]'"; $sth = $dbh->prepare($SQL); $sth->execute || &dbdie; @columns = $sth->fetchrow; $sth->finish; $dbh->disconnect; return $columns[0]; } sub get_address { $dbh = DBI->connect("DBI:mysql:$dbase:$dbhost",$dbuser,$dbpass) || &dbdie; $SQL="SELECT addr_1 from user_db where username='$_[0]'"; $sth = $dbh->prepare($SQL); $sth->execute || &dbdie; @columns = $sth->fetchrow; $sth->finish; $dbh->disconnect; return $columns[0]; } sub get_zipcode { $dbh = DBI->connect("DBI:mysql:$dbase:$dbhost",$dbuser,$dbpass) || &dbdie; $SQL="SELECT zip from user_db where username='$_[0]'"; $sth = $dbh->prepare($SQL); $sth->execute || &dbdie; @columns = $sth->fetchrow; $sth->finish; $dbh->disconnect; return $columns[0]; } sub get_freezeid { $dbh = DBI->connect("DBI:mysql:$dbase:$dbhost",$dbuser,$dbpass) || &dbdie; $SQL="SELECT freezeid from freeze2 where custid='$_[0]' and valid='y' and invnum='$_[1]'"; $sth = $dbh->prepare($SQL); $sth->execute || &dbdie; @columns = $sth->fetchrow; $sth->finish; $dbh->disconnect; return $columns[0]; } sub get_amount { $dbh = DBI->connect("DBI:mysql:$dbase:$dbhost",$dbuser,$dbpass) || &dbdie; $SQL="SELECT amount from freeze2 where custid='$_[0]' and invnum='$_[1]' "; $sth = $dbh->prepare($SQL); $sth->execute || &dbdie; @columns = $sth->fetchrow; $sth->finish; $dbh->disconnect; return $columns[0]; } sub get_status { $dbh = DBI->connect("DBI:mysql:$dbase:$dbhost",$dbuser,$dbpass) || &dbdie; $SQL="SELECT active from user_db where custid='$_[0]'"; $sth = $dbh->prepare($SQL); $sth->execute || &dbdie; @columns = $sth->fetchrow; $sth->finish; $dbh->disconnect; return $columns[0]; } sub get_lastrow { $dbh = DBI->connect("DBI:mysql:$dbase:$dbhost",$dbuser,$dbpass) || &dbdie; $SQL="SELECT id from transact order by id desc limit 1"; $sth = $dbh->prepare($SQL); $sth->execute || &dbdie; @columns = $sth->fetchrow; $sth->finish; $dbh->disconnect; return $columns[0]; } sub thaw { $status=&get_status($_[0]); if ($status =~ m/^frozen/) { &send_sql("UPDATE user_db SET active='thaw' WHERE custid='$_[0]'"); } } sub warm { if (&get_status($_[0]) =~ m/^chill/) { $unfreezeid=&get_freezeid($_[0],$_[1]); &send_sql("UPDATE freeze2 set end=now(),valid='n' where freezeid='$unfreezeid'"); &send_sql("UPDATE user_db set active='active' where custid='$_[0]'"); $action="warm"; } else { &thaw($_[0]); $action="thaw"; } } sub failedsale { print "Please contact KA.Net at 502-992-0324 regarding this transaction<br>"; print "Please mention that this is regarding transaction $invoice<br>"; print "</body></html>"; open (FMAIL, "|$mailprog -t -oi") || die "Can't open $mailprog\n"; print FMAIL "From: Online Payment <staff\@ka.net>\n"; print FMAIL "To: billing\@ka.net\n"; print FMAIL "Subject: (Online Payment) Failed Sale $invoice\n\n"; print FMAIL "CCVS::sale failed for invoice $invoice. Please track this down\n"; print FMAIL "Transaction $transactnum \n"; print FMAIL "Result Code $_[0] \n"; print FMAIL "Username: $username, amount $amount \n"; close (FMAIL); die "Failed Sale\n"; } sub reviewedsale { print "Please contact KA.Net at 502-992-0324 regarding this transaction<br>"; print "Please mention that this is regarding transaction $invoice<br>"; print "</body></html>"; open (FMAIL, "|$mailprog -t -oi") || die "Can't open $mailprog\n"; print FMAIL "From: Online Payment <staff\@ka.net>\n"; print FMAIL "To: billing\@ka.net\n"; print FMAIL "Subject: (Online Payment) Review Sale $invoice\n\n"; print FMAIL "CCVS::sale under review for invoice $invoice. Please track this down\n"; print FMAIL "Transaction $transactnum \n"; print FMAIL "Result Code $_[0] \n"; print FMAIL "Username: $username, amount $amount \n"; close (FMAIL); } sub truncate_cc { $revnum=reverse($_[0]); ($digit1,$digit2,$digit3,$digit4,$blah)=split(//,$revnum); $lastfour=$digit1.$digit2.$digit3.$digit4; return reverse($lastfour); } sub reallydie { print "<h3>$_[0]</h3></body></html>\n"; die "$_[0]"; }
Prev Next Back to outline