only tokenize cards
[freeside.git] / FS / FS / cust_main / Billing_Realtime.pm
index 59792e7..f089059 100644 (file)
@@ -416,6 +416,13 @@ sub realtime_bop {
   # set fields from passed cust_payby
   _bop_cust_payby_options(\%options);
 
+  # check for banned credit card/ACH
+  my $ban = FS::banned_pay->ban_search(
+    'payby'   => $bop_method2payby{$options{method}},
+    'payinfo' => $options{payinfo},
+  );
+  return "Banned credit card" if $ban && $ban->bantype ne 'warn';
+
   # possibly run a separate transaction to tokenize card number,
   #   so that we never store tokenized card info in cust_pay_pending
   if (($options{method} eq 'CC') && !$self->tokenized($options{'payinfo'})) {
@@ -502,16 +509,6 @@ sub realtime_bop {
   die $@ if $@;
 
   ###
-  # check for banned credit card/ACH
-  ###
-
-  my $ban = FS::banned_pay->ban_search(
-    'payby'   => $bop_method2payby{$options{method}},
-    'payinfo' => $options{payinfo},
-  );
-  return "Banned credit card" if $ban && $ban->bantype ne 'warn';
-
-  ###
   # check for term discount validity
   ###
 
@@ -1587,12 +1584,6 @@ sub realtime_refund_bop {
         $content{'name'} = $self->get('first'). ' '. $self->get('last');
       }
     }
-    if ( $cust_pay->payby eq 'CARD'
-         && !$content{'card_number'}
-         && $cust_pay->tokenized
-    ) {
-      $content{'card_token'} = $cust_pay->payinfo;
-    }
     $void->content( 'action' => 'void', %content );
     $void->test_transaction(1)
       if $conf->exists('business-onlinepayment-test_transaction');
@@ -1799,6 +1790,13 @@ sub realtime_verify_bop {
   return "No cust_payby" unless $options{'cust_payby'};
   _bop_cust_payby_options(\%options);
 
+  # check for banned credit card/ACH
+  my $ban = FS::banned_pay->ban_search(
+    'payby'   => $bop_method2payby{'CC'},
+    'payinfo' => $options{payinfo},
+  );
+  return "Banned credit card" if $ban && $ban->bantype ne 'warn';
+
   # possibly run a separate transaction to tokenize card number,
   #   so that we never store tokenized card info in cust_pay_pending
   if (($options{method} eq 'CC') && !$self->tokenized($options{'payinfo'})) {
@@ -1819,16 +1817,6 @@ sub realtime_verify_bop {
   die $@ if $@;
 
   ###
-  # check for banned credit card/ACH
-  ###
-
-  my $ban = FS::banned_pay->ban_search(
-    'payby'   => $bop_method2payby{'CC'},
-    'payinfo' => $options{payinfo},
-  );
-  return "Banned credit card" if $ban && $ban->bantype ne 'warn';
-
-  ###
   # massage data
   ###
 
@@ -2236,6 +2224,13 @@ sub realtime_tokenize {
   return '' unless $options{method} eq 'CC';
   return '' if $self->tokenized($options{payinfo}); #already tokenized
 
+  # check for banned credit card/ACH
+  my $ban = FS::banned_pay->ban_search(
+    'payby'   => $bop_method2payby{'CC'},
+    'payinfo' => $options{payinfo},
+  );
+  return "Banned credit card" if $ban && $ban->bantype ne 'warn';
+
   ###
   # select a gateway
   ###
@@ -2264,16 +2259,6 @@ sub realtime_tokenize {
                 && grep /^Tokenize$/, @{$supported_actions{'CC'}};
 
   ###
-  # check for banned credit card/ACH
-  ###
-
-  my $ban = FS::banned_pay->ban_search(
-    'payby'   => $bop_method2payby{'CC'},
-    'payinfo' => $options{payinfo},
-  );
-  return "Banned credit card" if $ban && $ban->bantype ne 'warn';
-
-  ###
   # massage data
   ###
 
@@ -2414,8 +2399,9 @@ sub token_check {
 
   my $cache = {}; #cache for module info
 
-  # look for a gateway that can't tokenize
+  # look for a gateway that can and can't tokenize
   my $require_tokenized = 1;
+  my $someone_tokenizing = 0;
   foreach my $gateway (
     FS::payment_gateway->all_gateways(
       'method'  => 'CC',
@@ -2427,18 +2413,26 @@ sub token_check {
       # no default gateway, no promise to tokenize
       # can just load other gateways as-needeed below
       $require_tokenized = 0;
-      last;
+      last if $someone_tokenizing;
+      next;
     }
     my $info = _token_check_gateway_info($cache,$gateway);
     die $info unless ref($info); # means it's an error message
-    unless ($info->{'can_tokenize'}) {
+    if ($info->{'can_tokenize'}) {
+      $someone_tokenizing = 1;
+    } else {
       # a configured gateway can't tokenize, that's all we need to know right now
       # can just load other gateways as-needeed below
       $require_tokenized = 0;
-      last;
+      last if $someone_tokenizing;
     }
   }
 
+  unless ($someone_tokenizing) { #no need to check, if no one can tokenize
+    warn "no gateways tokenize\n" if $debug;
+    return;
+  }
+
   warn "REQUIRE TOKENIZED" if $require_tokenized && $debug;
 
   # upgrade does not call this with autocommit turned on,
@@ -2469,7 +2463,7 @@ CUSTLOOP:
       }
 
       if ($require_tokenized && $opt{'daily'}) {
-        $log->critical("Untokenized card number detected in cust_payby ".$cust_payby->custpaybynum);
+        $log->info("Untokenized card number detected in cust_payby ".$cust_payby->custpaybynum. '; tokenizing');
         $dbh->commit or die $dbh->errstr; # commit log message
       }
 
@@ -2570,7 +2564,7 @@ CUSTLOOP:
       }
 
       if ($require_tokenized && $opt{'daily'}) {
-        $log->critical("Untokenized card number detected in $table ".$record->get($record->primary_key));
+        $log->info("Untokenized card number detected in $table ".$record->get($record->primary_key). ';tokenizing');
         $dbh->commit or die $dbh->errstr; # commit log message
       }
 
@@ -2712,7 +2706,15 @@ sub _token_check_next_recnum {
   my $recnum = shift @$recnums;
   return $recnum if $recnum;
   my $tclass = 'FS::'.$table;
-  my $sth = $dbh->prepare('SELECT '.$tclass->primary_key.' FROM '.$table.' ORDER BY '.$tclass->primary_key.' LIMIT '.$step.' OFFSET '.$$offset) or die $dbh->errstr;
+  my $sth = $dbh->prepare(
+    'SELECT '.$tclass->primary_key.
+    ' FROM '.$table.
+    " WHERE payby IN ( 'CARD', 'DCRD' ) ".
+    "   AND ( length(payinfo) > 80 OR payinfo NOT LIKE '99%' )".
+    ' ORDER BY '.$tclass->primary_key.
+    ' LIMIT '.$step.
+    ' OFFSET '.$$offset
+  ) or die $dbh->errstr;
   $sth->execute() or die $sth->errstr;
   my @recnums;
   while (my $rec = $sth->fetchrow_hashref) {