[ic] How do I get the errors to show on CC processing with Authorize.net

Robert Trembath interchange-users@lists.akopia.com
Fri Jun 8 15:54:01 2001


Javier,
I did what you suggested and this is what I got:

[robert@www globalsub]$ perl -c authorizenet
syntax error at authorizenet line 3, near "EOS
sub authorizenet "
Can't use global @_ in "my" at authorizenet line 4, near "= @_"
BEGIN not safe after errors--compilation aborted at authorizenet line 122.

I don't know perl. I know php,sql,html,asp and a few others. So I'm not
familar with perl syntax. Any help would be greatly appreciated.

I've been using this without real-time credit authorization and love it, but
how much of a perfomance hit will this be? I'm running a dell poweredge 1550
with 866PIII, 1gig of RAM, Raid 5 with PERC3 on RH 7.0. Any idea?

Here's what's in my authorizenet file, it located in
/usr/lib/interchange/eg/globalsub/:

GlobalSub <<EOS
sub authorizenet {
	my ($user, $secret, $amount) = @_;

	my (%actual) = Vend::Order::map_actual();

	if (! $user ) {
		$user    =  $::Variable->{MV_PAYMENT_ID} ||
                    $::Variable->{CYBER_ID}
                    or return undef;
	}

	if(! $secret) {
        $secret  =  $::Variable->{MV_PAYMENT_SECRET} ||
                    $::Variable->{CYBER_SECRET}
                    or return undef;
    }

    my $server  =   $::Variable->{MV_PAYMENT_SERVER} ||
                    $::Variable->{CYBER_SERVER} ||
                    'secure.authorize.net';

    my $script 	=   $::Variable->{MV_PAYMENT_SCRIPT} ||
                    $::Variable->{CYBER_SCRIPT} ||
                    '/gateway/transact.dll';

    my $port    =   $::Variable->{MV_PAYMENT_PORT} ||
                    $::Variable->{CYBER_PORT} ||
                    443;

	my $precision = $::Variable->{MV_PAYMENT_PRECISION} ||
                    $::Variable->{CYBER_PRECISION} ||
                    2;
	my $referer   = $::Variable->{MV_PAYMENT_REFERER};

	$actual{mv_credit_card_exp_month} =~ s/\D//g;
    $actual{mv_credit_card_exp_month} =~ s/^0+//;
    $actual{mv_credit_card_exp_year} =~ s/\D//g;
    $actual{mv_credit_card_exp_year} =~ s/\d\d(\d\d)/$1/;

    $actual{mv_credit_card_number} =~ s/\D//g;

    my $exp = sprintf '%02d%02d',
                        $actual{mv_credit_card_exp_month},
                        $actual{mv_credit_card_exp_year};

	 $actual{cyber_mode} = 'AUTH_CAPTURE'
        unless $actual{cyber_mode};

	my %type_map = (
		mauth_capture 			=>	'AUTH_CAPTURE',
		mauthonly				=>	'AUTH_ONLY',
		CAPTURE_ONLY			=>  'CAPTURE_ONLY',
		CREDIT					=>	'CREDIT',
		VOID					=>	'VOID',
		PRIOR_AUTH_CAPTURE		=>	'PRIOR_AUTH_CAPTURE',

	);

	if (defined $type_map{$actual{cyber_mode}}) {
        $actual{cyber_mode} = $type_map{$actual{cyber_mode}};
    }
    else {
        $actual{cyber_mode} = 'AUTH_CAPTURE';
    }

    if(! $amount) {
        $amount = Vend::Interpolate::total_cost();
        $amount = sprintf("%.${precision}f", $amount);
    }

    my($orderID);
    my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
gmtime(time());

    # We'll make an order ID based on date, time, and MiniVend session

    # $mon is the month index where Jan=0 and Dec=11, so we use
    # $mon+1 to get the more familiar Jan=1 and Dec=12
    $orderID = sprintf("%02d%02d%02d%02d%02d%05d%s",
            $year + 1900,$mon + 1,$mday,$hour,$min,$Vend::SessionName);

    my %query = (
                    x_Card_Num		=> $actual{mv_credit_card_number},
                    x_First_Name        => $actual{b_fname},
                    x_Last_Name         => $actual{b_lname},
                    x_Address           => $actual{b_address1},
                    x_City              => $actual{b_city},
                    x_State             => $actual{b_state},
                    x_Zip		=> $actual{b_zip},
                    x_Type		=> $actual{mv_payment_mode},
                    x_Amount    	=> $amount,
                    x_Exp_Date  	=> $exp,
                    x_Method    	=> 'CC',
                    x_Invoice_Num       => $actual{mv_order_number},
#                    x_Company           => $actual{company},
#                    x_Phone             => $actaul{day_phone},
                    x_Password  	=> $secret,
                    x_Login     	=> $user,
                    x_Version   	=> '3.0',
                    x_ADC_URL   	=> 'FALSE',
                    x_ADC_Delim_Data	=> 'TRUE',


    );

    my @query;

    for (keys %query) {
        my $key = $_;
        my $val = $query{$key};
        $val =~ s/["\$\n\r]//g;
        $val =~ s/\$//g;
        my $len = length($val);
        if($val =~ /[&=]/) {
            $key .= "[$len]";
        }
        push @query, "$key=$val";
    }
    my $string = join '&', @query;

    use Net::SSLeay qw(post_https make_form make_headers);

    my ($page, $response, %reply_headers)
                = post_https($server, $port, $script,
                	   make_headers( Referer => $referer),
                       make_form(
                               %query
                       ));

    # Minivend names are on the  left, Authorize.Net on the right
    my %result_map = ( qw/
            MStatus               x_response_code
            pop.status            x_response_code
            MErrMsg               x_response_reason_text
            pop.error-message     x_response_reason_text
            order-id              x_trans_id
            pop.order-id          x_trans_id
            pop.auth-code         x_auth_code
            pop.avs_code          x_avs_code
            pop.avs_zip           x_zip
            pop.avs_addr          x_address
    /
    );


#::logError(qq{\nauthorizenet page: $page response: $response\n});

    my ($response_code,
    	$response_subcode,
    	$response_reason_code,
    	$response_reason_text,
    	$auth_code,
    	$avs_code,
    	$trans_id) = split (/,/,$page);

#::logError(qq{authorizenet response_reason_text=$response_reason_text
response_code: $response_code});

    my %result;
    if ($response_code == 1) {
    	$result{MStatus} = 'success';
    	$result{'order-id'} = 1; # ? Why this this set to 1? -mark
    } else {
    	$result{MStatus} = 'failure';

		# NOTE: A lot more AVS codes could be checked for here.
    	if ($avs_code eq 'N') {
    		$result{MErrMsg} = "You must enter the correct billing address of your
credit card. The bank returned the following error: " .
$response_reason_text;
    	} else {
    		$result{MErrMsg} = "$response_reason_text" ;
			my $msg = errmsg("Authorizenet error: %s. Please call in your order or
try again.",
					$response_reason_text,
					);
    	}
    }

    return (%result);

}
EOS

-----Original Message-----
From: interchange-users-admin@developer.akopia.com
[mailto:interchange-users-admin@developer.akopia.com]On Behalf Of Javier
Martin
Sent: Friday, June 08, 2001 12:01 PM
To: interchange-users@developer.akopia.com
Subject: RE: [ic] How do I get the errors to show on CC processing with
Authorize.net


I'll try to answer your question also sharing my experience with the
authorizenet module:

If the authorizenet globalsub doesn't seem to even execute, you probably
have compilation errors or some module is missing. Strip out everything
except the perl code, save it with another name and do a 'perl -c' on that
file. It will show you errors. In my case, I was missing the Net::SSLeay
module. You can install it through:

  perl -MCPAN -e 'install Net::SSLeay'


There are a couple more things I had to change in the authorizenet module:


1. Put error messages in the $Vend::Session->{errors}{mv_credit_card_valid}
variable. This allows automatically displaying errors in red in your form by
way of the [error] tag (see the construct example, you will really NEED to
get ideas from there). After the '$result{MStatus} = "failure"' (near the
end of file), add this line:

   $Vend::Session->{errors}{mv_credit_card_valid} = $response_reason_text;


2. Force the transaction type to be a constant value, instead of fetching it
from the mv_payment_mode CGI variable, because someone could save your
checkout page locally, add an <input hidden name=mv_payment_mode
value="CREDIT"> and you will be creditting the customer instead of charging
him!!!.  Probably you'll want to invent a new variable in catalog.cfg (say
MV_PAYMENT_TRANSACTION), and set it to "AUTH_CAPTURE". Then in the %query
hash you change the "x_type" value to:

   x_type => $::Variable{MV_PAYMENT_TRANSACTION}


3. The cyber_mode and mv_cyber_mode variables are not used, and will not be
used in versions past 4.6.5. Forget all you have read about it.


4. You will also want to test transactions before going live. Add a new
variable (say MV_PAYMENT_TEST), then add code to the authorize globalsub to
check it and add a new pair "x_Test_Request" to the %query hash.


5. I have experienced some problems when querying authorizenet for a
payment. During the time it takes to authorize to charge the credit card,
the whole interchange server gets blocked. This means that no one will
obtain response from the server during this lapse. This problem gets more
serious if for some reason the authorizenet response is delayed due to some
error! In test mode, sometimes my interchange server blocks for 1-2 minutes
waiting for authorize. I'm still trying to work this out. Anyone has
deas?  --  Mike?

Javier



> -----Original Message-----
> From: interchange-users-admin@developer.akopia.com
> [mailto:interchange-users-admin@developer.akopia.com]On Behalf Of Robert
> Trembath
> Sent: viernes, 08 de junio de 2001 17:38
> To: interchange-users@developer.akopia.com
> Subject: RE: [ic] How do I get the errors to show on CC processing with
> Authorize.net
>
>
> I finally got it to enter something in the error log:
>
> 131.226.161.178 mKSFVWZR:131.226.161.178 - [08/June/2001:09:27:11 -0500]
> catalog /cgi-bin/catalog/process.html bad custom payment GlobalSub:
> authorizenet
>
> Here is what's in my authorizenet:
>
> GlobalSub <<EOS
> sub authorizenet {
> 	my ($user, $secret, $amount) = @_;
>
> 	my (%actual) = Vend::Order::map_actual();
>
> 	if (! $user ) {
> 		$user    =  $::Variable->{MV_PAYMENT_ID} ||
>                     $::Variable->{CYBER_ID}
>                     or return undef;
> 	}
>
> 	if(! $secret) {
>         $secret  =  $::Variable->{MV_PAYMENT_SECRET} ||
>                     $::Variable->{CYBER_SECRET}
>                     or return undef;
>     }
>
>     my $server  =   $::Variable->{MV_PAYMENT_SERVER} ||
>                     $::Variable->{CYBER_SERVER} ||
>                     'secure.authorize.net';
>
>     my $script 	=   $::Variable->{MV_PAYMENT_SCRIPT} ||
>                     $::Variable->{CYBER_SCRIPT} ||
>                     '/gateway/transact.dll';
>
>     my $port    =   $::Variable->{MV_PAYMENT_PORT} ||
>                     $::Variable->{CYBER_PORT} ||
>                     443;
>
> 	my $precision = $::Variable->{MV_PAYMENT_PRECISION} ||
>                     $::Variable->{CYBER_PRECISION} ||
>                     2;
> 	my $referer   = $::Variable->{MV_PAYMENT_REFERER};
>
> 	$actual{mv_credit_card_exp_month} =~ s/\D//g;
>     $actual{mv_credit_card_exp_month} =~ s/^0+//;
>     $actual{mv_credit_card_exp_year} =~ s/\D//g;
>     $actual{mv_credit_card_exp_year} =~ s/\d\d(\d\d)/$1/;
>
>     $actual{mv_credit_card_number} =~ s/\D//g;
>
>     my $exp = sprintf '%02d%02d',
>                         $actual{mv_credit_card_exp_month},
>                         $actual{mv_credit_card_exp_year};
>
> 	 $actual{cyber_mode} = 'AUTH_CAPTURE'
>         unless $actual{cyber_mode};
>
> 	my %type_map = (
> 		mauth_capture 			=>	'AUTH_CAPTURE',
> 		mauthonly				=>	'AUTH_ONLY',
> 		CAPTURE_ONLY			=>  'CAPTURE_ONLY',
> 		CREDIT					=>	'CREDIT',
> 		VOID					=>	'VOID',
> 		PRIOR_AUTH_CAPTURE		=>
> 'PRIOR_AUTH_CAPTURE',
>
> 	);
>
> 	if (defined $type_map{$actual{cyber_mode}}) {
>         $actual{cyber_mode} = $type_map{$actual{cyber_mode}};
>     }
>     else {
>         $actual{cyber_mode} = 'AUTH_CAPTURE';
>     }
>
>     if(! $amount) {
>         $amount = Vend::Interpolate::total_cost();
>         $amount = sprintf("%.${precision}f", $amount);
>     }
>
>     my($orderID);
>     my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
> gmtime(time());
>
>     # We'll make an order ID based on date, time, and MiniVend session
>
>     # $mon is the month index where Jan=0 and Dec=11, so we use
>     # $mon+1 to get the more familiar Jan=1 and Dec=12
>     $orderID = sprintf("%02d%02d%02d%02d%02d%05d%s",
>             $year + 1900,$mon + 1,$mday,$hour,$min,$Vend::SessionName);
>
>     my %query = (
>                     x_Card_Num		=>
> $actual{mv_credit_card_number},
>                     x_First_Name        => $actual{b_fname},
>                     x_Last_Name         => $actual{b_lname},
>                     x_Address           => $actual{b_address1},
>                     x_City              => $actual{b_city},
>                     x_State             => $actual{b_state},
>                     x_Zip		=> $actual{b_zip},
>                     x_Type		=> $actual{mv_payment_mode},
>                     x_Amount    	=> $amount,
>                     x_Exp_Date  	=> $exp,
>                     x_Method    	=> 'CC',
>                     x_Invoice_Num       => $actual{mv_order_number},
> #                    x_Company           => $actual{company},
> #                    x_Phone             => $actaul{day_phone},
>                     x_Password  	=> $secret,
>                     x_Login     	=> $user,
>                     x_Version   	=> '3.0',
>                     x_ADC_URL   	=> 'FALSE',
>                     x_ADC_Delim_Data	=> 'TRUE',
>
>
>     );
>
>     my @query;
>
>     for (keys %query) {
>         my $key = $_;
>         my $val = $query{$key};
>         $val =~ s/["\$\n\r]//g;
>         $val =~ s/\$//g;
>         my $len = length($val);
>         if($val =~ /[&=]/) {
>             $key .= "[$len]";
>         }
>         push @query, "$key=$val";
>     }
>     my $string = join '&', @query;
>
>     use Net::SSLeay qw(post_https make_form make_headers);
>
>     my ($page, $response, %reply_headers)
>                 = post_https($server, $port, $script,
>                 	   make_headers( Referer => $referer),
>                        make_form(
>                                %query
>                        ));
>
>     # Minivend names are on the  left, Authorize.Net on the right
>     my %result_map = ( qw/
>             MStatus               x_response_code
>             pop.status            x_response_code
>             MErrMsg               x_response_reason_text
>             pop.error-message     x_response_reason_text
>             order-id              x_trans_id
>             pop.order-id          x_trans_id
>             pop.auth-code         x_auth_code
>             pop.avs_code          x_avs_code
>             pop.avs_zip           x_zip
>             pop.avs_addr          x_address
>     /
>     );
>
>
> #::logError(qq{\nauthorizenet page: $page response: $response\n});
>
>     my ($response_code,
>     	$response_subcode,
>     	$response_reason_code,
>     	$response_reason_text,
>     	$auth_code,
>     	$avs_code,
>     	$trans_id) = split (/,/,$page);
>
> #::logError(qq{authorizenet response_reason_text=$response_reason_text
> response_code: $response_code});
>
>     my %result;
>     if ($response_code == 1) {
>     	$result{MStatus} = 'success';
>     	$result{'order-id'} = 1; # ? Why this this set to 1? -mark
>     } else {
>     	$result{MStatus} = 'failure';
>
> 		# NOTE: A lot more AVS codes could be checked for here.
>     	if ($avs_code eq 'N') {
>     		$result{MErrMsg} = "You must enter the correct
> billing address of your
> credit card. The bank returned the following error: " .
> $response_reason_text;
>     	} else {
>     		$result{MErrMsg} = "$response_reason_text" ;
> 			my $msg = errmsg("Authorizenet error: %s.
> Please call in your order or
> try again.",
> 					$response_reason_text,
> 					);
>     	}
>     }
>
>     return (%result);
>
> }
> EOS
>
> This is located in /usr/lib/interchange/eg/globalsub
>
> I've followed Mike's directions in this file and added the needed lines to
> interchange.cfg and catalog.cfg
>
> Please help ASAP as I am past deadline!
> Robert
>
> -----Original Message-----
> From: interchange-users-admin@developer.akopia.com
> [mailto:interchange-users-admin@developer.akopia.com]On Behalf Of Robert
> Trembath
> Sent: Friday, June 08, 2001 10:13 AM
> To: interchange-users@developer.akopia.com
> Subject: RE: [ic] How do I get the errors to show on CC processing with
> Authorize.net
>
>
>
> Did some searching through the list made some changes that Mike
> mentioned in
> a previous post to variables in the authorizenet page on the x_address and
> x_zip lines. But still encountering a problem.
> Please Help!
> Robert
>
> -----Original Message-----
> From: interchange-users-admin@developer.akopia.com
> [mailto:interchange-users-admin@developer.akopia.com]On Behalf Of Robert
> Trembath
> Sent: Friday, June 08, 2001 8:52 AM
> To: interchange-users@developer.akopia.com
> Subject: [ic] How do I get the errors to show on CC processing with
> Authorize.net
>
>
> Good morning everyone,
> A small question, I don't seem to be getting any error messages back from
> authorize.net if a card doen't go through. Any time I try to use a credir
> card I get redirected back to the payment screen and it says my
> errors will
> be in red, although there are no errors in red!
> If I use a different payment type it goes through just fine.
>
> So I need to see what errors are coming back from authorize.net
> or what else
> might be stopping the process.
>
> Thanks,
> Robert
>
> _______________________________________________
> Interchange-users mailing list
> Interchange-users@lists.akopia.com
> http://lists.akopia.com/mailman/listinfo/interchange-users
>
> _______________________________________________
> Interchange-users mailing list
> Interchange-users@lists.akopia.com
> http://lists.akopia.com/mailman/listinfo/interchange-users
>
> _______________________________________________
> Interchange-users mailing list
> Interchange-users@lists.akopia.com
> http://lists.akopia.com/mailman/listinfo/interchange-users

_______________________________________________
Interchange-users mailing list
Interchange-users@lists.akopia.com
http://lists.akopia.com/mailman/listinfo/interchange-users