[freeside-commits] freeside/FS/FS Conf.pm, 1.265, 1.266 Schema.pm, 1.126, 1.127 agent.pm, 1.18, 1.19 cust_main.pm, 1.408, 1.409 cust_pay_pending.pm, 1.6, 1.7 cust_pkg.pm, 1.116, 1.117 payby.pm, 1.14, 1.15 payment_gateway.pm, 1.2, 1.3

Jeff Finucane,420,, jeff at wavetail.420.am
Tue Mar 10 09:14:11 PDT 2009


Update of /home/cvs/cvsroot/freeside/FS/FS
In directory wavetail.420.am:/tmp/cvs-serv17517/FS/FS

Modified Files:
	Conf.pm Schema.pm agent.pm cust_main.pm cust_pay_pending.pm 
	cust_pkg.pm payby.pm payment_gateway.pm 
Log Message:
merge webpay support in with autoselection of old realtime_bop and realtime_refund_bop

Index: Conf.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/Conf.pm,v
retrieving revision 1.265
retrieving revision 1.266
diff -u -d -r1.265 -r1.266
--- Conf.pm	2 Mar 2009 04:58:09 -0000	1.265
+++ Conf.pm	10 Mar 2009 16:14:08 -0000	1.266
@@ -8,6 +8,7 @@
 use FS::ConfItem;
 use FS::ConfDefaults;
 use FS::Conf_compat17;
+use FS::payby;
 use FS::conf;
 use FS::Record qw(qsearch qsearchs);
 use FS::UID qw(dbh datasrc use_confcompat);
@@ -620,6 +621,17 @@
   },
 
   {
+    'key'         => 'business-onlinepayment-namespace',
+    'section'     => 'billing',
+    'description' => 'Specifies which perl module namespace (which group of collection routines) is used by default.',
+    'type'        => 'select',
+    'select_hash' => [
+                       'Business::OnlinePayment' => 'Direct API (Business::OnlinePayment)',
+		       'Business::OnlineThirdPartyPayment' => 'Web API (Business::ThirdPartyPayment)',
+                     ],
+  },
+
+  {
     'key'         => 'business-onlinepayment-description',
     'section'     => 'billing',
     'description' => 'String passed as the description field to <a href="http://search.cpan.org/search?mode=module&query=Business%3A%3AOnlinePayment">Business::OnlinePayment</a>.  Evaluated as a double-quoted perl string, with the following variables available: <code>$agent</code> (the agent name), and <code>$pkgs</code> (a comma-separated list of packages for which these charges apply)',

Index: payby.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/payby.pm,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- payby.pm	3 Sep 2008 01:46:12 -0000	1.14
+++ payby.pm	10 Mar 2009 16:14:09 -0000	1.15
@@ -48,28 +48,33 @@
     tinyname  => 'card',
     shortname => 'Credit card',
     longname  => 'Credit card (automatic)',
+    realtime  => 1,
   },
   'DCRD' => {
     tinyname  => 'card',
     shortname => 'Credit card',
     longname  => 'Credit card (on-demand)',
     cust_pay  => 'CARD', #this is a customer type only, payments are CARD...
+    realtime  => 1,
   },
   'CHEK' => {
     tinyname  => 'check',
     shortname => 'Electronic check',
     longname  => 'Electronic check (automatic)',
+    realtime  => 1,
   },
   'DCHK' => {
     tinyname  => 'check',
     shortname => 'Electronic check',
     longname  => 'Electronic check (on-demand)',
     cust_pay  => 'CHEK', #this is a customer type only, payments are CHEK...
+    realtime  => 1,
   },
   'LECB' => {
     tinyname  => 'phone bill',
     shortname => 'Phone bill billing',
     longname  => 'Phone bill billing',
+    realtime  => 1,
   },
   'BILL' => {
     tinyname  => 'billing',
@@ -131,6 +136,15 @@
   return 1;
 }
 
+sub realtime {  # can use realtime payment facilities
+  my( $self, $payby ) = @_;
+
+  return 0 unless $hash{$payby};
+  return 0 unless exists( $hash{$payby}->{realtime} );
+
+  return $hash{$payby}->{realtime};
+}
+
 sub payby2longname {
   my $self = shift;
   map { $_ => $hash{$_}->{longname} } $self->payby;
@@ -157,6 +171,7 @@
 %payby2bop = (
   'CARD' => 'CC',
   'CHEK' => 'ECHECK',
+  'MCRD' => 'CC',
 );
 
 sub payby2bop {

Index: payment_gateway.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/payment_gateway.pm,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- payment_gateway.pm	2 Mar 2008 01:31:38 -0000	1.2
+++ payment_gateway.pm	10 Mar 2009 16:14:09 -0000	1.3
@@ -1,12 +1,14 @@
 package FS::payment_gateway;
 
 use strict;
-use vars qw( @ISA );
+use vars qw( @ISA $me $DEBUG );
 use FS::Record qw( qsearch qsearchs dbh );
 use FS::option_Common;
 use FS::agent_payment_gateway;
 
 @ISA = qw( FS::option_Common );
+$me = '[ FS::payment_gateway ]';
+$DEBUG=0;
 
 =head1 NAME
 
@@ -37,6 +39,8 @@
 
 =item gatewaynum - primary key
 
+=item gateway_namespace - Business::OnlinePayment or Business::OnlineThirdPartyPayment
+
 =item gateway_module - Business::OnlinePayment:: module name
 
 =item gateway_username - payment gateway username
@@ -110,8 +114,12 @@
   my $error = 
     $self->ut_numbern('gatewaynum')
     || $self->ut_alpha('gateway_module')
+    || $self->ut_enum('gateway_namespace', ['Business::OnlinePayment',
+                                            'Business::OnlineThirdPartyPayment',
+                                           ] )
     || $self->ut_textn('gateway_username')
     || $self->ut_anything('gateway_password')
+    || $self->ut_textn('gateway_callback_url')  # a bit too permissive
     || $self->ut_enum('disabled', [ '', 'Y' ] )
     #|| $self->ut_textn('gateway_action')
   ;
@@ -131,6 +139,10 @@
     $self->gateway_action('Normal Authorization');
   }
 
+  # this little kludge mimics FS::CGI::popurl
+  $self->gateway_callback_url($self->gateway_callback_url. '/')
+    if ( $self->gateway_callback_url && $self->gateway_callback_url !~ /\/$/ );
+
   $self->SUPER::check;
 }
 
@@ -186,6 +198,41 @@
 
 }
 
+=item namespace_description
+
+returns a friendly name for the namespace
+
+=cut
+
+my %namespace2description = (
+  '' => 'Direct',
+  'Business::OnlinePayment' => 'Direct',
+  'Business::OnlineThirdPartyPayment' => 'Hosted',
+);
+
+sub namespace_description {
+  $namespace2description{shift->gateway_namespace} || 'Unknown';
+}
+
+# _upgrade_data
+#
+# Used by FS::Upgrade to migrate to a new database.
+#
+#
+
+sub _upgrade_data {
+  my ($class, %opts) = @_;
+  my $dbh = dbh;
+
+  warn "$me upgrading $class\n" if $DEBUG;
+
+  foreach ( qsearch( 'payment_gateway', { 'gateway_namespace' => '' } ) ) {
+    $_->gateway_namespace('Business::OnlinePayment');  #defaulting
+    my $error = $_->replace;
+    die "$class had error during upgrade replacement: $error" if $error;
+  }
+}
+
 =back
 
 =head1 BUGS

Index: cust_pkg.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_pkg.pm,v
retrieving revision 1.116
retrieving revision 1.117
diff -u -d -r1.116 -r1.117
--- cust_pkg.pm	22 Feb 2009 10:34:26 -0000	1.116
+++ cust_pkg.pm	10 Mar 2009 16:14:09 -0000	1.117
@@ -439,9 +439,7 @@
 sub check {
   my $self = shift;
 
-  $self->locationnum('')
-    if defined($self->locationnum) && length($self->locationnum)
-    && ( $self->locationnum == 0 || $self->locationnum == -1 );
+  $self->locationnum('') if !$self->locationnum || $self->locationnum == -1;
 
   my $error = 
     $self->ut_numbern('pkgnum')

Index: agent.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/agent.pm,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- agent.pm	13 Nov 2008 02:22:03 -0000	1.18
+++ agent.pm	10 Mar 2009 16:14:08 -0000	1.19
@@ -3,12 +3,14 @@
 use strict;
 use vars qw( @ISA );
 #use Crypt::YAPassGen;
+use Business::CreditCard 0.28;
 use FS::Record qw( dbh qsearch qsearchs );
 use FS::cust_main;
 use FS::cust_pkg;
 use FS::agent_type;
 use FS::reg_code;
 use FS::TicketSystem;
+use FS::Conf;
 
 @ISA = qw( FS::m2m_Common FS::Record );
 
@@ -200,6 +202,106 @@
   FS::TicketSystem->queue($self->ticketing_queueid);
 };
 
+=item payment_gateway [ OPTION => VALUE, ... ]
+
+Returns a payment gateway object (see L<FS::payment_gateway>) for this agent.
+
+Currently available options are I<invnum>, I<method>, and I<payinfo>.
+
+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> and I<payinfo> options can be used to influence the choice
+as well.  Presently only 'CC' and 'ECHECK' methods are meaningful.
+
+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.
+
+=cut
+
+sub payment_gateway {
+  my ( $self, %options ) = @_;
+
+  my $taxclass = '';
+  if ( $options{invnum} ) {
+    my $cust_bill = qsearchs('cust_bill', { 'invnum' => $options{invnum} } );
+    die "invnum ". $options{'invnum'}. " not found" unless $cust_bill;
+    my @taxclasses =
+      map  { $_->part_pkg->taxclass }
+      grep { $_ }
+      map  { $_->cust_pkg }
+      $cust_bill->cust_bill_pkg;
+    unless ( grep { $taxclasses[0] ne $_ } @taxclasses ) { #unless there are
+                                                           #different taxclasses      $taxclass = $taxclasses[0];
+    }
+  }
+
+  #look for an agent gateway override first
+  my $cardtype;
+  if ( $options{method} && $options{method} eq 'CC' ) {
+    $cardtype = cardtype($options{payinfo});
+  } elsif ( $options{method} && $options{method} eq 'ECHECK' ) {
+    $cardtype = 'ACH';
+  } else {
+    $cardtype = $options{method} || '';
+  }
+
+  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 = new FS::payment_gateway;
+  if ( $override ) { #use a payment gateway override
+
+    $payment_gateway = $override->payment_gateway;
+
+  } else { #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
+
+    my $conf = new FS::Conf;
+    die "Real-time processing not enabled\n"
+      unless $conf->exists('business-onlinepayment');
+
+    #load up config
+    my $bop_config = 'business-onlinepayment';
+    $bop_config .= '-ach'
+      if ( $options{method}
+           && $options{method} =~ /^(ECHECK|CHEK)$/
+           && $conf->exists($bop_config. '-ach')
+         );
+    my ( $processor, $login, $password, $action, @bop_options ) =
+      $conf->config($bop_config);
+    $action ||= 'normal authorization';
+    pop @bop_options if scalar(@bop_options) % 2 && $bop_options[-1] =~ /^\s*$/;
+    die "No real-time processor is enabled - ".
+        "did you set the business-onlinepayment configuration value?\n"
+      unless $processor;
+
+    $payment_gateway->gateway_namespace( $conf->config('business-onlinepayment-namespace') ||
+                                 'Business::OnlinePayment');
+    $payment_gateway->gateway_module($processor);
+    $payment_gateway->gateway_username($login);
+    $payment_gateway->gateway_password($password);
+    $payment_gateway->gateway_action($action);
+    $payment_gateway->set('options', [ @bop_options ]);
+
+  }
+
+  $payment_gateway;
+}
+
 =item num_prospect_cust_main
 
 Returns the number of prospects (customers with no packages ever ordered) for

Index: cust_main.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_main.pm,v
retrieving revision 1.408
retrieving revision 1.409
diff -u -d -r1.408 -r1.409
--- cust_main.pm	17 Feb 2009 02:01:59 -0000	1.408
+++ cust_main.pm	10 Mar 2009 16:14:08 -0000	1.409
@@ -3368,6 +3368,10 @@
 
 }
 
+# some horrid false laziness here to avoid refactor fallout
+# eventually realtime realtime_bop and realtime_refund_bop should go
+# away and be replaced by _new_realtime_bop and _new_realtime_refund_bop
+
 =item realtime_bop METHOD AMOUNT [ OPTION => VALUE ... ]
 
 Runs a realtime credit card, ACH (electronic check) or phone bill transaction
@@ -3401,7 +3405,12 @@
[...1426 lines suppressed...]
     unless $refund->is_success();
 
-  my %method2payby = (
-    'CC'     => 'CARD',
-    'ECHECK' => 'CHEK',
-    'LEC'    => 'LECB',
-  );
-
   my $paybatch = "$processor:". $refund->authorization;
   $paybatch .= ':'. $refund->order_number
     if $refund->can('order_number') && $refund->order_number;
@@ -4349,7 +5529,7 @@
     'paynum'   => $options{'paynum'},
     'refund'   => $amount,
     '_date'    => '',
-    'payby'    => $method2payby{$method},
+    'payby'    => $bop_method2payby{$options{method}},
     'payinfo'  => $payinfo,
     'paybatch' => $paybatch,
     'reason'   => $options{'reason'} || 'card or ACH refund',

Index: Schema.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/Schema.pm,v
retrieving revision 1.126
retrieving revision 1.127
diff -u -d -r1.126 -r1.127
--- Schema.pm	2 Mar 2009 08:50:01 -0000	1.126
+++ Schema.pm	10 Mar 2009 16:14:08 -0000	1.127
@@ -845,10 +845,12 @@
         'payunique',    'varchar', 'NULL', $char_d, '', '', #separate paybatch "unique" functions from current usage
 
         'status',       'varchar',     '', $char_d, '', '', 
+        'session_id',   'varchar', 'NULL', $char_d, '', '', #only need 32
         'statustext',   'text',    'NULL',  '', '', '', 
         'gatewaynum',   'int',     'NULL',  '', '', '',
         #'cust_balance', @money_type,            '', '',
         'paynum',       'int',     'NULL',  '', '', '',
+        'jobnum',       'int',     'NULL',  '', '', '', 
       ],
       'primary_key' => 'paypendingnum',
       'unique'      => [ [ 'payunique' ] ],
@@ -1857,10 +1859,12 @@
     'payment_gateway' => {
       'columns' => [
         'gatewaynum',       'serial',   '',     '', '', '', 
+        'gateway_namespace','varchar',  'NULL', $char_d, '', '', 
         'gateway_module',   'varchar',  '',     $char_d, '', '', 
         'gateway_username', 'varchar',  'NULL', $char_d, '', '', 
         'gateway_password', 'varchar',  'NULL', $char_d, '', '', 
         'gateway_action',   'varchar',  'NULL', $char_d, '', '', 
+        'gateway_callback_url', 'varchar',  'NULL', $char_d, '', '', 
         'disabled',   'char',  'NULL',   1, '', '', 
       ],
       'primary_key' => 'gatewaynum',

Index: cust_pay_pending.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_pay_pending.pm,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- cust_pay_pending.pm	16 Feb 2009 23:54:37 -0000	1.6
+++ cust_pay_pending.pm	10 Mar 2009 16:14:09 -0000	1.7
@@ -191,6 +191,7 @@
     #|| $self->ut_textn('statustext')
     || $self->ut_anything('statustext')
     #|| $self->ut_money('cust_balance')
+    || $self->ut_hexn('session_id')
     || $self->ut_foreign_keyn('paynum', 'cust_pay', 'paynum' )
     || $self->payinfo_check() #payby/payinfo/paymask/paydate
   ;
@@ -215,6 +216,18 @@
   $self->SUPER::check;
 }
 
+=item cust_main
+
+Returns the associated L<FS::cust_main> record if any.  Otherwise returns false.
+
+=cut
+
+sub cust_main {
+  my $self = shift;
+  qsearchs('cust_main', { custnum => $self->custnum } );
+}
+
+
 #these two are kind-of false laziness w/cust_main::realtime_bop
 #(currently only used when resolving pending payments manually)
 



More information about the freeside-commits mailing list