From 237c409621598baa378402a74a389049790c0d41 Mon Sep 17 00:00:00 2001 From: khoff Date: Mon, 9 Sep 2002 19:14:45 +0000 Subject: [PATCH] initial release --- MANIFEST | 2 + Makefile.PL | 9 +++ Skipjack.pm | 221 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 232 insertions(+) create mode 100644 MANIFEST create mode 100644 Makefile.PL create mode 100644 Skipjack.pm diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..18ea7b2 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,2 @@ +Skipjack.pm +MANIFEST diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..6f2ee31 --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,9 @@ +use ExtUtils::MakeMaker; +WriteMakefile( + 'NAME' => 'Business::OnlinePayment::Skipjack', + 'VERSION_FROM' => 'Skipjack.pm', + 'AUTHOR' => 'See README', + 'PREREQ_PM' => {'Net::SSLeay' => 0, 'Text::CSV' => 0, + 'Business::OnlinePayment' => 0}, + 'dist' => {CI => 'ci -l'}, +); diff --git a/Skipjack.pm b/Skipjack.pm new file mode 100644 index 0000000..6719cbf --- /dev/null +++ b/Skipjack.pm @@ -0,0 +1,221 @@ +## Business::OnlinePayment::Skipjack +## +## Original Skipjack.pm developed by New York Connect Net (http://nyct.net) +## Michael Bacarella +## +## Modified for GetCareer.com by Slipstream.com +## Troy Davis +## +## 'Adapted' (completely rewritten) for Business::OnlinePayment +## by Fire2Wire Internet Services (http://www.fire2wire.com) +## Mark Wells +## Kristian Hoffmann +## James Switzer + +## Required packages: +## Net::SSLeay +## Text::CSV +## Business::OnlinePayment + + +package Business::OnlinePayment::Skipjack; + +use strict; +use Business::OnlinePayment; +use Net::SSLeay qw(post_https make_form); +use Text::CSV; +use vars qw(@ISA @EXPORT @EXPORT_OK); + +#$VERSION="0.1"; + +require Exporter; + +@ISA = qw(Exporter AutoLoader Business::OnlinePayment); +# Items to export into callers namespace by default. Note: do not export +# names by default without a very good reason. Use EXPORT_OK instead. +# Do not simply export all your public functions/methods/constants. +@EXPORT = qw(); +@EXPORT_OK = qw(); + +my %CC_ERRORS = ( + '-1' => 'Invalid length (-1)', + '-35' => 'Invalid credit card number (-35)', + '-37' => 'Failed communication (-37)', + '-39' => 'Serial number is too short (-39)', + '-51' => 'The zip code is invalid', + '-52' => 'The shipto zip code is invalid', + '-53' => 'Length of expiration date (-53)', + '-54' => 'Length of account number date (-54)', + '-55' => 'Length of street address (-55)', + '-56' => 'Length of shipto street address (-56)', + '-57' => 'Length of transaction amount (-57)', + '-58' => 'Length of name (-58)', + '-59' => 'Length of location (-59)', + '-60' => 'Length of state (-60)', + '-61' => 'Length of shipto state (-61)', + '-62' => 'Length of order string (-62)', + '-64' => 'Invalid phone number (-64)', + '-65' => 'Empty name (-65)', + '-66' => 'Empty email (-66)', + '-67' => 'Empty street address (-66)', + '-68' => 'Empty city (-68)', + '-69' => 'Empty state (-69)', + '-70' => 'Empty zip code (-70)', + '-71' => 'Empty order number (-71)', + '-72' => 'Empty account number (-72)', + '-73' => 'Empty expiration month (-73)', + '-74' => 'Empty expiration year (-74)', + '-75' => 'Empty serial number (-75)', + '-76' => 'Empty transaction amount (-76)', + '-79' => 'Length of customer name (-79)', + '-80' => 'Length of shipto customer name (-80)', + '-81' => 'Length of customer location (-81)', + '-82' => 'Length of customer state (-82)', + '-83' => 'Length of shipto phone (-83)', + '-84' => 'Pos Error duplicate ordernumber (-84)', + '-91' => 'Pos Error CVV2 (-91)', + '-92' => 'Pos Error Approval Code (-92)', + '-93' => 'Pos Error Blind Credits Not Allowed (-93)', + '-94' => 'Pos Error Blind Credits Failed (-94)', + '-95' => 'Pos Error Voice Authorizations Not Allowed (-95)', + ); + +my %AVS_CODES = ( + 'X' => 'Exact match, 9 digit zip', + 'Y' => 'Exact match, 5 digit zip', + 'A' => 'Address match only', + 'W' => '9 digit match only', + 'Z' => '5 digit match only', + 'N' => 'No address or zip match', + 'U' => 'Address unavailable', + 'R' => 'Issuer system unavailable', + 'E' => 'Not a mail/phone order', + 'S' => 'Service not supported' + ); + +my %FIELDS = ( + name => 'sjname', + email => 'Email', + address => 'Streetaddress', + city => 'City', + state => 'State', + zip => 'Zipcode', + invoice_number => 'Ordernumber', + card_number => 'Accountnumber', + exp_month => 'Month', + exp_year => 'Year', + amount => 'Transactionamount', + orderstring => 'Orderstring', + phone => 'Shiptophone', + login => 'Serialnumber', + ); + + +sub _gen_ordernum { return int(rand(4000000000)); } + +sub set_defaults +{ + my $self = shift; + + # For production + $self->server('www.skipjackic.com'); + $self->path('/scripts/evolvcc.dll?AuthorizeAPI'); + + # For auth testing + #$self->server('developer.skipjackic.com'); # test mode + #$self->path('/scripts/evolvcc.dll?AuthorizeAPI'); + + # For comms testing + #$self->server('www.skipjackic.com'); + #$self->path('/secure/echo.asp'); + + $self->port(443); + + return; +} + + +sub submit +{ + my $self = shift; + my %c = $self->content; + my (%input, %output); + my ($page, $response, %reply_headers); + +# if($c{type} and $c{type} ne 'normal authorization') { + if($c{type} eq 'credit') { + warn 'Business::OnlinePayment::Skipjack does not support "' . + $c{type}. '"transactions'; + return; + } + + # FIXME! + # This should be set from %processor_info. + + # Or, if we want, from $c{login}. + + $c{expiration} =~ /(\d\d?).*(\d\d?)/; # extremely crude way to split the month and year + $c{exp_month} = sprintf('%02d',$1); + $c{exp_year} = sprintf('%02d',$2); + + $c{invoice_number} = _gen_ordernum unless $c{invoice_number}; + + $c{orderstring} = '0~'.$c{description}.'~'.$c{amount}.'~1~N~||' + unless $c{orderstring}; + + %input = map { ($FIELDS{$_} || $_), $c{$_} } keys(%c); + + ($page, $response, %reply_headers) = + post_https($self->server, + $self->port, + $self->path, + '', + make_form(%input)); + + + %output = parse_Authorize_API($page); + + $self->{_result} = \%output; + $self->authorization($output{'AUTHCODE'}); + return; +} + +sub is_success +{ + my $self = shift; + + return ($self->{_result}->{'szIsApproved'} == 1); +} + +sub error_message +{ + my $self = shift; + my $r; + + if($self->is_success) { return ''; } + if(($r = $self->{_result}->{'szReturnCode'}) < 0) { return $CC_ERRORS{$r}; } + if($r = $self->{_result}->{'szAVSResponseMessage'}) { return $r; } + if($r = $self->{_result}->{'szAuthorizationDeclinedMessage'}) { return $r; } +} + +sub parse_Authorize_API +{ + + my $page = shift; + my %output; + my $csv_keys = new Text::CSV; + my $csv_values = new Text::CSV; + + my ($keystring, $valuestring) = split(/\r\n/, $page); + $csv_keys->parse($keystring); + $csv_values->parse($valuestring); + @output{$csv_keys->fields()} = $csv_values->fields(); + + return %output; + +} + +__END__ + +1; + -- 2.11.0