0.08 Suppress elipsis character from strings truncated by Truncate::Unicode
[Business-BatchPayment-Paymentech.git] / Paymentech.pm
index 19277cc..0743bba 100644 (file)
@@ -3,7 +3,9 @@ package Business::BatchPayment::Paymentech;
 use 5.006;
 use strict;
 use warnings;
-our $VERSION = '0.03';
+our $VERSION = '0.08';
+
+use Unicode::Truncate 'truncate_egc';
 
 =head1 NAME
 
@@ -26,6 +28,7 @@ my $processor = Business::BatchPayment->processor('Paymentech',
   industryType  => 'EC'
   login         => 'TESTUSER',
   password      => 'MYPASS',
+  with_recurringInd  => 1,
 );
 
 my $result = $processor->submit(@items);
@@ -51,6 +54,8 @@ unzip programs.  Unlikely to work on non-Unix systems.
 
 =item industryType - your 2-letter industry type code
 
+=item with_recurringInd - enable the recurring charge indicator field
+
 =back
 
 =cut
@@ -65,6 +70,8 @@ use Moose;
 with 'Business::BatchPayment::Processor';
 with 'Business::BatchPayment::TestMode';
 
+use Encode;
+
 # could have some validation on all of these
 has [ qw(merchantID terminalID bin industryType login password) ] => (
   is       => 'ro',
@@ -72,6 +79,12 @@ has [ qw(merchantID terminalID bin industryType login password) ] => (
   required => 1,
 );
 
+has 'with_recurringInd' => (
+  is      => 'ro',
+  isa     => 'Bool',
+  default => 0,
+);
+
 has 'fileDateTime' => (
   is      => 'ro',
   isa     => 'Str',
@@ -108,6 +121,7 @@ sub format_request {
     OUTPUT      => \$output,
     DATA_MODE   => 1,
     DATA_INDENT => 2,
+    ENCODING    => 'utf-8',
   );
   $self->format_header($batch, $xml);
   my $count = 1;
@@ -127,6 +141,7 @@ sub format_header {
   my ($self, $batch, $xml) = @_;
   my $num_items = $batch->count;
 
+  $xml->xmlDecl();
   $xml->startTag('transRequest', RequestCount => $num_items + 1);
   $xml->startTag('batchFileID');
   $xml->dataElement(userID => $self->login);
@@ -148,12 +163,13 @@ sub format_item {
       terminalID   => $self->terminalID,
     );
     if ($item->payment_type eq 'CC') {
+      my $expiration = $item->expiration;
+      $expiration =~ s/\D//g;
       push @order, (
         ccAccountNum => $item->card_number,
-        ccExp        => $item->expiration,
+        ccExp        => $expiration,
       );
-    }
-    elsif ( $item->payment_type eq 'ECHECK' ) {
+    } elsif ( $item->payment_type eq 'ECHECK' ) {
       push @order, (
         cardBrand       => 'EC',
         ecpCheckRT      => $item->routing_code,
@@ -161,17 +177,26 @@ sub format_item {
         ecpBankAcctType => $BankAcctType{ $item->account_type },
         ecpDelvMethod   => 'A',
       );
-    }
-    else {
+    } else {
       die "payment type ".$item->type." not supported";
     }
-    push @order, (
-      avsZip         => $item->zip,
-      avsAddress1    => substr($item->address,   0, 30),
-      avsAddress2    => substr($item->address2,  0, 30),
-      avsCity        => substr($item->city,      0, 20),
-      avsState       => substr($item->state,     0, 2),
-      avsName        => substr($item->first_name. ' '. $item->last_name, 0, 30),
+    if ( $self->with_recurringInd ) {
+      if ( $item->recurring_billing eq 'F' ) {
+        push @order, ( recurringInd => 'RF' );
+      } elsif ( $item->recurring_billing eq 'S' ) {
+        push @order, ( recurringInd => 'RS' );
+      }
+    } # else don't send recurringInd at all
+
+    push @order, (                   # truncate_egc will die() on empty string
+      avsZip      => $item->zip,
+      avsAddress1 => $item->address  ? truncate_egc($item->address,  30, '') : undef,
+      avsAddress2 => $item->address2 ? truncate_egc($item->address2, 30, '') : undef,
+      avsCity     => $item->city     ? truncate_egc($item->city,     20, '') : undef,
+      avsState    => $item->state    ? truncate_egc($item->state,     2, '') : undef,
+      avsName     => ($item->first_name || $item->last_name)
+                     ? truncate_egc($item->first_name.' '.$item->last_name, 30, '')
+                     : undef,
       ( $paymentech_countries{ $item->country }
         ? ( avsCountryCode  => $item->country )
         : ()
@@ -285,6 +310,20 @@ sub parse_item {
   $item;
 }
 
+# DEPRECATED
+
+# sub bytes_substr {
+#   my ($string, $offset, $length, $repl) = @_;
+#   my $bytes = substr(
+#     Encode::encode('utf8', $string || ''),
+#     $offset,
+#     $length,
+#     Encode::encode('utf8', $repl || '')
+#   );
+#   return Encode::decode('utf8', $bytes, Encode::FB_QUIET);
+# }
+
+
 package Business::BatchPayment::Paymentech::Transport;
 
 use File::Temp qw( tempdir );