changes to support eWay third-party payment, #10208
authormark <mark>
Tue, 21 Dec 2010 09:12:45 +0000 (09:12 +0000)
committermark <mark>
Tue, 21 Dec 2010 09:12:45 +0000 (09:12 +0000)
FS/FS/ClientAPI/MyAccount.pm
FS/FS/ClientAPI/Signup.pm
FS/FS/Conf.pm
FS/FS/agent.pm
FS/FS/cust_main/Billing_Realtime.pm
FS/FS/cust_pay_pending.pm
fs_selfservice/FS-SelfService/cgi/make_thirdparty_payment.html
fs_selfservice/FS-SelfService/cgi/post_thirdparty_payment.html [new file with mode: 0644]
fs_selfservice/FS-SelfService/cgi/selfservice.cgi
httemplate/edit/payment_gateway.html

index e41fe7d..ecabe31 100644 (file)
@@ -237,6 +237,28 @@ sub logout {
   }
 }
 
   }
 }
 
+sub payment_gateway {
+  # internal use only
+  # takes a cust_main and a cust_payby entry, returns the payment_gateway
+  my $conf = new FS::Conf;
+  my $cust_main = shift;
+  my $cust_payby = shift;
+  my $gatewaynum = $conf->config('selfservice-payment_gateway');
+  if ( $gatewaynum ) {
+    my $pg = qsearchs('payment_gateway', { gatewaynum => $gatewaynum });
+    die "configured gatewaynum $gatewaynum not found!" if !$pg;
+    return $pg;
+  }
+  else {
+    return '' if ! FS::payby->realtime($cust_payby);
+    my $pg = $cust_main->agent->payment_gateway(
+      'method'  => FS::payby->payby2bop($cust_payby),
+      'nofatal' => 1
+    );
+    return $pg;
+  }
+}
+
 sub access_info {
   my $p = shift;
 
 sub access_info {
   my $p = shift;
 
@@ -262,18 +284,11 @@ sub access_info {
   my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
     or return { 'error' => "unknown custnum $custnum" };
 
   my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
     or return { 'error' => "unknown custnum $custnum" };
 
-  $info->{hide_payment_fields} =
-  [
-    map { my $pg = '';
-          if ( FS::payby->realtime($_) ) {
-            $pg = $cust_main->agent->payment_gateway(
-              'method'  => FS::payby->payby2bop($_),
-              'nofatal' => 1,
-            );
-          }
-          $pg && $pg->gateway_namespace eq 'Business::OnlineThirdPartyPayment';
-        }
-    @{ $info->{cust_paybys} }
+  $info->{'hide_payment_fields'} = [ 
+    map { 
+      my $pg = payment_gateway($cust_main, $_);
+      $pg && $pg->gateway_namespace eq 'Business::OnlineThirdPartyPayment';
+    } @{ $info->{cust_paybys} }
   ];
 
   $info->{'self_suspend_reason'} = 
   ];
 
   $info->{'self_suspend_reason'} = 
@@ -532,18 +547,11 @@ sub payment_info {
   my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
     or return { 'error' => "unknown custnum $custnum" };
 
   my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
     or return { 'error' => "unknown custnum $custnum" };
 
-  $return{hide_payment_fields} =
-  [
-    map { my $pg = '';
-          if ( FS::payby->realtime($_) ) {
-            $pg = $cust_main->agent->payment_gateway(
-              'method'  => FS::payby->payby2bop($_),
-              'nofatal' => 1,
-            );
-          }
-          $pg && $pg->gateway_namespace eq 'Business::OnlineThirdPartyPayment';
-        }
-    @{ $return{cust_paybys} }
+  $return{'hide_payment_fields'} = [
+    map { 
+      my $pg = payment_gateway($cust_main, $_);
+      $pg && $pg->gateway_namespace eq 'Business::OnlineThirdPartyPayment';
+    } @{ $return{cust_paybys} }
   ];
 
   $return{balance} = $cust_main->balance; #XXX pkg-balances?
   ];
 
   $return{balance} = $cust_main->balance; #XXX pkg-balances?
@@ -692,6 +700,7 @@ sub process_payment {
     'paycvv'   => $paycvv,
     'pkgnum'   => $session->{'pkgnum'},
     'discount_term' => $discount_term,
     'paycvv'   => $paycvv,
     'pkgnum'   => $session->{'pkgnum'},
     'discount_term' => $discount_term,
+    'selfservice' => 1,
     map { $_ => $p->{$_} } @{ $payby2fields{$payby} }
   );
   return { 'error' => $error } if $error;
     map { $_ => $p->{$_} } @{ $payby2fields{$payby} }
   );
   return { 'error' => $error } if $error;
@@ -746,18 +755,27 @@ sub realtime_collect {
   my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
     or return { 'error' => "unknown custnum $custnum" };
 
   my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
     or return { 'error' => "unknown custnum $custnum" };
 
+  my $amount;
+  if ( $p->{'amount'} ) {
+    $amount = $p->{'amount'};
+  }
+  elsif ( $session->{'pkgnum'} ) {
+    $amount = $cust_main->balance_pkgnum( $session->{'pkgnum'} );
+  }
+  else {
+    $amount = $cust_main->balance;
+  }
+
   my $error = $cust_main->realtime_collect(
     'method'     => $p->{'method'},
   my $error = $cust_main->realtime_collect(
     'method'     => $p->{'method'},
+    'amount'     => $amount,
     'pkgnum'     => $session->{'pkgnum'},
     'session_id' => $p->{'session_id'},
     'apply'      => 1,
     'pkgnum'     => $session->{'pkgnum'},
     'session_id' => $p->{'session_id'},
     'apply'      => 1,
+    'selfservice'=> 1,
   );
   return { 'error' => $error } unless ref( $error );
 
   );
   return { 'error' => $error } unless ref( $error );
 
-  my $amount = $session->{'pkgnum'}
-                 ? $cust_main->balance_pkgnum( $session->{'pkgnum'} )
-                 : $cust_main->balance;
-
   return { 'error' => '', amount => $amount, %$error };
 }
 
   return { 'error' => '', amount => $amount, %$error };
 }
 
@@ -1410,7 +1428,7 @@ sub _do_bop_realtime {
 
     my $bill_error =    $cust_main->bill
                      || $cust_main->apply_payments_and_credits
 
     my $bill_error =    $cust_main->bill
                      || $cust_main->apply_payments_and_credits
-                     || $cust_main->realtime_collect;
+                     || $cust_main->realtime_collect('selfservice' => 1);
 
     if (    $cust_main->balance > $old_balance
          && $cust_main->balance > 0
 
     if (    $cust_main->balance > $old_balance
          && $cust_main->balance > 0
index 65bb4e3..757dd47 100644 (file)
@@ -321,23 +321,34 @@ sub signup_info {
     warn "$me has agent $agent\n" if $DEBUG > 1;
     if ( $agent ) { #else complain loudly?
       $signup_info->{'hide_payment_fields'} = [];
     warn "$me has agent $agent\n" if $DEBUG > 1;
     if ( $agent ) { #else complain loudly?
       $signup_info->{'hide_payment_fields'} = [];
-      foreach my $payby (@{$signup_info->{payby}}) {
-        warn "$me checking $payby payment fields\n" if $DEBUG > 1;
-        my $hide = 0;
-        if ( FS::payby->realtime($payby) ) {
-          my $payment_gateway =
-            $agent->payment_gateway( 'method'  => FS::payby->payby2bop($payby),
-                                     'nofatal' => 1,
-                                   );
-          if ( $payment_gateway
-                 && $payment_gateway->gateway_namespace
-                      eq 'Business::OnlineThirdPartyPayment'
-             ) {
-            warn "$me hiding $payby payment fields\n" if $DEBUG > 1;
-            $hide = 1;
+      my $gatewaynum = $conf->config('selfservice-payment_gateway');
+      if ( $gatewaynum ) {
+        my $pg = qsearchs('payment_gateway', { gatewaynum => $gatewaynum });
+        die "configured gatewaynum $gatewaynum not found!" if !$pg;
+        my $hide = $pg->gateway_namespace eq 'Business::OnlineThirdPartyPayment';
+        $signup_info->{'hide_payment_fields'} = [
+          map { $hide } @{$signup_info->{'payby'}}
+        ];
+      }
+      else {
+        foreach my $payby (@{$signup_info->{payby}}) {
+          warn "$me checking $payby payment fields\n" if $DEBUG > 1;
+          my $hide = 0;
+          if ( FS::payby->realtime($payby) ) {
+            my $payment_gateway =
+              $agent->payment_gateway( 'method'  => FS::payby->payby2bop($payby),
+                                       'nofatal' => 1,
+                                     );
+            if ( $payment_gateway
+                   && $payment_gateway->gateway_namespace
+                        eq 'Business::OnlineThirdPartyPayment'
+               ) {
+              warn "$me hiding $payby payment fields\n" if $DEBUG > 1;
+              $hide = 1;
+            }
           }
           }
-        }
-        push @{$signup_info->{'hide_payment_fields'}}, $hide;
+          push @{$signup_info->{'hide_payment_fields'}}, $hide;
+        } # foreach $payby
       }
     }
     warn "$me done setting agent-specific payment flag\n" if $DEBUG > 1;
       }
     }
     warn "$me done setting agent-specific payment flag\n" if $DEBUG > 1;
@@ -698,6 +709,7 @@ sub new_customer {
     $bill_error = $cust_main->realtime_collect(
        method        => FS::payby->payby2bop( $packet->{payby} ),
        depend_jobnum => $placeholder->jobnum,
     $bill_error = $cust_main->realtime_collect(
        method        => FS::payby->payby2bop( $packet->{payby} ),
        depend_jobnum => $placeholder->jobnum,
+       selfservice   => 1,
     );
     #warn "$me error collecting from new customer: $bill_error"
     #  if $bill_error;
     );
     #warn "$me error collecting from new customer: $bill_error"
     #  if $bill_error;
@@ -787,29 +799,36 @@ sub capture_payment {
 
   my $conf = new FS::Conf;
 
 
   my $conf = new FS::Conf;
 
-  my $url = $packet->{url};
-  my $payment_gateway =
-    qsearchs('payment_gateway', { 'gateway_callback_url' => popurl(0, $url) } );
-
-  unless ($payment_gateway) {
-
-    my ( $processor, $login, $password, $action, @bop_options ) =
-      $conf->config('business-onlinepayment');
-    $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 = new FS::payment_gateway( {
-      gateway_namespace => $conf->config('business-onlinepayment-namespace'),
-      gateway_module    => $processor,
-      gateway_username  => $login,
-      gateway_password  => $password,
-      gateway_action    => $action,
-      options   => [ ( @bop_options ) ],
-    });
-
+  my $payment_gateway;
+  if ( my $gwnum = $conf->config('selfservice-payment_gateway') ) {
+    $payment_gateway = qsearchs('payment_gateway', { 'gatewaynum' => $gwnum })
+      or die "configured gatewaynum $gwnum not found!";
+  }
+  else {
+    my $url = $packet->{url};
+
+    $payment_gateway = qsearchs('payment_gateway', 
+        { 'gateway_callback_url' => popurl(0, $url) } 
+      );
+    if (!$payment_gateway) { 
+
+      my ( $processor, $login, $password, $action, @bop_options ) =
+        $conf->config('business-onlinepayment');
+      $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 = new FS::payment_gateway( {
+        gateway_namespace => $conf->config('business-onlinepayment-namespace'),
+        gateway_module    => $processor,
+        gateway_username  => $login,
+        gateway_password  => $password,
+        gateway_action    => $action,
+        options   => [ ( @bop_options ) ],
+      });
+    }
   }
  
   die "No real-time third party processor is enabled - ".
   }
  
   die "No real-time third party processor is enabled - ".
@@ -847,7 +866,10 @@ sub capture_payment {
 
   my $cust_main = $cust_pay_pending->cust_main;
   my $bill_error =
 
   my $cust_main = $cust_pay_pending->cust_main;
   my $bill_error =
-    $cust_main->realtime_botpp_capture( $cust_pay_pending, %{$packet->{data}} );
+    $cust_main->realtime_botpp_capture( $cust_pay_pending, 
+      %{$packet->{data}},
+      apply => 1,
+  );
 
   return { 'error'      => ( $bill_error->{bill_error} ? '_decline' : '' ),
            %$bill_error,
 
   return { 'error'      => ( $bill_error->{bill_error} ? '_decline' : '' ),
            %$bill_error,
index 22e761f..5fb5a27 100644 (file)
@@ -584,6 +584,26 @@ my %msg_template_options = (
   'per_agent' => 1,
 );
 
   'per_agent' => 1,
 );
 
+my $_gateway_name = sub {
+  my $g = shift;
+  return '' if !$g;
+  ($g->gateway_username . '@' . $g->gateway_module);
+};
+
+my %payment_gateway_options = (
+  'type'        => 'select-sub',
+  'options_sub' => sub {
+    my @gateways = qsearch({
+        'table' => 'payment_gateway',
+        'hashref' => { 'disabled' => '' },
+      });
+    map { $_->gatewaynum, $_gateway_name->($_) } @gateways;
+  },
+  'option_sub'  => sub {
+    my $gateway = FS::payment_gateway->by_key(shift);
+    $_gateway_name->($gateway);
+  },
+);
 
 #Billing (81 items)
 #Invoicing (50 items)
 
 #Billing (81 items)
 #Invoicing (50 items)
@@ -1726,6 +1746,13 @@ and customer address. Include units.',
   },
 
   {
   },
 
   {
+    'key'         => 'selfservice-payment_gateway',
+    'section'     => 'self-service',
+    'description' => 'Force the use of this payment gateway for self-service.',
+    %payment_gateway_options,
+  },
+
+  {
     'key'         => 'selfservice-save_unchecked',
     'section'     => 'self-service',
     'description' => 'In self-service, uncheck "Remember information" checkboxes by default (normally, they are checked by default).',
     'key'         => 'selfservice-save_unchecked',
     'section'     => 'self-service',
     'description' => 'In self-service, uncheck "Remember information" checkboxes by default (normally, they are checked by default).',
@@ -2971,7 +2998,7 @@ and customer address. Include units.',
 #  {
 #    'key'         => 'batch-manual_approval',
 #    'section'     => 'billing',
 #  {
 #    'key'         => 'batch-manual_approval',
 #    'section'     => 'billing',
-#    'description' => 'Allow manual batch closure, which will approve all payments that do not yet have a status.  This is dangerous, but may be needed if your processor does not provide a list of approved payments.',
+#    'description' => 'Allow manual batch closure, which will approve all payments that do not yet have a status.  This is very dangerous.',
 #    'type'        => 'checkbox',
 #  },
 #
 #    'type'        => 'checkbox',
 #  },
 #
index d291ca0..3794d3f 100644 (file)
@@ -276,7 +276,7 @@ sub payment_gateway {
     $payment_gateway = $override->payment_gateway;
 
     $payment_gateway->gateway_namespace('Business::OnlinePayment')
     $payment_gateway = $override->payment_gateway;
 
     $payment_gateway->gateway_namespace('Business::OnlinePayment')
-      unless $payment_gateway->gateway_name;
+      unless $payment_gateway->gateway_namespace;
 
   } else { #use the standard settings from the config
 
 
   } else { #use the standard settings from the config
 
index ba1e9c8..10b898d 100644 (file)
@@ -178,6 +178,14 @@ sub _bop_recurring_billing {
 sub _payment_gateway {
   my ($self, $options) = @_;
 
 sub _payment_gateway {
   my ($self, $options) = @_;
 
+  if ( $options->{'selfservice'} ) {
+    my $gatewaynum = FS::Conf->new->config('selfservice-payment_gateway');
+    if ( $gatewaynum ) {
+      return $options->{payment_gateway} ||= 
+          qsearchs('payment_gateway', { gatewaynum => $gatewaynum });
+    }
+  }
+
   $options->{payment_gateway} = $self->agent->payment_gateway( %$options )
     unless exists($options->{payment_gateway});
 
   $options->{payment_gateway} = $self->agent->payment_gateway( %$options )
     unless exists($options->{payment_gateway});
 
@@ -467,6 +475,24 @@ sub realtime_bop {
     'custnum' => $self->custnum,
     'status'  => { op=>'!=', value=>'done' } 
   });
     'custnum' => $self->custnum,
     'status'  => { op=>'!=', value=>'done' } 
   });
+  # This is a problem.  A self-service third party payment that fails somehow 
+  # can't be retried, EVER, until someone manually clears it.  Totally 
+  # arbitrary fix: if the existing payment is more than two minutes old, 
+  # kill it.  This doesn't limit how long it can take the pending payment 
+  # to complete, only how long it will obstruct new payments.
+  my @still_pending;
+  foreach (@pending) {
+    if ( time - $_->_date > 120 ) {
+      my $error = $_->delete;
+      warn "error deleting stale pending payment ".$_->paypendingnum.": $error"
+        if $error; # not fatal, it will fail anyway
+    }
+    else {
+      push @still_pending, $_;
+    }
+  }
+  @pending = @still_pending;
+
   return "A payment is already being processed for this customer (".
          join(', ', map 'paypendingnum '. $_->paypendingnum, @pending ).
          "); $options{method} transaction aborted."
   return "A payment is already being processed for this customer (".
          join(', ', map 'paypendingnum '. $_->paypendingnum, @pending ).
          "); $options{method} transaction aborted."
@@ -511,6 +537,7 @@ sub realtime_bop {
     'customer_id'    => $self->custnum,
     %$bop_content,
     'reference'      => $cust_pay_pending->paypendingnum, #for now
     'customer_id'    => $self->custnum,
     %$bop_content,
     'reference'      => $cust_pay_pending->paypendingnum, #for now
+    'callback_url'   => $payment_gateway->gateway_callback_url,
     'email'          => $email,
     %content, #after
   );
     'email'          => $email,
     %content, #after
   );
@@ -1016,9 +1043,10 @@ sub realtime_botpp_capture {
 
   my $method = FS::payby->payby2bop($cust_pay_pending->payby);
 
 
   my $method = FS::payby->payby2bop($cust_pay_pending->payby);
 
-  my $payment_gateway = $cust_pay_pending->gatewaynum
-    ? qsearchs( 'payment_gateway',
-                { gatewaynum => $cust_pay_pending->gatewaynum }
+  my $payment_gateway;
+  my $gatewaynum = $cust_pay_pending->getfield('gatewaynum');
+  $payment_gateway = $gatewaynum ? qsearchs( 'payment_gateway',
+                { gatewaynum => $gatewaynum }
               )
     : $self->agent->payment_gateway( 'method' => $method,
                                      # 'invnum'  => $cust_pay_pending->invnum,
               )
     : $self->agent->payment_gateway( 'method' => $method,
                                      # 'invnum'  => $cust_pay_pending->invnum,
@@ -1080,7 +1108,14 @@ sub realtime_botpp_capture {
   my $error =
     $self->_realtime_bop_result( $cust_pay_pending, $transaction, %options );
 
   my $error =
     $self->_realtime_bop_result( $cust_pay_pending, $transaction, %options );
 
-  {
+  if ( $options{'apply'} ) {
+    my $apply_error = $self->apply_payments_and_credits;
+    if ( $apply_error ) {
+      warn "WARNING: error applying payment: $apply_error\n";
+    }
+  }
+
+  return {
     bill_error => $error,
     session_id => $cust_pay_pending->session_id,
   }
     bill_error => $error,
     session_id => $cust_pay_pending->session_id,
   }
index f48e1a8..e54690e 100644 (file)
@@ -120,9 +120,9 @@ Transaction recorded in database
 
 Additional status information.
 
 
 Additional status information.
 
-=cut
+=item gatewaynum
 
 
-#=item cust_balance - 
+L<FS::payment_gateway> id.
 
 =item paynum - 
 
 
 =item paynum - 
 
@@ -292,10 +292,10 @@ sub insert_cust_pay {
 
 }
 
 
 }
 
-=item decline
+=item decline [ STATUSTEXT ]
 
 
-Sets the status of this pending pament to "done" (with statustext
-"declined (manual)").
+Sets the status of this pending payment to "done" (with statustext
+"declined (manual)" unless otherwise specified).
 
 Currently only used when resolving pending payments manually.
 
 
 Currently only used when resolving pending payments manually.
 
@@ -303,11 +303,12 @@ Currently only used when resolving pending payments manually.
 
 sub decline {
   my $self = shift;
 
 sub decline {
   my $self = shift;
+  my $statustext = shift || "declined (manual)";
 
   #could send decline email too?  doesn't seem useful in manual resolution
 
   $self->status('done');
 
   #could send decline email too?  doesn't seem useful in manual resolution
 
   $self->status('done');
-  $self->statustext("declined (manual)");
+  $self->statustext($statustext);
   $self->replace;
 }
 
   $self->replace;
 }
 
index 4055ed0..b5b9eea 100755 (executable)
@@ -1,35 +1,36 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
-<%= include('header', 'Pay now') %>
+<%= $url = "$selfurl?session=$session_id;action="; 
+  $cgi = new CGI;
+  ''; %>
+<%= include('header', 'Make a payment') %>
+
+<FORM NAME="OneTrueForm" METHOD="POST" ACTION="<%=$selfurl%>" 
+onSubmit="document.OneTrueForm.process.disabled=true">
+<INPUT TYPE="hidden" NAME="session" VALUE="<%=$session_id%>">
+<INPUT TYPE="hidden" NAME="action" VALUE="post_thirdparty_payment">
+<INPUT TYPE="hidden" NAME="payby_method" VALUE="<%= 
+$cgi->param('payby_method') =~ /(CC|ECHECK)/;
+$1 %>">
+<TABLE BGCOLOR="#cccccc">
+<TR>
+  <TH ALIGN="right">Balance&nbsp;due</TH>
+  <TD COLSPAN=7>
+    <SPAN STYLE="background-color: #ffffff;">$<%=sprintf("%.2f", $balance)%>
+  </TD>
+</TR>
+<TR>
+  <TH ALIGN="right">Payment&nbsp;amount</TH>
+  <TD COLSPAN=7>
+    $<INPUT TYPE="text" NAME="amount" SIZE=8 VALUE="<%=sprintf("%.2f", $balance)%>">
+  </TD>
+</TR>
+<TR><TH></TH>
+<TD><INPUT TYPE="submit" NAME="process" VALUE="Process payment">
+</FORM>
 
 
-<SCRIPT TYPE="text/javascript">
-  function popcollect() {
-    overlib( OLiframeContent('<%= $popup_url %>', 336, 550, 'Secure Payment Area', 0, 'auto' ), CAPTION, 'Pay now', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK, BGCOLOR, '#333399', CGCOLOR, '#333399', CLOSETEXT, 'Close' );
-    return false;
-  }
-</SCRIPT>
 <SCRIPT TYPE="text/javascript" SRC="overlibmws.js"></SCRIPT>
 <SCRIPT TYPE="text/javascript" SRC="overlibmws_iframe.js"></SCRIPT>
 <SCRIPT TYPE="text/javascript" SRC="overlibmws_draggable.js"></SCRIPT>
 <SCRIPT TYPE="text/javascript" SRC="overlibmws_crossframe.js"></SCRIPT>
 <SCRIPT TYPE="text/javascript" SRC="iframecontentmws.js"></SCRIPT>
 
 <SCRIPT TYPE="text/javascript" SRC="overlibmws.js"></SCRIPT>
 <SCRIPT TYPE="text/javascript" SRC="overlibmws_iframe.js"></SCRIPT>
 <SCRIPT TYPE="text/javascript" SRC="overlibmws_draggable.js"></SCRIPT>
 <SCRIPT TYPE="text/javascript" SRC="overlibmws_crossframe.js"></SCRIPT>
 <SCRIPT TYPE="text/javascript" SRC="iframecontentmws.js"></SCRIPT>
 
-<%= if ( $error ) {
-  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">$error</FONT><BR><BR>!;
-}else{
-  $OUT .= <<EOF;
-    You are about to contact our payment processor to pay $amount.<BR><BR>
-    Your transaction reference number is $reference <BR><BR>
-    <FORM NAME="collect_popper" method="post" action="javascript:void(0)" onSubmit="popcollect()">
-EOF
-
-  my %itemhash = @collectitems;
-  foreach my $input (keys %itemhash) {
-    $OUT .= qq!<INPUT NAME="$input" TYPE="hidden" VALUE="$itemhash{$input}">!;
-  }
-
-  $OUT .= qq!<INPUT NAME="submit" type="submit" value="Pay now">!;
-  $OUT .= qq!</FORM>!;
-}
-%>
-
 <%= include('footer') %>
 <%= include('footer') %>
diff --git a/fs_selfservice/FS-SelfService/cgi/post_thirdparty_payment.html b/fs_selfservice/FS-SelfService/cgi/post_thirdparty_payment.html
new file mode 100644 (file)
index 0000000..17710b2
--- /dev/null
@@ -0,0 +1,42 @@
+<%= $url = "$selfurl?session=$session_id;action="; ''; %>
+<%= include('header', 'Pay now') %>
+
+<SCRIPT TYPE="text/javascript" SRC="overlibmws.js"></SCRIPT>
+<SCRIPT TYPE="text/javascript" SRC="overlibmws_iframe.js"></SCRIPT>
+<SCRIPT TYPE="text/javascript" SRC="overlibmws_draggable.js"></SCRIPT>
+<SCRIPT TYPE="text/javascript" SRC="overlibmws_crossframe.js"></SCRIPT>
+<SCRIPT TYPE="text/javascript" SRC="iframecontentmws.js"></SCRIPT>
+
+<%= if ( $error ) {
+  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">$error</FONT><BR><BR>!;
+}else{
+  $OUT .= <<EOF;
+    You are about to contact our payment processor to pay $amount.<BR><BR>
+    Your transaction reference number is $reference <BR><BR>
+    <FORM METHOD="POST" ACTION="$popup_url">
+EOF
+    
+#<FORM NAME="collect_popper" method="post" action="javascript:void(0)" onSubmit="popcollect()">
+  my %itemhash = @collectitems;
+#  my $query = join(';', 
+#    map { uri_escape($_) . '=' . uri_escape($itemhash{$_}) }
+#    keys(%itemhash)
+#  );
+  foreach my $input (keys(%itemhash)) {
+    $OUT .= qq!<INPUT NAME="$input" TYPE="hidden" VALUE="$itemhash{$input}">\n!;
+  }
+  $OUT .= qq!<INPUT NAME="submit" TYPE="submit" VALUE="Pay now"></FORM>!
+}
+%>
+
+<%=
+#<SCRIPT TYPE="text/javascript">
+#  function popcollect() {
+#    overlib( OLiframeContent('<%= $popup_url %>', 336, 550, 'Secure Payment Area', 0, 'auto' ), CAPTION, 'Pay now', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK, BGCOLOR, '#333399', CGCOLOR, '#333399', CLOSETEXT, 'Close' );
+#    overlib( OLpostAJAX('<%= $popup_url %>', 
+#    return false;
+#  }
+#</SCRIPT>
+%>
+
+<%= include('footer') %>
index 1f8e550..3f0562a 100644 (file)
@@ -16,13 +16,13 @@ use FS::SelfService qw(
   part_svc_info provision_acct provision_external provision_phone
   unprovision_svc change_pkg suspend_pkg domainselector
   list_svcs list_svc_usage list_cdr_usage list_support_usage
   part_svc_info provision_acct provision_external provision_phone
   unprovision_svc change_pkg suspend_pkg domainselector
   list_svcs list_svc_usage list_cdr_usage list_support_usage
-  myaccount_passwd list_invoices create_ticket get_ticket did_report
+  myaccount_passwd list_invoices create_ticket get_ticket
   mason_comp
 );
 
 $template_dir = '.';
 
   mason_comp
 );
 
 $template_dir = '.';
 
-$DEBUG = 1;
+$DEBUG = 0;
 
 $form_max = 255;
 
 
 $form_max = 255;
 
@@ -72,8 +72,51 @@ if ( $cgi->param('session') eq 'login' ) {
 $session_id = $cgi->param('session');
 
 #order|pw_list XXX ???
 $session_id = $cgi->param('session');
 
 #order|pw_list XXX ???
-$cgi->param('action') =~
-    /^(myaccount|tktcreate|tktview|didreport|invoices|view_invoice|make_payment|make_ach_payment|make_term_payment|make_thirdparty_payment|payment_results|ach_payment_results|recharge_prepay|recharge_results|logout|change_bill|change_ship|change_pay|process_change_bill|process_change_ship|process_change_pay|customer_order_pkg|process_order_pkg|customer_change_pkg|process_change_pkg|process_order_recharge|provision|provision_svc|process_svc_acct|process_svc_phone|process_svc_external|delete_svc|view_usage|view_usage_details|view_cdr_details|view_support_details|change_password|process_change_password|customer_suspend_pkg|process_suspend_pkg)$/
+my @actions = ( qw(
+  myaccount
+  tktcreate
+  tktview
+  didreport
+  invoices
+  view_invoice
+  make_payment
+  make_ach_payment
+  make_term_payment
+  make_thirdparty_payment
+  post_thirdparty_payment
+  payment_results
+  ach_payment_results
+  recharge_prepay
+  recharge_results
+  logout
+  change_bill
+  change_ship
+  change_pay
+  process_change_bill
+  process_change_ship
+  process_change_pay
+  customer_order_pkg
+  process_order_pkg
+  customer_change_pkg
+  process_change_pkg
+  process_order_recharge
+  provision
+  provision_svc
+  process_svc_acct
+  process_svc_phone
+  process_svc_external
+  delete_svc
+  view_usage
+  view_usage_details
+  view_cdr_details
+  view_support_details
+  change_password
+  process_change_password
+  customer_suspend_pkg
+  process_suspend_pkg
+));
+$cgi->param('action') =~ ( '^(' . join('|', @actions) . ')$' )
   or die "unknown action ". $cgi->param('action');
 my $action = $1;
 
   or die "unknown action ". $cgi->param('action');
 my $action = $1;
 
@@ -83,9 +126,11 @@ $FS::SelfService::DEBUG = $DEBUG;
 my $result = eval "&$action();";
 die $@ if $@;
 
 my $result = eval "&$action();";
 die $@ if $@;
 
-#fixed "Use of uninitialized value in string eq"; very annoying when developing
-if ( $result->{error} && ($result->{error} eq "Can't resume session"
-                           || $result->{error} eq "Expired session") ) {
+warn Dumper($result) if $DEBUG;
+
+if ( $result->{error} eq "Can't resume session"
+  || $result->{error} eq "Expired session" ) { #ick
+
   my $login_info = login_info();
   do_template('login', $login_info);
   exit;
   my $login_info = login_info();
   do_template('login', $login_info);
   exit;
@@ -106,7 +151,9 @@ do_template($action, {
 #--
 
 use Data::Dumper;
 #--
 
 use Data::Dumper;
-sub myaccount { my $result = customer_info( 'session_id' => $session_id ); warn Dumper($result); $result;}
+sub myaccount { 
+  customer_info( 'session_id' => $session_id ); 
+}
 
 sub change_bill { my $payment_info =
                     payment_info( 'session_id' => $session_id );
 
 sub change_bill { my $payment_info =
                     payment_info( 'session_id' => $session_id );
@@ -580,9 +627,22 @@ sub ach_payment_results {
 }
 
 sub make_thirdparty_payment {
 }
 
 sub make_thirdparty_payment {
+  payment_info('session_id' => $session_id);
+}
+
+sub post_thirdparty_payment {
   $cgi->param('payby_method') =~ /^(CC|ECHECK)$/
     or die "illegal payby method";
   $cgi->param('payby_method') =~ /^(CC|ECHECK)$/
     or die "illegal payby method";
-  realtime_collect( 'session_id' => $session_id, 'method' => $1 );
+  my $method = $1;
+  $cgi->param('amount') =~ /^(\d+(\.\d*)?)$/
+    or die "illegal amount";
+  my $amount = $1;
+  my $result = realtime_collect( 
+    'session_id' => $session_id,
+    'method' => $method, 
+    'amount' => $amount,
+  );
+  $result;
 }
 
 sub make_term_payment {
 }
 
 sub make_term_payment {
@@ -619,15 +679,6 @@ sub logout {
   FS::SelfService::logout( 'session_id' => $session_id );
 }
 
   FS::SelfService::logout( 'session_id' => $session_id );
 }
 
-sub didreport {
-  my $result = did_report( 'session_id' => $session_id, 
-               'format' => $cgi->param('type'),
-               'recentonly' => $cgi->param('recentonly'),
-           );
-  die $result->{'error'} if exists $result->{'error'} && $result->{'error'};
-  $result;
-}
-
 sub provision {
   my $result = list_pkgs( 'session_id' => $session_id );
   die $result->{'error'} if exists $result->{'error'} && $result->{'error'};
 sub provision {
   my $result = list_pkgs( 'session_id' => $session_id );
   die $result->{'error'} if exists $result->{'error'} && $result->{'error'};
@@ -815,31 +866,12 @@ sub do_template {
     or die $Text::Template::ERROR;
 
   #warn "filling in $template with $fill_in\n";
     or die $Text::Template::ERROR;
 
   #warn "filling in $template with $fill_in\n";
-
-    if($result && ref($result) && $result->{'format'} && $result->{'content'}
-       && $result->{'format'} eq 'csv') {
-       print $cgi->header('-expires' => 'now',
-                       '-Content-Type' => 'text/csv',
-                       '-Content-Disposition' => "attachment;filename=output.csv",
-                       ),
-           $result->{'content'};
-    }
-    elsif($result && ref($result) && $result->{'format'} && $result->{'content'}
-       && $result->{'format'} eq 'xls') {
-       print $cgi->header('-expires' => 'now',
-                       '-Content-Type' => 'application/vnd.ms-excel',
-                       '-Content-Disposition' => "attachment;filename=output.xls",
-                       '-Content-Length' => length($result->{'content'}),
-                       ),
-           $result->{'content'};
-    }
-    else {
-       print $cgi->header( '-expires' => 'now' ),
-           $template->fill_in( PACKAGE => 'FS::SelfService::_selfservicecgi',
-                            HASH    => $fill_in
-                          );
-    }
-
+  my $data = $template->fill_in( 
+    PACKAGE => 'FS::SelfService::_selfservicecgi',
+    HASH    => $fill_in,
+  ) || "Error processing template $source"; # at least print _something_
+  print $cgi->header( '-expires' => 'now' );
+  print $data;
 }
 
 #*FS::SelfService::_selfservicecgi::include = \&Text::Template::fill_in_file;
 }
 
 #*FS::SelfService::_selfservicecgi::include = \&Text::Template::fill_in_file;
index a9909c3..62e35fc 100644 (file)
@@ -48,6 +48,7 @@ my %modules =  (
   'CyberSource'           => 'Business::OnlinePayment',
   'eSec'                  => 'Business::OnlinePayment',
   'eSelectPlus'           => 'Business::OnlinePayment',
   'CyberSource'           => 'Business::OnlinePayment',
   'eSec'                  => 'Business::OnlinePayment',
   'eSelectPlus'           => 'Business::OnlinePayment',
+  'eWayShared'            => 'Business::OnlineThirdPartyPayment',
   'ElavonVirtualMerchant' => 'Business::OnlinePayment',
   'Exact'                 => 'Business::OnlinePayment',
   'iAuthorizer'           => 'Business::OnlinePayment',
   'ElavonVirtualMerchant' => 'Business::OnlinePayment',
   'Exact'                 => 'Business::OnlinePayment',
   'iAuthorizer'           => 'Business::OnlinePayment',
@@ -92,7 +93,7 @@ my %modules =  (
 my @actions = (
                 'Normal Authorization',
                 'Authorization Only',
 my @actions = (
                 'Normal Authorization',
                 'Authorization Only',
-                'Authorization Only, Post Authorization',
+                'Authorization Only,Post Authorization',
               );
 
 my $fields = [
               );
 
 my $fields = [
@@ -117,7 +118,11 @@ my $fields = [
                  type     => 'select',
                  options  => \@actions,
                },
                  type     => 'select',
                  options  => \@actions,
                },
-               'gateway_callback_url',
+               {
+                 field    => 'gateway_callback_url',
+                 type     => 'text',
+                 size     => 40,
+               },
                {
                  field               => 'gateway_options',
                  type                => 'textarea',
                {
                  field               => 'gateway_options',
                  type                => 'textarea',