failure_status support
[Business-OnlinePayment-PaymenTech.git] / lib / Business / OnlinePayment / PaymenTech.pm
index 52977f8..5ae91b7 100644 (file)
@@ -8,7 +8,10 @@ use Tie::IxHash;
 use vars qw($VERSION $DEBUG @ISA $me);
 
 @ISA = qw(Business::OnlinePayment::HTTPS);
-$VERSION = '2.03_03';
+
+$VERSION = '2.05';
+$VERSION = eval $VERSION; # modperlstyle: convert the string into a number
+
 $DEBUG = 0;
 $me='Business::OnlinePayment::PaymenTech';
 
@@ -39,6 +42,7 @@ tie my %new_order, 'Tie::IxHash', (
   AVSaddress1               => [ ':address', 30 ],
   AVScity                   => [ ':city', 20 ],
   AVSstate                  => [ ':state', 2 ],
+  AVScountryCode            => [ ':country', 2 ],
   OrderID                   => [ ':invoice_number', 22 ], 
   Amount                    => [ ':amount', 12 ],
   Comments                  => [ ':email', 64 ],
@@ -93,6 +97,34 @@ my %currency_code = (
   MXN => [484, 2],
 );
 
+my %paymentech_countries = map { $_ => 1 } qw( US CA GB UK );
+my %failure_status = (
+  # values of the RespCode element
+  # in theory RespMsg should be set to a descriptive message, but it looks
+  # like that's not reliable
+  # XXX we should have a way to indicate other actions required by the 
+  # processor, such as "honor with identification", "call for instructions",
+  # etc.
+  '00'  => undef,         # Approved
+  '04'  => 'pickup',      # Pickup
+  '33'  => 'expired',     # Card is Expired
+  '41'  => 'stolen',      # Lost/Stolen
+  '42'  => 'inactive',    # Account Not Active
+  '43'  => 'stolen',      # Lost/Stolen Card
+  '44'  => 'inactive',    # Account Not Active
+  #'45' duplicate transaction, should also have its own status
+  'B7'  => 'blacklisted', # Fraud
+  'B9'  => 'blacklisted', # On Negative File
+  'BB'  => 'stolen',      # Possible Compromise
+  'BG'  => 'blacklisted', # Blocked Account
+  'BQ'  => 'blacklisted', # Issuer has Flagged Account as Suspected Fraud
+  'C4'  => 'nsf',         # Over Credit Limit
+  'D5'  => 'blacklisted', # On Negative File
+  'D7'  => 'nsf',         # Insufficient Funds
+  'F3'  => 'inactive',    # Account Closed
+  'K6'  => 'nsf',         # NSF
+);
+
 sub set_defaults {
     my $self = shift;
 
@@ -190,7 +222,15 @@ sub map_fields {
       $content{invoice_number} ||= sprintf("%04x%04x",time % 2**16,int(rand() * 2**16));
     }
 
-    $content{expiration} =~ s/\D//g; # Because Freeside sends it as mm/yy, not mmyy.
+    # Always send as MMYY
+    $content{expiration} =~ s/\D//g; 
+    $content{expiration} = sprintf('%04d',$content{expiration});
+
+    $content{country} ||= 'US';
+    $content{country} = ( $paymentech_countries{ $content{country} }
+                            ? $content{country}
+                            : ''
+                        ),
 
     $self->content(%content);
     return;
@@ -290,6 +330,7 @@ sub submit {
             )
     {
 
+      $self->failure_status( $failure_status{ $r->{RespCode} } || 'decline' );
       $self->is_success(0);
       $self->error_message( "Transaction error: '".
                             ($r->{'ProcStatusMsg'} || $r->{'StatusMsg'}) . "'"