RT#42265: Add Authorization Only and Reverse Authorization support to B:OP:vSecurePro...
authorJonathan Prykop <jonathan@freeside.biz>
Mon, 2 May 2016 21:26:46 +0000 (16:26 -0500)
committerJonathan Prykop <jonathan@freeside.biz>
Mon, 2 May 2016 21:26:46 +0000 (16:26 -0500)
Changes
lib/Business/OnlinePayment/vSecureProcessing.pm

diff --git a/Changes b/Changes
index 3639c62..3c95774 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,10 @@
 Revision history for Perl module Business::OnlinePayment::vSecureProcessing
 
+0.10    Mon May  2 16:04:02 CDT 2016
+        - support for Authorization Only & Reverse Authorization
+        - bug fix to _info routine (returns hashref, not hash)
+        - B::OP standard handling of result_code
+
 0.09    Thu Nov  5 10:32:10 PST 2015
         - Pass Cf1/Cf2 for voids and refunds as well
 
index f7d8b9d..0ca96ad 100644 (file)
@@ -11,25 +11,27 @@ use Business::OnlinePayment::HTTPS;
 
 @ISA = qw(Business::OnlinePayment::HTTPS);
 $DEBUG = 0;
-$VERSION = '0.09';
+$VERSION = '0.10';
 
 sub _info {
-  'info_compat'       => '0.01',
-  'gateway_name'      => 'vSecure Processing',
-  'gateway_url'       => 'http://www.vsecureprocessing.com/',
-  'module_version'    => $VERSION,
-  'supported_types'   => [qw( CC )],
-  'token_support'     => 0,
-  'test_transaction'  => 1,
-  'partial_auth'      => 1,
-  'supported_actions' => [
-                           'Normal Authorization',
-                           #'Authorization Only',
-                           #'Post Authorization',
-                           'Reverse Authorization',
-                           'Void',
-                           'Credit',
-                         ],
+  return {
+    'info_compat'       => '0.01',
+    'gateway_name'      => 'vSecure Processing',
+    'gateway_url'       => 'http://www.vsecureprocessing.com/',
+    'module_version'    => $VERSION,
+    'supported_types'   => [qw( CC )],
+    'token_support'     => 0,
+    'test_transaction'  => 1,
+    'partial_auth'      => 1,
+    'supported_actions' => [
+                             'Normal Authorization',
+                             'Authorization Only',
+                             #'Post Authorization',
+                             'Reverse Authorization',
+                             'Void',
+                             'Credit',
+                           ],
+  };
 }
 
 # mapping out all possible endpoints
@@ -64,9 +66,24 @@ my %payment_actions = (
     },
     'authorize' => {
         path      => '/vsg2/processauth',
+        process   => 'ProcessAuth',
+        fields    => [qw(
+          Amount TypeOfSale Cf1 Cf2 Cf3 AccountNumber
+          ExpirationMonth ExpirationYear Cvv
+          CardHolderFirstName CardHolderLastName AvsZip AvsStreet
+          IndustryType ApplicationId
+        )],
+
     },
     'authorize_cancel' => {
         path      => '/vsg2/processauthcancel',
+        process   => 'ProcessAuthCancel',
+        fields    => [qw(
+          Amount AccountNumber
+          ExpirationMonth ExpirationYear
+          ReferenceNumber ResponseCode TransactionDate
+          IndustryType ApplicationId
+        )],
     },
     'capture' => {
         path      => '/vsg2/processcaptureonly',
@@ -114,13 +131,13 @@ sub set_defaults {
     # B::OP creates the following accessors:
     #     server, path, test_transaction, transaction_type,
     #     server_response, is_success, authorization,
-    #     result_code, error_message,
+    #     result_code, error_message, response_code
     
-    $self->build_subs(qw/
+    $self->build_subs( qw(
             platform tid appid
-            action reference_number cvv2_response avs_code response_code
+            action reference_number cvv2_response avs_code
             risk_score txn_amount txn_date partial_auth_amount
-    /);
+    );
     
     $DEBUG = exists($options{debug}) ? $options{debug} : $DEBUG;
     
@@ -210,7 +227,7 @@ sub submit {
       $self->server('dvrotsos2.kattare.com');
     }
     
-    my @acceptable_actions = ('charge', 'refund', 'void');
+    my @acceptable_actions = ('charge', 'refund', 'void', 'authorize', 'authorize_cancel');
     
     unless ( grep { $action eq $_ } @acceptable_actions ) {
         croak "'$action' is not supported at this time.";
@@ -247,10 +264,13 @@ sub submit {
 #                                },
             ApplicationId   => $self->appid(),
             Recurring       => ($content{'recurring_billing'} && $content{'recurring_billing'} eq 'YES' ) ? 1 : 0,
-            ReferenceNumber => ($content{'ref_num'}) ? $content{'ref_num'} : '',
+            ReferenceNumber => ($content{'authorization'}) ? $content{'authorization'} : '',
             Token           => ($content{'token'}) ? $content{'token'} : '',
             Receipt         => ($content{'receipt'}) ? $content{'receipt'} : '',
-            TransactionDate => ($content{'txn_date'}) ? $content{'txn_date'} : ''
+            TransactionDate => ($content{'txn_date'}) ? $content{'txn_date'} : '',
+            # note that B::OP response_code is the http response & message, ie '500 Internal Server Error'
+            # whereas ResponseCode is a 2-digit ISO code indicating result of transaction
+            ResponseCode    => ($content{'result_code'}) ? $content{'result_code'} : '',
         }
         # we won't be using level2 nor level3.  So I'm leaving them out for now.
     };
@@ -277,9 +297,6 @@ sub submit {
         croak "Missing required fields: ".join(', ', @missing_fields);
     }
     
-    my $process_action = $action;
-    $process_action =~ s/\b([a-z])/\u$1/g;
-    $process_action = 'Process'.$process_action;
     my $xml_data;
     my $writer = new XML::Writer( OUTPUT      => \$xml_data,
                                   DATA_MODE   => 0,
@@ -336,7 +353,7 @@ sub submit {
     # parse the result page.
     $self->parse_response($page);
 
-    if ( $self->is_success && $self->response_code == 10 ) { #partial auth
+    if ( $self->is_success && $self->result_code == 10 ) { #partial auth
 
       if ( $content{'partial_auth'} ) {
 
@@ -381,9 +398,9 @@ sub submit {
               "(Raw HTTPS content: ".$page.")"
             );
         } else {
-            my $response_code = $self->response_code() || '';
-            if ($response_code) {
-                $self->error_message(qq|Error code ${response_code} was returned by vSecureProcessing. (enable debugging for raw HTTPS response)|);
+            my $result_code = $self->result_code() || '';
+            if ($result_code) {
+                $self->error_message(qq|Error code ${result_code} was returned by vSecureProcessing. (enable debugging for raw HTTPS response)|);
             }else {
                 $self->error_message('No error information was returned by vSecureProcessing (enable debugging for raw HTTPS response)');
             }
@@ -400,8 +417,8 @@ sub parse_response {
     if ($self->server_response =~ /^200/) {
         my $response = XMLin($page);
         warn "Response:\n".Dumper($response)."\n" if $DEBUG > 2;
-        $self->result_code($response->{Status}); # 0 /1
-        $self->response_code($response->{ResponseCode}); # see documentation for translation
+        $self->is_success($response->{Status} ? 0 : 1);
+        $self->result_code($response->{ResponseCode}); # NOT response_code, which is http response
         $self->avs_code($response->{AvsResponse}); # Y / N
 
         #weird (missing?) gateway responses turn into a hashref screwing up Card Fortress
@@ -412,9 +429,9 @@ sub parse_response {
 
         $self->txn_date($response->{TransactionDate}); # MMDDhhmmss
         $self->txn_amount($response->{TransactionAmount} / 100); # 00000003500 / 100
-        $self->reference_number($response->{ReferenceNumber});
+        $self->reference_number($response->{ReferenceNumber}); # overlap with authorization, 
+                                                               # not used by anything or documented???
         
-        $self->is_success($self->result_code() eq '0' ? 1 : 0);
         if ($self->is_success()) {
             $self->authorization($response->{ReferenceNumber});
         } else { # fill in error_message if there is is an error