[ic] GlobalSub for external payment gateway

Jacob =?iso-8859-1?Q?S=F6nnichsen?= Jacob.Sonnichsen@get2net.dk
Sat, 28 Apr 2001 23:09:51 +0200


I have made a small script for connecting to an external payment
gateway, but I keep getting this error in the error.log:
192.168.1.3 moyZKNyi:192.168.1.3 - [02/May/2001:17:36:27 +0200]
Privat-Shop /cgi-bin/Privat-Shop/process.html bad custom payment
GlobalSub: external

Can someone give me a clue to what is going wrong?

This is my script :

# Connection routine for External payment gateway
#
# by Jacob Sonnichsen, Virus Consult <VirusConsult@mail.com> with reused
code by
#  mark@summersault.com
# Mike Heins <mike@minivend.com>
# webmaster@nameastar.net
# Jeff Nappi <brage@cyberhighway.net>
# Paul Delys <paul@gi.alaska.edu>

Variable EXTERNAL_HELP <<EOV

 1. Modify interchange.cfg to use this file.

 #include globalsub/external

 2. Modify catalog.cfg to set the server and your Merchant ID


 # Username and password
 Variable MV_PAYMENT_MERCHANT Your Merchant Number
 Variable MV_PAYMENT_SECRET  Your Gateway Password
 Variable MV_PAYMENT_MODE    custom external
 Variable MV_PAYMENT_REFERER A valid referering url
 Variable MV_PAYMENT_SERVER  A valid url to payment gateway
 Variable MV_PAYMENT_CURRENCY Currency (208=DK)

 3. Make sure CreditCardAuto is off (default in Interchange demos)

 4. Copy ccfail.html and ccok.html to your interchange catalog pages

 5. Restart Interchange.

EOV

GlobalSub <<EOS
sub external {
 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}
                    or return undef;

    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};

    my $ccOK = sprintf ('%s%s',$SecureURL,'/ccok.html');
    my $ccFAIL = sprintf ('%s%s',$SecureURL,'/ccfail.html');


  $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_Merchantnumber => $actual{mv_payment_merchant},
                    x_CardNumber => $actual{mv_credit_card_number},
#                    x_First_Name        => $actual{b_fname},
#                    x_Last_Name         => $actual{b_lname},
#                    x_Address           => $actual{address},
#                    x_City              => $actual{b_city},
#                    x_State             => $actual{b_state},
#                    x_Zip  => $actual{zip},
#                    x_Type  => $actual{mv_payment_mode},
                    x_Amount     => $amount,
      x_Currency  => $actual{mv_payment_currency},
      x_Expiremonth => $actual{mv_credit_card_exp_month},
      x_Expireyear => $actual{mv_credit_card_exp_year},
#                    x_Exp_Date   => $exp,
#                    x_Method     => 'CC',
      x_Ordernumber => $actual{mv_order_number},
      x_AcceptURL  => $ccOK,
      x_DeclineURL => $ccFAIL,
#                    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"
     }
    }

    return (%result);

}
EOS