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 "Transaction Processing";
# 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 " Credit card authorization in progress...
";
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'}, "
\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'}, "\n";
&reviewedsale($authresult{'result_text'});
}
if ($status == CV_AUTH) {
print "Authorization successful - Transaction proceeding...
";
print "Testing authresult: acode:", $authresult{'acode'}, " Result Text: ", $authresult{'result_text'},"
";
$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 " Transaction Completed!
";
print "
Thank you for your transaction.
";
print "Here is your receipt
";
print "Transaction $transactnum ; Username $username ;
";
print "$cctype card number $trunccard was billed for \$$total";
print "";
}
else {
print " Transaction completed with errors
";
print "
Thank you for your transaction.
";
print "Your username was not found, and has been queued for manual processing
";
print "Here is your receipt
";
print "Transaction $transactnum ; Username $username ;
";
print "$cctype card number $trunccard was billed for \$$total";
print "