X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=PayflowPro.pm;h=b8415b923fb74155cfe3239294ce3d285a01c095;hb=3f274c8db4116da8e5db9fc54ba79de77d48de24;hp=05cdb6ba78a438184afcc3a525b396285121f298;hpb=e7a92c02f33e9541f6817f00172c9518271aad91;p=Business-OnlinePayment-PayflowPro.git diff --git a/PayflowPro.pm b/PayflowPro.pm index 05cdb6b..b8415b9 100644 --- a/PayflowPro.pm +++ b/PayflowPro.pm @@ -17,84 +17,91 @@ sub set_defaults { $self->server('payflow.verisign.com'); $self->port('443'); - $self->build_subs(qw( - vendor partner cert_path order_number avs_code cvv2_code - )); + $self->build_subs( + qw( + vendor partner cert_path order_number avs_code cvv2_code + ) + ); } sub map_fields { - my($self) = @_; + my ($self) = @_; my %content = $self->content(); #ACTION MAP - my %actions = ('normal authorization' => 'S', # Sale transaction - 'credit' => 'C', # Credit (refund) - 'authorization only' => 'A', # Authorization - 'post authorization' => 'D', # Delayed Capture - 'void' => 'V', # Void - ); - $content{'action'} = $actions{lc($content{'action'})} || $content{'action'}; + my %actions = ( + 'normal authorization' => 'S', # Sale transaction + 'credit' => 'C', # Credit (refund) + 'authorization only' => 'A', # Authorization + 'post authorization' => 'D', # Delayed Capture + 'void' => 'V', # Void + ); + + $content{'action'} = $actions{ lc( $content{'action'} ) } + || $content{'action'}; # TYPE MAP - my %types = ('visa' => 'C', - 'mastercard' => 'C', - 'american express' => 'C', - 'discover' => 'C', - 'cc' => 'C', - #'check' => 'ECHECK', - ); - $content{'type'} = $types{lc($content{'type'})} || $content{'type'}; - $self->transaction_type($content{'type'}); + my %types = ( + 'visa' => 'C', + 'mastercard' => 'C', + 'american express' => 'C', + 'discover' => 'C', + 'cc' => 'C', + #'check' => 'ECHECK', + ); + + $content{'type'} = $types{ lc( $content{'type'} ) } || $content{'type'}; + + $self->transaction_type( $content{'type'} ); # stuff it back into %content $self->content(%content); } sub remap_fields { - my($self,%map) = @_; + my ( $self, %map ) = @_; my %content = $self->content(); - foreach(keys %map) { - $content{$map{$_}} = $content{$_}; + foreach ( keys %map ) { + $content{ $map{$_} } = $content{$_}; } $self->content(%content); } sub revmap_fields { - my($self, %map) = @_; + my ( $self, %map ) = @_; my %content = $self->content(); - foreach(keys %map) { -# warn "$_ = ". ( ref($map{$_}) -# ? ${ $map{$_} } -# : $content{$map{$_}} ). "\n"; - $content{$_} = ref($map{$_}) - ? ${ $map{$_} } - : $content{$map{$_}}; + foreach ( keys %map ) { + $content{$_} = + ref( $map{$_} ) + ? ${ $map{$_} } + : $content{ $map{$_} }; } $self->content(%content); } sub submit { - my($self) = @_; + my ($self) = @_; $self->map_fields(); my %content = $self->content; - my($month, $year, $zip); + my ( $month, $year, $zip ); if ( $self->transaction_type() ne 'C' ) { - croak("PayflowPro can't (yet?) handle transaction type: " . - $self->transaction_type()); + croak( "PayflowPro can't (yet?) handle transaction type: " + . $self->transaction_type() ); } - if ( defined($content{'expiration'}) && length($content{'expiration'}) ) { + if ( defined( $content{'expiration'} ) && length( $content{'expiration'} ) ) + { $content{'expiration'} =~ /^(\d+)\D+\d*(\d{2})$/ - or croak "unparsable expiration $content{expiration}"; + or croak "unparsable expiration $content{expiration}"; ( $month, $year ) = ( $1, $2 ); - $month = '0'. $month if $month =~ /^\d$/; + $month = '0' . $month if $month =~ /^\d$/; } ( $zip = $content{'zip'} ) =~ s/\D//g; @@ -102,88 +109,97 @@ sub submit { $self->server('test-payflow.verisign.com') if $self->test_transaction; $self->revmap_fields( - # (BUG?) VENDOR B::OP:PayflowPro < 0.05 backward compatibility. If - # vendor not set use login (although test indicate undef vendor is ok) - VENDOR => $self->vendor ? \( $self->vendor ) : 'login', - PARTNER => \( $self->partner ), - USER => 'login', - PWD => 'password', - TRXTYPE => 'action', - TENDER => 'type', - ORIGID => 'order_number', - COMMENT1 => 'description', - COMMENT2 => 'invoice_number', - ACCT => 'card_number', - CVV2 => 'cvv2', - EXPDATE => \( $month.$year ), # MM/YY from 'expiration' - AMT => 'amount', - - FIRSTNAME => 'first_name', - LASTNAME => 'last_name', - NAME => 'name', - EMAIL => 'email', - COMPANYNAME => 'company', - STREET => 'address', - CITY => 'city', - STATE => 'state', - ZIP => \$zip, # 'zip' with non-numbers removed - COUNTRY => 'country', + # (BUG?) VENDOR B::OP:PayflowPro < 0.05 backward compatibility. If + # vendor not set use login (although test indicate undef vendor is ok) + VENDOR => $self->vendor ? \( $self->vendor ) : 'login', + PARTNER => \( $self->partner ), + USER => 'login', + PWD => 'password', + TRXTYPE => 'action', + TENDER => 'type', + ORIGID => 'order_number', + COMMENT1 => 'description', + COMMENT2 => 'invoice_number', + + ACCT => 'card_number', + CVV2 => 'cvv2', + EXPDATE => \( $month . $year ), # MM/YY from 'expiration' + AMT => 'amount', + + FIRSTNAME => 'first_name', + LASTNAME => 'last_name', + NAME => 'name', + EMAIL => 'email', + COMPANYNAME => 'company', + STREET => 'address', + CITY => 'city', + STATE => 'state', + ZIP => \$zip, # 'zip' with non-numbers removed + COUNTRY => 'country', ); my @required = qw( TRXTYPE TENDER PARTNER VENDOR USER PWD ); - if ( $self->transaction_type() eq 'C' ) { #credit card - if ( $content{'action'} =~ /^[CDV]$/ - && defined($content{'ORIGID'}) - && length($content{'ORIGID'}) - ) - { - push @required, qw(ORIGID); - } else { - # not currently supported, we croak above if transaction_type ne 'C' - push @required, qw(AMT ACCT EXPDATE); - } + if ( $self->transaction_type() eq 'C' ) { # credit card + if ( $content{'action'} =~ /^[CDV]$/ + && defined( $content{'ORIGID'} ) + && length( $content{'ORIGID'} ) ) + { + push @required, qw(ORIGID); + } + else { + # never get here, we croak above if transaction_type ne 'C' + push @required, qw(AMT ACCT EXPDATE); + } } $self->required_fields(@required); - my %params = $self->get_fields(qw( - VENDOR PARTNER USER PWD TRXTYPE TENDER ORIGID COMMENT1 COMMENT2 - ACCT CVV2 EXPDATE AMT - FIRSTNAME LASTNAME NAME EMAIL COMPANYNAME STREET CITY STATE ZIP COUNTRY - )); + my %params = $self->get_fields( + qw( + VENDOR PARTNER USER PWD TRXTYPE TENDER ORIGID COMMENT1 COMMENT2 + ACCT CVV2 EXPDATE AMT + FIRSTNAME LASTNAME NAME EMAIL COMPANYNAME + STREET CITY STATE ZIP COUNTRY + ) + ); $ENV{'PFPRO_CERT_PATH'} = $self->cert_path; - my( $response, $resultstr ) = pfpro( \%params, $self->server, $self->port ); - # PNREF (aka transaction id) is set on success and failure - $self->order_number( $response->{'PNREF'} ); + my ( $response, $resultstr ) = + pfpro( \%params, $self->server, $self->port ); # AVS and CVS values may be set on success or failure my $avs_code; if ( exists $response->{AVSADDR} || exists $response->{AVSZIP} ) { - if ( $response->{AVSADDR} eq 'Y' && $response->{AVSZIP} eq 'Y' ) { - $avs_code = 'Y'; - } elsif ( $response->{AVSADDR} eq 'Y' ) { - $avs_code = 'A'; - } elsif ( $response->{AVSZIP} eq 'Y' ) { - $avs_code = 'Z'; - } elsif ( $response->{AVSADDR} eq 'N' || $response->{AVSZIP} eq 'N' ) { - $avs_code = 'N'; - } else { - $avs_code = ''; - } + if ( $response->{AVSADDR} eq 'Y' && $response->{AVSZIP} eq 'Y' ) { + $avs_code = 'Y'; + } + elsif ( $response->{AVSADDR} eq 'Y' ) { + $avs_code = 'A'; + } + elsif ( $response->{AVSZIP} eq 'Y' ) { + $avs_code = 'Z'; + } + elsif ( $response->{AVSADDR} eq 'N' || $response->{AVSZIP} eq 'N' ) { + $avs_code = 'N'; + } + else { + $avs_code = ''; + } } $self->avs_code($avs_code); - $self->cvv2_code($response->{'CVV2MATCH'}); - $self->result_code($response->{'RESULT'}); - $self->error_message($response->{'RESPMSG'}); - $self->authorization($response->{'AUTHCODE'}); + $self->cvv2_code( $response->{'CVV2MATCH'} ); + $self->result_code( $response->{'RESULT'} ); + $self->order_number( $response->{'PNREF'} ); + $self->error_message( $response->{'RESPMSG'} ); + $self->authorization( $response->{'AUTHCODE'} ); # RESULT must be an explicit zero, not just numerically equal if ( $response->{'RESULT'} eq '0' ) { - $self->is_success(1); - } else { - $self->is_success(0); + $self->is_success(1); + } + else { + $self->is_success(0); } } @@ -420,10 +436,12 @@ response message returned with the transaction result. This module implements an interface to the Payflow Pro Perl API, which can be downloaded at https://manager.paypal.com/ with a valid login. -=head1 AUTHOR +=head1 AUTHORS Ivan Kohler +Phil Lobbes Ephil at perkpartners.comE + Based on Business::OnlinePayment::AuthorizeNet written by Jason Kohles. =head1 SEE ALSO