#!/usr/bin/perl =head1 NAME CCLib.pm -- Compatibility module for AUTHORIZE.NET and CyberCash version 2 =cut package CCLib; # You need the SSLeay perl module installed, # look for it on http://www.cpan.org use Net::SSLeay; use Carp; use Exporter; @EXPORT = qw/ SetServer sendmserver /; use POSIX qw/tmpnam/; $VERSION = '0.01'; use vars qw/$VERSION/; my $Port = 443; my $Server = 'www.authorize.net'; my $Path = '/scripts/authnet25/AuthRequest.asp'; my $Password; my $VendorID; my $Reqavs; =head1 VERSION 0.02 =head1 SYNOPSIS #not used for minivend :) use CCLib; SetServer( host => 'www.authorize.net', port => '443', secret => 'test', vendor => 'test', ); my $mode = 'mauthonly' || 'mauthcapture'; %result = sendmserver( $actual{cyber_mode}, 'Order-ID' => $orderID, 'Amount' => $amount, 'Card-Number' => $actual{mv_credit_card_number} 'Card-Name' => $actual{b_name}, 'Card-Address' => $actual{b_address}, 'Card-City' => $actual{b_city}, 'Card-State' => $actual{b_state}, 'Card-Zip' => $actual{b_zip}, 'Card-Country' => $actual{b_country}, 'Card-Exp' => $exp, ); if($result{MStatus} !~ /^success/) { $error = $result{MErrMsg}; return undef; } else { return 1; } =head1 DESCRIPTION This module interfaces Authorize.net servers to software designed for CyberCash 2. It is also quite suitable for standalone use with Perl. This module was designed to work with MiniVend, so if you see references to $Vend::Cfg that is the reason. You may ignore those references; they should not cause problems. If you want to set your Vendor ID in the environment, use $ENV{AUTHORIZENET_VENDORID}. The C executable can either reside in the Perl @INC libary include path, or can be in your $ENV{PATH}. They are used in that order. =head2 Example of use with MiniVend Set the following variables in catalog.cfg: # the authorize.net host Variable CYBER_HOST www.authorize.net # the authorize.net port, defaults to 443 #Variable CYBER_PORT 443 # your password Variable CYBER_SECRET testlogin # your password Variable CYBER_VENDOR testpassword # Do you want to deny transactions with an AVS mismatch? Variable CYBER_AVS TRUE/FALSE You can set your mv_cyber_mode variable to any valid PaymentNet transaction type, or to the CyberCash: CyberCash AuthorizeNet ------------------------------ mauthonly NA mauthcapture PA =head1 AUTHOR Jeff Nappi, Cyberhighway Internet Services Based on paymentnet CyberCash 2 interface by Mike Heins of Internet Robotics =head1 BUGS Doesn't capture and log approval. That would be easy to add. =cut sub SetServer { #::logGlobal("Setserver called", @_); my (%hash) = @_; $Server = $hash{'host'} if $hash{'host'} and $hash{'host'} ne 'localhost'; $Port = $hash{'port'} if $hash{'port'} and $hash{'port'} ne '8000'; $Password = $hash{'secret'} if $hash{'secret'}; if ($hash{'vendor'}) { $VendorID = $hash{'vendor'}; #::logGlobal("vendor id assigned from hash"); } elsif($ENV{AUTHORIZENET_VENDORID}) { #::logGlobal("vendor id assigned from AUTHORIZENET env"); $VendorID = $ENV{AUTHORIZENET_VENDORID}; } elsif( defined $Vend::Cfg and ref $Vend::Cfg->{Variable} and $Vend::Cfg->{Variable}{CYBER_VENDOR} ) { #::logGlobal("vendor id assigned from CYBER_VENDOR"); $VendorID = $Vend::Cfg->{Variable}{CYBER_VENDOR}; } else { carp "No vendor id assigned.\n"; $VendorID = 'test'; } return 1; } my %mode_translate = ( qw/ NA NA AO AO CR CR PA PA mauthonly NA mauthcapture PA authonly NA authcapture PA / ); sub sendmserver { my $mode = shift; my %opt = @_; if ($Vend::Cfg->{Variable}{CYBER_AVS} =~ "TRUE") { $Reqavs = "TRUE"; } else { $Reqavs = "FALSE"; } my $debug = "mode=$mode\n"; for(keys %opt) { $debug .= "$_=$opt{$_}\n"; } my $temp = $CGI::values{mv_order_number}; #::logGlobal("HELLO: sendmserver called:\n$debug"); my (@err_parms); unless( $Server && $Password && $VendorID && $Port ) { @err_parms = ( 'MStatus' , 'error_before_connect', 'MErrMsg' ); my $err = ''; $err .= "No server set.\n" unless $Server; $err .= "No password given.\n" unless $Password; $err .= "No port set.\n" unless $Port; $err .= "No Vendor ID given.\n" unless $VendorID; push @err_parms, $err; #::logGlobal("error", @err_parms); return(@err_parms); } $opt{'Card-Number'} =~ tr/0-9//cd; $opt{'Card-Exp'} =~ tr/0-9//cd; $opt{'Card-Exp'} = "0" . $opt{'Card-Exp'} if length $opt{'Card-Exp'} < 4; $opt{'Amount'} =~ tr/.0-9//cd; unless ($mode_translate{$mode}) { @err_parms = ('MStatus', 'error_before_connect', 'MErrMsg', 'No mode set.'); #::logGlobal("error", @err_parms); return(@err_parms); } my ($page,$server_response,%headers,$response, $authcode,$text,$avs,$transid); ($page, $server_response, %headers) = &Net::SSLeay::post_https($Server, $Port, $Path, '', &Net::SSLeay::make_form( 'TESTREQUEST' => 'FALSE', 'LOGIN' => $VendorID, 'PASSWORD' => $Password, 'AMOUNT' => $opt{'Amount'}, 'METHOD' => $CGI::values{METHOD}, 'TYPE' => $mode_translate{$mode}, 'CARDNUM' => $opt{'Card-Number'}, 'EXPDATE' => $opt{'Card-Exp'}, 'NAME' => $opt{'Card-Name'}, 'ADDRESS' => $opt{'Card-Address'}, 'CITY' => $opt{'Card-City'}, 'STATE' => $opt{'Card-State'}, 'ZIP' => $opt{'Card-Zip'}, 'COUNTRY' => $opt{'Card-Country'}, 'REJECTAVSMISMATCH' => $Reqavs)); ($response,$authcode,$text,$avs,$transid) = split (/,/,$page); #::logGlobal("response was --$response--\nauthcode was --$authcode--\ntext was --$text--\navs was --$avs--\ntransid was --$transid--\n"); my %result; if ($response eq 'A' || $reponse eq 'P') { #::logGlobal("response was --$response--\nset MStatus to success.\n"); $result{MStatus} = 'success'; $result{'order-id'} = 1; } else { #::logGlobal("response was --$response--\nset MErrMsg to $text.\n"); $result{MStatus} = 'failure'; if (grep(/AVS/, $text)) { $result{MErrMsg} = "You must enter the correct billing address of your credit card. The bank returned the following error: " . $text; } else { $result{MErrMsg} = $text; } } return (%result); } 1;