[freeside-commits] branch master updated. 8f47076c27dd065fa130fd6b1af7dd90c2125d5f

Mark Wells mark at 420.am
Thu Aug 15 17:16:16 PDT 2013


The branch, master has been updated
       via  8f47076c27dd065fa130fd6b1af7dd90c2125d5f (commit)
      from  7a51c5cf922048cf1478920b3fec496e0bb26aef (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 8f47076c27dd065fa130fd6b1af7dd90c2125d5f
Author: Mark Wells <mark at freeside.biz>
Date:   Thu Aug 15 16:59:05 2013 -0700

    capture B:OP and B:BP failure_status values from payment attempts, #21117

diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index 2ce1794..b0e330d 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -1611,6 +1611,7 @@ sub tables_hashref {
         'invnum',       'int',     'NULL',  '', '', '',
         'manual',       'char',    'NULL',   1, '', '',
         'discount_term','int',     'NULL',  '', '', '',
+        'failure_status','varchar','NULL',  16, '', '',
       ],
       'primary_key' => 'paypendingnum',
       'unique'      => [ [ 'payunique' ] ],
@@ -1775,6 +1776,7 @@ sub tables_hashref {
         'amount',      @money_type,                  '', '', 
         'currency',         'char', 'NULL',       3, '', '',
         'status',        'varchar', 'NULL', $char_d, '', '', 
+        'failure_status','varchar', 'NULL',      16, '', '',
         'error_message', 'varchar', 'NULL', $char_d, '', '',
       ],
       'primary_key' => 'paybatchnum',
diff --git a/FS/FS/cust_main/Billing_Realtime.pm b/FS/FS/cust_main/Billing_Realtime.pm
index 1caa3e5..0fd86b1 100644
--- a/FS/FS/cust_main/Billing_Realtime.pm
+++ b/FS/FS/cust_main/Billing_Realtime.pm
@@ -1005,8 +1005,9 @@ sub _realtime_bop_result {
 
   } else {
 
-    my $perror = $payment_gateway->gateway_module. " error: ".
-      $transaction->error_message;
+    my $perror = $transaction->error_message;
+    #$payment_gateway->gateway_module. " error: ".
+    # removed for conciseness
 
     my $jobnum = $cust_pay_pending->jobnum;
     if ( $jobnum ) {
@@ -1104,7 +1105,11 @@ sub _realtime_bop_result {
     }
 
     $cust_pay_pending->status('done');
-    $cust_pay_pending->statustext("declined: $perror");
+    $cust_pay_pending->statustext($perror);
+    #'declined:': no, that's failure_status
+    if ( $transaction->can('failure_status') ) {
+      $cust_pay_pending->failure_status( $transaction->failure_status );
+    }
     my $cpp_done_err = $cust_pay_pending->replace;
     if ( $cpp_done_err ) {
       my $e = "WARNING: $options{method} declined but pending payment not ".
diff --git a/FS/FS/cust_pay_batch.pm b/FS/FS/cust_pay_batch.pm
index e1e32d3..b93d816 100644
--- a/FS/FS/cust_pay_batch.pm
+++ b/FS/FS/cust_pay_batch.pm
@@ -84,6 +84,9 @@ following fields are currently supported:
 
 =item error_message - the error returned by the gateway if any
 
+=item failure_status - the normalized L<Business::BatchPayment> failure 
+status, if any
+
 =back
 
 =head1 METHODS
@@ -340,20 +343,24 @@ sub approve {
   return;
 }
 
-=item decline [ REASON ]
+=item decline [ REASON [ STATUS ] ]
 
 Decline this payment.  This will replace the existing record with the 
 same paybatchnum, set its status to 'Declined', and run collection events
 as appropriate.  This should only be called from the batch import process.
 
 REASON is a string description of the decline reason, defaulting to 
-'Returned payment'.
+'Returned payment', and will go into the "error_message" field.
+
+STATUS is a normalized failure status defined by L<Business::BatchPayment>,
+and will go into the "failure_status" field.
 
 =cut
 
 sub decline {
   my $new = shift;
   my $reason = shift || 'Returned payment';
+  my $failure_status = shift || '';
   #my $conf = new FS::Conf;
 
   my $paybatchnum = $new->paybatchnum;
@@ -390,6 +397,7 @@ sub decline {
   } # !$old->status
   $new->status('Declined');
   $new->error_message($reason);
+  $new->failure_status($failure_status);
   my $error = $new->replace($old);
   if ( $error ) {
     return "error updating status of paybatchnum $paybatchnum: $error\n";
diff --git a/FS/FS/cust_pay_pending.pm b/FS/FS/cust_pay_pending.pm
index 8e29f08..8c6ef69 100644
--- a/FS/FS/cust_pay_pending.pm
+++ b/FS/FS/cust_pay_pending.pm
@@ -124,6 +124,13 @@ Transaction recorded in database
 
 Additional status information.
 
+=item failure_status
+
+One of the standard failure status strings defined in 
+L<Business::OnlinePayment>: "expired", "nsf", "stolen", "pickup", 
+"blacklisted", "declined".  If the transaction status is not "declined", 
+this will be empty.
+
 =item gatewaynum
 
 L<FS::payment_gateway> id.
@@ -215,6 +222,7 @@ sub check {
     || $self->ut_text('status')
     #|| $self->ut_textn('statustext')
     || $self->ut_anything('statustext')
+    || $self->ut_textn('failure_status')
     #|| $self->ut_money('cust_balance')
     || $self->ut_hexn('session_id')
     || $self->ut_foreign_keyn('paynum', 'cust_pay', 'paynum' )
@@ -425,10 +433,11 @@ sub approve {
   '';
 }
 
-=item decline [ STATUSTEXT ]
+=item decline [ STATUSTEXT [ STATUS ] ]
 
 Sets the status of this pending payment to "done" (with statustext
-"declined (manual)" unless otherwise specified).
+"declined (manual)" unless otherwise specified).  The optional STATUS can be
+used to set the failure_status field.
 
 Currently only used when resolving pending payments manually.
 
@@ -437,11 +446,15 @@ Currently only used when resolving pending payments manually.
 sub decline {
   my $self = shift;
   my $statustext = shift || "declined (manual)";
+  my $failure_status = shift || '';
 
   #could send decline email too?  doesn't seem useful in manual resolution
+  # this is also used for thirdparty payment execution failures, but a decline
+  # email isn't useful there either, and will just confuse people.
 
   $self->status('done');
   $self->statustext($statustext);
+  $self->failure_status($failure_status);
   $self->replace;
 }
 
diff --git a/FS/FS/pay_batch.pm b/FS/FS/pay_batch.pm
index 3a06914..8c6c368 100644
--- a/FS/FS/pay_batch.pm
+++ b/FS/FS/pay_batch.pm
@@ -735,7 +735,8 @@ sub import_from_gateway {
           $total += $cust_pay_batch->paid;
         }
         else {
-          $error = $cust_pay_batch->decline($item->error_message);
+          $error = $cust_pay_batch->decline($item->error_message,
+                                            $item->failure_status);
         }
 
         if ( $error ) {        
diff --git a/FS/FS/payinfo_Mixin.pm b/FS/FS/payinfo_Mixin.pm
index 5c4acf7..66c1e59 100644
--- a/FS/FS/payinfo_Mixin.pm
+++ b/FS/FS/payinfo_Mixin.pm
@@ -290,6 +290,33 @@ sub payinfo_used {
   return 0;
 }
 
+=item display_status
+
+For transactions that have both 'status' and 'failure_status', shows the
+status in a single, display-friendly string.
+
+=cut
+
+sub display_status {
+  my $self = shift;
+  my %status = (
+    'done'        => 'Approved',
+    'expired'     => 'Card Expired',
+    'stolen'      => 'Lost/Stolen',
+    'pickup'      => 'Pick Up Card',
+    'nsf'         => 'Insufficient Funds',
+    'inactive'    => 'Inactive Account',
+    'blacklisted' => 'Blacklisted',
+    'declined'    => 'Declined',
+    'approved'    => 'Approved',
+  );
+  if ( $self->failure_status ) {
+    return $status{$self->failure_status};
+  } else {
+    return $status{$self->status};
+  }
+}
+
 =back
 
 =head1 BUGS
diff --git a/httemplate/search/cust_pay_batch.cgi b/httemplate/search/cust_pay_batch.cgi
index 9f9eb30..d5fe52b 100755
--- a/httemplate/search/cust_pay_batch.cgi
+++ b/httemplate/search/cust_pay_batch.cgi
@@ -30,10 +30,10 @@
                                   sub {
                                     sprintf('%.02f', $_[0]->amount)
                                   },
-                                  'status',
+                                  sub { $_[0]->display_status },
                                   'error_message',
                                 ],
-	      'align'       => 'rrrlllcrll',
+	      'align'       => 'rrrlllcrlll',
 	      'links'       => [ '',
 	                         ["${p}view/cust_bill.cgi?", 'invnum'],
 	                         (["${p}view/cust_main.cgi?", 'custnum']) x 2,
diff --git a/httemplate/search/cust_pay_pending.html b/httemplate/search/cust_pay_pending.html
index 54c9935..fe82268 100755
--- a/httemplate/search/cust_pay_pending.html
+++ b/httemplate/search/cust_pay_pending.html
@@ -28,6 +28,9 @@ my $edit_pending =
 my $status_sub = sub {
   my $pending = shift;
   my $return = $pending->status;
+  if ( $pending->failure_status ) {
+    $return = $pending->display_status;
+  }
   my $action = $statusaction{$pending->status};
   return $return unless $action && $edit_pending;
   my $link = include('/elements/popup_link.html',
diff --git a/httemplate/view/cust_main/payment_history/attempted_batch_payment.html b/httemplate/view/cust_main/payment_history/attempted_batch_payment.html
index 95947f5..765e542 100644
--- a/httemplate/view/cust_main/payment_history/attempted_batch_payment.html
+++ b/httemplate/view/cust_main/payment_history/attempted_batch_payment.html
@@ -7,7 +7,14 @@ my ($payby,$payinfo) = translate_payinfo($cust_pay_batch);
 $payby = translate_payby($payby,$payinfo);
 my $info = $payby ? "($payby$payinfo)" : '';
 
-$info .= ': '. $cust_pay_batch->error_message
-  if length($cust_pay_batch->error_message);
+my $detail = '';
+if ( $cust_pay_batch->failure_status ) {
+  $detail = $cust_pay_batch->display_status;
+  $detail .= ' ('.$cust_pay_batch->error_message.')' 
+    if $cust_pay_batch->error_message;
+} else {
+  $detail = $cust_pay_batch->error_message;
+}
+$info .= ': '.$detail if length($detail);
 
 </%init>
diff --git a/httemplate/view/cust_main/payment_history/attempted_payment.html b/httemplate/view/cust_main/payment_history/attempted_payment.html
index f044fc0..63209c7 100644
--- a/httemplate/view/cust_main/payment_history/attempted_payment.html
+++ b/httemplate/view/cust_main/payment_history/attempted_payment.html
@@ -12,7 +12,15 @@ if ( $opt{'pkg-balances'} && $cust_pay_pending->pkgnum ) {
   $info .= ' for '. $cust_pkg->pkg_label_long;
 }
 
-$info .= ': '. $cust_pay_pending->statustext
-  if length($cust_pay_pending->statustext);
+my $detail = '';
+if ( $cust_pay_pending->failure_status ) {
+  $detail = $cust_pay_pending->display_status;
+  $detail .= ' (' . $cust_pay_pending->statustext . ')'
+    if $cust_pay_pending->statustext;
+} else {
+  $detail = $cust_pay_pending->statustext;
+}
+
+$info .= ': '.$detail if length($detail);
 
 </%init>

-----------------------------------------------------------------------

Summary of changes:
 FS/FS/Schema.pm                                    |    2 +
 FS/FS/cust_main/Billing_Realtime.pm                |   11 ++++++--
 FS/FS/cust_pay_batch.pm                            |   12 +++++++-
 FS/FS/cust_pay_pending.pm                          |   17 +++++++++++-
 FS/FS/pay_batch.pm                                 |    3 +-
 FS/FS/payinfo_Mixin.pm                             |   27 ++++++++++++++++++++
 httemplate/search/cust_pay_batch.cgi               |    4 +-
 httemplate/search/cust_pay_pending.html            |    3 ++
 .../payment_history/attempted_batch_payment.html   |   11 ++++++-
 .../payment_history/attempted_payment.html         |   12 +++++++-
 10 files changed, 88 insertions(+), 14 deletions(-)




More information about the freeside-commits mailing list