71513: Card tokenization [token_check]
[freeside.git] / FS / FS / agent.pm
index fc23433..8aa78c2 100644 (file)
@@ -238,51 +238,48 @@ sub ticketing_queue {
 
 Returns a payment gateway object (see L<FS::payment_gateway>) for this agent.
 
-Currently available options are I<nofatal>, I<invnum>, I<method>, 
-I<payinfo>, and I<thirdparty>.
+Currently available options are I<nofatal>, I<method>, I<thirdparty>,
+<conf> and I<load_gatewaynum>.
 
 If I<nofatal> is set, and no gateway is available, then the empty string
 will be returned instead of throwing a fatal exception.
 
-If I<invnum> is set to the number of an invoice (see L<FS::cust_bill>) then
-an attempt will be made to select a gateway suited for the taxes paid on 
-the invoice.
+The I<method> option can be used to influence the choice
+as well.  Presently only CHEK/ECHECK and PAYPAL methods are meaningful.
 
-The I<method> and I<payinfo> options can be used to influence the choice
-as well.  Presently only 'CC', 'ECHECK', and 'PAYPAL' methods are meaningful.
+If I<method> is CHEK/ECHECK and the default gateway is being returned,
+the business-onlinepayment-ach gateway will be returned if available.
 
-When the I<method> is 'CC' then the card number in I<payinfo> can direct
-this routine to route to a gateway suited for that type of card.
+If I<thirdparty> is set and the I<method> is PAYPAL, the defined paypal
+gateway will be returned.
 
-If I<thirdparty> is set, the defined self-service payment gateway will 
-be returned.
+If I<load_gatewaynum> exists, then either the specified gateway or the
+default gateway will be returned.  Agent overrides are ignored, and this can
+safely be called as a class method if this option is specified.  Not
+compatible with I<thirdparty>.
+
+Exsisting I<$conf> may be passed for efficiency.
 
 =cut
 
+# opts invnum/payinfo for cardtype/taxclass overrides no longer supported
+# any future overrides added here need to be reconciled with the tokenization process
+
 sub payment_gateway {
   my ( $self, %options ) = @_;
   
-  my $conf = new FS::Conf;
+  my $conf = $options{'conf'};
+  $conf ||= new FS::Conf;
 
   if ( $options{thirdparty} ) {
-    # still a kludge, but it gets the job done
-    # and the 'cardtype' semantics don't really apply to thirdparty
-    # gateways because we have to choose a gateway without ever 
-    # seeing the card number
-    my $gatewaynum =
-      $conf->config('selfservice-payment_gateway', $self->agentnum);
-    my $gateway;
-    $gateway = FS::payment_gateway->by_key($gatewaynum) if $gatewaynum;
-    return $gateway if $gateway;
-
-    # a little less kludgey than the above, and allows PayPal to coexist 
-    # with credit card gateways
+
+    # allows PayPal to coexist with credit card gateways
     my $is_paypal = { op => '!=', value => 'PayPal' };
     if ( uc($options{method}) eq 'PAYPAL' ) {
       $is_paypal = 'PayPal';
     }
 
-    $gateway = qsearchs({
+    my $gateway = qsearchs({
         table     => 'payment_gateway',
         addl_from => ' JOIN agent_payment_gateway USING (gatewaynum) ',
         hashref   => {
@@ -302,52 +299,17 @@ sub payment_gateway {
     }
   }
 
-  my $taxclass = '';
-  if ( $options{invnum} ) {
-
-    my $cust_bill = qsearchs('cust_bill', { 'invnum' => $options{invnum} } );
-    die "invnum ". $options{'invnum'}. " not found" unless $cust_bill;
-
-    my @part_pkg =
-      map  { $_->part_pkg }
-      grep { $_ }
-      map  { $_->cust_pkg }
-      $cust_bill->cust_bill_pkg;
-
-    my @taxclasses = map $_->taxclass, @part_pkg;
-
-    $taxclass = $taxclasses[0]
-      unless grep { $taxclasses[0] ne $_ } @taxclasses; #unless there are
-                                                        #different taxclasses
-  }
-
-  #look for an agent gateway override first
-  my $cardtype = '';
-  if ( $options{method} ) {
-    if ( $options{method} eq 'CC' && $options{payinfo} ) {
-      $cardtype = cardtype($options{payinfo});
-    } elsif ( $options{method} eq 'ECHECK' ) {
-      $cardtype = 'ACH';
-    } else {
-      $cardtype = $options{method}
-    }
+  my ($override, $payment_gateway);
+  if (exists $options{'load_gatewaynum'}) { # no agent overrides if this opt is in use
+    if ($options{'load_gatewaynum'}) {
+      $payment_gateway = qsearchs('payment_gateway', { gatewaynumnum => $options{'load_gatewaynum'} } );
+      # always fatal
+      die "Could not load payment gateway ".$options{'load_gatewaynum'} unless $payment_gateway;
+    } # else use default, loaded below
+  } else {
+    $override = qsearchs('agent_payment_gateway', { agentnum => $self->agentnum } );
   }
 
-  my $override =
-       qsearchs('agent_payment_gateway', { agentnum => $self->agentnum,
-                                           cardtype => $cardtype,
-                                           taxclass => $taxclass,       } )
-    || qsearchs('agent_payment_gateway', { agentnum => $self->agentnum,
-                                           cardtype => '',
-                                           taxclass => $taxclass,       } )
-    || qsearchs('agent_payment_gateway', { agentnum => $self->agentnum,
-                                           cardtype => $cardtype,
-                                           taxclass => '',              } )
-    || qsearchs('agent_payment_gateway', { agentnum => $self->agentnum,
-                                           cardtype => '',
-                                           taxclass => '',              } );
-
-  my $payment_gateway;
   if ( $override ) { #use a payment gateway override
 
     $payment_gateway = $override->payment_gateway;
@@ -355,11 +317,13 @@ sub payment_gateway {
     $payment_gateway->gateway_namespace('Business::OnlinePayment')
       unless $payment_gateway->gateway_namespace;
 
-  } else { #use the standard settings from the config
+  } elsif (!$payment_gateway) { #use the standard settings from the config
 
     # the standard settings from the config could be moved to a null agent
     # agent_payment_gateway referenced payment_gateway
 
+    # remember, this block might be run as a class method if false load_gatewaynum exists
+
     unless ( $conf->exists('business-onlinepayment') ) {
       if ( $options{'nofatal'} ) {
         return '';