[freeside-commits] branch master updated. 3be3194b8429383cf47fde8ea662327a0a60d8b0

Mark Wells mark at 420.am
Fri Jun 28 16:43:12 PDT 2013


The branch, master has been updated
       via  3be3194b8429383cf47fde8ea662327a0a60d8b0 (commit)
      from  a281af4caba53bfd4219bab5d07ce4153a83125a (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 3be3194b8429383cf47fde8ea662327a0a60d8b0
Author: Mark Wells <mark at freeside.biz>
Date:   Fri Jun 28 16:42:17 2013 -0700

    new thirdparty payment framework, #23752, #23579, #22395

diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm
index 01e0ebc..b735958 100644
--- a/FS/FS/ClientAPI/MyAccount.pm
+++ b/FS/FS/ClientAPI/MyAccount.pm
@@ -349,6 +349,8 @@ sub access_info {
       $conf->exists('ticket_system-selfservice_edit_subject') && 
       $cust_main->edit_subject;
 
+  $info->{'timeout'} = $conf->config('selfservice-timeout') || 3600;
+
   return { %$info,
            'custnum'       => $custnum,
            'access_pkgnum' => $session->{'pkgnum'},
@@ -845,7 +847,7 @@ sub payment_info {
 
       'save_unchecked' => $conf->exists('selfservice-save_unchecked'),
 
-      'credit_card_surcharge_percentage' => $conf->config('credit-card-surcharge-percentage'),
+      'credit_card_surcharge_percentage' => scalar($conf->config('credit-card-surcharge-percentage')),
     };
 
   }
@@ -1267,6 +1269,50 @@ sub realtime_collect {
   return { 'error' => '', amount => $amount, %$error };
 }
 
+sub start_thirdparty {
+  my $p = shift;
+  my $session = _cache->get($p->{'session_id'})
+    or return { 'error' => "Can't resume session" }; #better error message
+  my $custnum = $session->{'custnum'};
+  my $cust_main = FS::cust_main->by_key($custnum);
+  
+  my $amount = $p->{'amount'}
+    or return { error => 'no amount' };
+
+  my $result = $cust_main->create_payment(
+    'method'      => $p->{'method'},
+    'amount'      => $p->{'amount'},
+    'pkgnum'      => $session->{'pkgnum'},
+    'session_id'  => $p->{'session_id'},
+  );
+  
+  if ( ref($result) ) { # hashref or error
+    return $result;
+  } else {
+    return { error => $result };
+  }
+}
+
+sub finish_thirdparty {
+  my $p = shift;
+  my $session_id = delete $p->{'session_id'};
+  my $session = _cache->get($session_id)
+    or return { 'error' => "Can't resume session" };
+  my $custnum = $session->{'custnum'};
+  my $cust_main = FS::cust_main->by_key($custnum);
+
+  if ( $p->{_cancel} ) {
+    # customer backed out of making a payment
+    return $cust_main->cancel_payment( $session_id );
+  }
+  my $result = $cust_main->execute_payment( $session_id, %$p );
+  if ( ref($result) ) {
+    return $result;
+  } else {
+    return { error => $result };
+  }
+}
+
 sub process_payment_order_pkg {
   my $p = shift;
 
diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm
index b88aa11..5e70b40 100644
--- a/FS/FS/Conf.pm
+++ b/FS/FS/Conf.pm
@@ -2272,6 +2272,12 @@ and customer address. Include units.',
   },
 
   {
+    'key'         => 'selfservice-timeout',
+    'section'     => 'self-service',
+    'description' => 'Timeout for the self-service login cookie, in seconds.  Defaults to 1 hour.',
+  },
+
+  {
     'key'         => 'backend-realtime',
     'section'     => 'billing',
     'description' => 'Run billing for backend signups immediately.',
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index da3ddab..72412c2 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -1576,6 +1576,9 @@ sub tables_hashref {
         #'cust_balance', @money_type,            '', '',
         'paynum',       'int',     'NULL',  '', '', '',
         'jobnum',    'bigint',     'NULL',  '', '', '', 
+        'invnum',       'int',     'NULL',  '', '', '',
+        'manual',       'char',    'NULL',   1, '', '',
+        'discount_term','int',     'NULL',  '', '', '',
       ],
       'primary_key' => 'paypendingnum',
       'unique'      => [ [ 'payunique' ] ],
diff --git a/FS/FS/agent.pm b/FS/FS/agent.pm
index 109343a..57093e3 100644
--- a/FS/FS/agent.pm
+++ b/FS/FS/agent.pm
@@ -230,7 +230,8 @@ 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>, and I<payinfo>.
+Currently available options are I<nofatal>, I<invnum>, I<method>, 
+I<payinfo>, and I<thirdparty>.
 
 If I<nofatal> is set, and no gateway is available, then the empty string
 will be returned instead of throwing a fatal exception.
@@ -245,10 +246,34 @@ as well.  Presently only 'CC', 'ECHECK', and 'PAYPAL' 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.
 
+If I<thirdparty> is set, the defined self-service payment gateway will 
+be returned.
+
 =cut
 
 sub payment_gateway {
   my ( $self, %options ) = @_;
+  
+  my $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 = FS::payment_gateway->by_key($gatewaynum)
+      if $gatewaynum;
+
+    if ( $gateway ) {
+      return $gateway;
+    } elsif ( $options{'nofatal'} ) {
+      return '';
+    } else {
+      die "no third-party gateway configured\n";
+    }
+  }
 
   my $taxclass = '';
   if ( $options{invnum} ) {
@@ -276,8 +301,6 @@ sub payment_gateway {
       $cardtype = cardtype($options{payinfo});
     } elsif ( $options{method} eq 'ECHECK' ) {
       $cardtype = 'ACH';
-    } elsif ( $options{method} eq 'PAYPAL' ) {
-      $cardtype = 'PayPal';
     } else {
       $cardtype = $options{method}
     }
@@ -298,7 +321,6 @@ sub payment_gateway {
                                            taxclass => '',              } );
 
   my $payment_gateway;
-  my $conf = new FS::Conf;
   if ( $override ) { #use a payment gateway override
 
     $payment_gateway = $override->payment_gateway;
diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm
index 7e3e26a..04c2e22 100644
--- a/FS/FS/cust_main.pm
+++ b/FS/FS/cust_main.pm
@@ -6,6 +6,7 @@ use base qw( FS::cust_main::Packages FS::cust_main::Status
              FS::cust_main::NationalID
              FS::cust_main::Billing FS::cust_main::Billing_Realtime
              FS::cust_main::Billing_Discount
+             FS::cust_main::Billing_ThirdParty
              FS::cust_main::Location
              FS::otaker_Mixin FS::payinfo_Mixin FS::cust_main_Mixin
              FS::geocode_Mixin FS::Quotable_Mixin
diff --git a/FS/FS/cust_pay.pm b/FS/FS/cust_pay.pm
index f6954a4..69f4c39 100644
--- a/FS/FS/cust_pay.pm
+++ b/FS/FS/cust_pay.pm
@@ -190,6 +190,15 @@ A hash of optional arguments may be passed.  Currently "manual" is supported.
 If true, a payment receipt is sent instead of a statement when
 'payment_receipt_email' configuration option is set.
 
+About the "manual" flag: Normally, if the 'payment_receipt' config option 
+is set, and the customer has an invoice email address, inserting a payment
+causes a I<statement> to be emailed to the customer.  If the payment is 
+considered "manual" (or if the customer has no invoices), then it will 
+instead send a I<payment receipt>.  "manual" should be true whenever a 
+payment is created directly from the web interface, from a user-initiated
+realtime payment, or from a third-party payment via self-service.  It should
+be I<false> when creating a payment from a billing event or from a batch.
+
 =cut
 
 sub insert {
diff --git a/FS/FS/cust_pay_pending.pm b/FS/FS/cust_pay_pending.pm
index f03ed1f..8e29f08 100644
--- a/FS/FS/cust_pay_pending.pm
+++ b/FS/FS/cust_pay_pending.pm
@@ -128,8 +128,24 @@ Additional status information.
 
 L<FS::payment_gateway> id.
 
-=item paynum - 
+=item paynum
 
+Payment number (L<FS::cust_pay>) of the completed payment.
+
+=item invnum
+
+Invoice number (L<FS::cust_bill>) to try to apply this payment to.
+
+=item manual
+
+Flag for whether this is a "manual" payment (i.e. initiated through 
+self-service or the back-office web interface, rather than from an event
+or a payment batch).  "Manual" payments will cause the customer to be 
+sent a payment receipt rather than a statement.
+
+=item discount_term
+
+Number of months the customer tried to prepay for.
 
 =back
 
@@ -203,6 +219,9 @@ sub check {
     || $self->ut_hexn('session_id')
     || $self->ut_foreign_keyn('paynum', 'cust_pay', 'paynum' )
     || $self->ut_foreign_keyn('pkgnum', 'cust_pkg', 'pkgnum')
+    || $self->ut_foreign_keyn('invnum', 'cust_bill', 'invnum')
+    || $self->ut_flag('manual')
+    || $self->ut_numbern('discount_term')
     || $self->payinfo_check() #payby/payinfo/paymask/paydate
   ;
   return $error if $error;
@@ -296,6 +315,116 @@ sub insert_cust_pay {
 
 }
 
+=item approve OPTIONS
+
+Sets the status of this pending payment to "done" and creates a completed 
+payment (L<FS::cust_pay>).  This should be called when a realtime or 
+third-party payment has been approved.
+
+OPTIONS may include any of 'processor', 'payinfo', 'discount_term', 'auth',
+and 'order_number' to set those fields on the completed payment, as well as 
+'apply' to apply payments for this customer after inserting the new payment.
+
+=cut
+
+sub approve {
+  my $self = shift;
+  my %opt = @_;
+
+  my $dbh = dbh;
+  my $oldAutoCommit = $FS::UID::AutoCommit;
+  local $FS::UID::AutoCommit = 0;
+
+  my $cust_pay = FS::cust_pay->new({
+      'custnum'     => $self->custnum,
+      'invnum'      => $self->invnum,
+      'pkgnum'      => $self->pkgnum,
+      'paid'        => $self->paid,
+      '_date'       => '',
+      'payby'       => $self->payby,
+      'payinfo'     => $self->payinfo,
+      'gatewaynum'  => $self->gatewaynum,
+  });
+  foreach my $opt_field (qw(processor payinfo auth order_number))
+  {
+    $cust_pay->set($opt_field, $opt{$opt_field}) if exists $opt{$opt_field};
+  }
+
+  my %insert_opt = (
+    'manual'        => $self->manual,
+    'discount_term' => $self->discount_term,
+  );
+  my $error = $cust_pay->insert( %insert_opt );
+  if ( $error ) {
+    # try it again without invnum or discount
+    # (both of those can make payments fail to insert, and at this point
+    # the payment is a done deal and MUST be recorded)
+    $self->invnum('');
+    my $error2 = $cust_pay->insert('manual' => $self->manual);
+    if ( $error2 ) {
+      # attempt to void the payment?
+      # no, we'll just stop digging at this point.
+      $dbh->rollback or die $dbh->errstr if $oldAutoCommit;
+      my $e = "WARNING: payment captured but not recorded - error inserting ".
+              "payment (". ($opt{processor} || $self->payby) . 
+              ": $error2\n(previously tried insert with invnum#".$self->invnum.
+              ": $error)\npending payment saved as paypendingnum#".
+              $self->paypendingnum."\n\n";
+      warn $e;
+      return $e;
+    }
+  }
+  if ( my $jobnum = $self->jobnum ) {
+    my $placeholder = FS::queue->by_key($jobnum);
+    my $error;
+    if (!$placeholder) {
+      $error = "not found";
+    } else {
+      $error = $placeholder->delete;
+    }
+
+    if ($error) {
+      $dbh->rollback or die $dbh->errstr if $oldAutoCommit;
+      my $e  = "WARNING: payment captured but could not delete job $jobnum ".
+               "for paypendingnum #" . $self->paypendingnum . ": $error\n\n";
+      warn $e;
+      return $e;
+    }
+  }
+
+  if ( $opt{'paynum_ref'} ) {
+    ${ $opt{'paynum_ref'} } = $cust_pay->paynum;
+  }
+
+  $self->status('done');
+  $self->statustext('captured');
+  $self->paynum($cust_pay->paynum);
+  my $cpp_done_err = $self->replace;
+
+  if ( $cpp_done_err ) {
+
+    $dbh->rollback or die $dbh->errstr if $oldAutoCommit;
+    my $e = "WARNING: payment captured but could not update pending status ".
+            "for paypendingnum ".$self->paypendingnum.": $cpp_done_err \n\n";
+    warn $e;
+    return $e;
+
+  } else {
+
+    # commit at this stage--we don't want to roll back if applying 
+    # payments fails
+    $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+
+    if ( $opt{'apply'} ) {
+      my $apply_error = $self->apply_payments_and_credits;
+      if ( $apply_error ) {
+        warn "WARNING: error applying payment: $apply_error\n\n";
+      }
+    }
+  }
+  '';
+}
+
 =item decline [ STATUSTEXT ]
 
 Sets the status of this pending payment to "done" (with statustext
diff --git a/FS/FS/payment_gateway.pm b/FS/FS/payment_gateway.pm
index e94a62c..68d8418 100644
--- a/FS/FS/payment_gateway.pm
+++ b/FS/FS/payment_gateway.pm
@@ -53,11 +53,11 @@ currently supported:
 
 =item gateway_callback_url - For ThirdPartyPayment only, set to the URL that 
 the user should be redirected to on a successful payment.  This will be sent
-as a transaction parameter (named "callback_url").
+as a transaction parameter named "return_url".
 
 =item gateway_cancel_url - For ThirdPartyPayment only, set to the URL that 
-the user should be redirected to if they cancel the transaction.  PayPal
-requires this; other gateways ignore it.
+the user should be redirected to if they cancel the transaction.  This will 
+be sent as a transaction parameter named "cancel_url".
 
 =item auto_resolve_status - For BatchPayment only, set to 'approve' to 
 auto-approve unresolved payments after some number of days, 'reject' to 
@@ -277,10 +277,6 @@ sub batch_processor {
   eval "use Business::BatchPayment;";
   die "couldn't load Business::BatchPayment: $@" if $@;
 
-  my $conf = new FS::Conf;
-  my $test_mode = $conf->exists('business-batchpayment-test_transaction');
-  $opt{'test_mode'} = 1 if $test_mode;
-
   my $module = $self->gateway_module;
   my $processor = eval { 
     Business::BatchPayment->create($module, $self->options, %opt)
@@ -289,11 +285,46 @@ sub batch_processor {
     if $@;
 
   die "$module does not support test mode"
-    if $test_mode and not $processor->does('Business::BatchPayment::TestMode');
+    if $opt{'test_mode'}
+      and not $processor->does('Business::BatchPayment::TestMode');
 
   return $processor;
 }
 
+=item processor OPTIONS
+
+Loads the module for the processor and returns an instance of it.
+
+=cut
+
+sub processor {
+  local $@;
+  my $self = shift;
+  my %opt = @_;
+  foreach (qw(action username password)) {
+    if (length($self->get("gateway_$_"))) {
+      $opt{$_} = $self->get("gateway_$_");
+    }
+  }
+  $opt{'return_url'} = $self->gateway_callback_url;
+  $opt{'cancel_url'} = $self->gateway_cancel_url;
+
+  my $conf = new FS::Conf;
+  my $test_mode = $conf->exists('business-batchpayment-test_transaction');
+  $opt{'test_mode'} = 1 if $test_mode;
+
+  my $namespace = $self->gateway_namespace;
+  eval "use $namespace";
+  die "couldn't load $namespace: $@" if $@;
+
+  if ( $namespace eq 'Business::BatchPayment' ) {
+    # at some point we can merge these, but there's enough special behavior...
+    return $self->batch_processor(%opt);
+  } else {
+    return $namespace->new( $self->gateway_module, $self->options, %opt );
+  }
+}
+
 # _upgrade_data
 #
 # Used by FS::Upgrade to migrate to a new database.
diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm
index d44f978..9da40b9 100644
--- a/fs_selfservice/FS-SelfService/SelfService.pm
+++ b/fs_selfservice/FS-SelfService/SelfService.pm
@@ -109,6 +109,9 @@ $socket .= '.'.$tag if defined $tag && length($tag);
   'call_time'                 => 'PrepaidPhone/call_time',
   'call_time_nanpa'           => 'PrepaidPhone/call_time_nanpa',
   'phonenum_balance'          => 'PrepaidPhone/phonenum_balance',
+
+  'start_thirdparty'          => 'MyAccount/start_thirdparty',
+  'finish_thirdparty'         => 'MyAccount/finish_thirdparty',
 );
 @EXPORT_OK = (
   keys(%autoload),
diff --git a/fs_selfservice/FS-SelfService/cgi/ach_payment_results.html b/fs_selfservice/FS-SelfService/cgi/ach_payment_results.html
index 9cdb65e..9c60222 100644
--- a/fs_selfservice/FS-SelfService/cgi/ach_payment_results.html
+++ b/fs_selfservice/FS-SelfService/cgi/ach_payment_results.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', 'Payment results') %>
 
 <%= if ( $error ) {
diff --git a/fs_selfservice/FS-SelfService/cgi/agent_customer_menu.html b/fs_selfservice/FS-SelfService/cgi/agent_customer_menu.html
index 603fc0b..1e986e1 100644
--- a/fs_selfservice/FS-SelfService/cgi/agent_customer_menu.html
+++ b/fs_selfservice/FS-SelfService/cgi/agent_customer_menu.html
@@ -1,4 +1,4 @@
-<%= $url = "$selfurl?session=$session_id;custnum=$custnum;action="; ''; %>
+<%= $url = "$selfurl?action="; ''; %>
 <TD VALIGN="top" HEIGHT=384 BGCOLOR="#dddddd">
 <A HREF="<%= $url %>agent_provision">Setup services</A><BR><BR>
 <A HREF="<%= $url %>agent_order_pkg">Purchase additional package</A><BR><BR>
diff --git a/fs_selfservice/FS-SelfService/cgi/change_bill.html b/fs_selfservice/FS-SelfService/cgi/change_bill.html
index 7941971..06ea12b 100755
--- a/fs_selfservice/FS-SelfService/cgi/change_bill.html
+++ b/fs_selfservice/FS-SelfService/cgi/change_bill.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', 'Edit billing address') %>
 
 <%= if ( $error ) { 
@@ -6,7 +5,6 @@
 }  ''; %>
 
 <FORM NAME="ChangeBillForm" ACTION="<%= $selfurl %>" METHOD=POST onSubmit="document.bottomform.submit.disabled=true;">
-<INPUT TYPE="hidden" NAME="session" VALUE="<%= $session_id %>">
 <INPUT TYPE="hidden" NAME="action" VALUE="process_change_bill">
 <TABLE BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0>
 
diff --git a/fs_selfservice/FS-SelfService/cgi/change_password.html b/fs_selfservice/FS-SelfService/cgi/change_password.html
index 68b6fd8..22d8973 100644
--- a/fs_selfservice/FS-SelfService/cgi/change_password.html
+++ b/fs_selfservice/FS-SelfService/cgi/change_password.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', 'Change password') %>
 
 <%= if ( $error ) {
@@ -6,7 +5,6 @@
 } ''; %>
 
 <FORM ACTION="<%= $selfurl %>" METHOD="POST">
-<INPUT TYPE="hidden" NAME="session" VALUE="<%= $session_id %>">
 <INPUT TYPE="hidden" NAME="action" VALUE="process_change_password">
 
 <TABLE BGCOLOR="#cccccc">
diff --git a/fs_selfservice/FS-SelfService/cgi/change_pay.html b/fs_selfservice/FS-SelfService/cgi/change_pay.html
index 9633e89..6898dc7 100644
--- a/fs_selfservice/FS-SelfService/cgi/change_pay.html
+++ b/fs_selfservice/FS-SelfService/cgi/change_pay.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', 'Change payment information') %>
 
 <%= if ( $error ) { 
@@ -13,7 +12,7 @@
   my $preauto = '<TR><TD COLSPAN=3><INPUT TYPE="checkbox" NAME="auto" VALUE="1"';
   my $postauto = '>Charge future payments to this card automatically</TD></TR>';
 
-  my $tail = qq(</TABLE><INPUT TYPE="hidden" NAME="session" VALUE="$session_id">). 
+  my $tail = qq(</TABLE>).
              qq(<INPUT TYPE="hidden" NAME="action" VALUE="process_change_pay">).
              qq(<BR>).
              qq(<INPUT TYPE="submit" NAME="process" ).
diff --git a/fs_selfservice/FS-SelfService/cgi/change_pkg.html b/fs_selfservice/FS-SelfService/cgi/change_pkg.html
index 2d7b488..5006706 100644
--- a/fs_selfservice/FS-SelfService/cgi/change_pkg.html
+++ b/fs_selfservice/FS-SelfService/cgi/change_pkg.html
@@ -12,7 +12,6 @@ function enable_change_pkg () {
   $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">$error</FONT><BR><BR>!;
 } ''; %>
 <FORM NAME="ChangePkgForm" ACTION="<%= $selfurl %>" METHOD=POST>
-<INPUT TYPE="hidden" NAME="session" VALUE="<%= $session_id %>">
 <INPUT TYPE="hidden" NAME="action" VALUE="process_change_pkg">
 <INPUT TYPE="hidden" NAME="pkgnum" VALUE="<%= encode_entities($pkgnum) %>">
 <INPUT TYPE="hidden" NAME="pkg" VALUE="<%= encode_entities($pkg) %>">
diff --git a/fs_selfservice/FS-SelfService/cgi/change_ship.html b/fs_selfservice/FS-SelfService/cgi/change_ship.html
index 59f9176..ecd20dc 100755
--- a/fs_selfservice/FS-SelfService/cgi/change_ship.html
+++ b/fs_selfservice/FS-SelfService/cgi/change_ship.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', 'Edit service address') %>
 
 <%= if ( $error ) { 
@@ -6,7 +5,6 @@
 }  ''; %>
 
 <FORM NAME="OneTrueForm" ACTION="<%= $selfurl %>" METHOD=POST onSubmit="document.bottomform.submit.disabled=true;">
-<INPUT TYPE="hidden" NAME="session" VALUE="<%= $session_id %>">
 <INPUT TYPE="hidden" NAME="action" VALUE="process_change_ship">
 <TABLE BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0>
 
diff --git a/fs_selfservice/FS-SelfService/cgi/customer_change_pkg.html b/fs_selfservice/FS-SelfService/cgi/customer_change_pkg.html
index 37dccaa..047f880 100644
--- a/fs_selfservice/FS-SelfService/cgi/customer_change_pkg.html
+++ b/fs_selfservice/FS-SelfService/cgi/customer_change_pkg.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', 'Change package') %>
 
 <%= include('change_pkg') %>
diff --git a/fs_selfservice/FS-SelfService/cgi/customer_order_pkg.html b/fs_selfservice/FS-SelfService/cgi/customer_order_pkg.html
index 192c29f..5fcf77f 100755
--- a/fs_selfservice/FS-SelfService/cgi/customer_order_pkg.html
+++ b/fs_selfservice/FS-SelfService/cgi/customer_order_pkg.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', 'Purchase additional package') %>
 
 <%= include('order_pkg') %>
diff --git a/fs_selfservice/FS-SelfService/cgi/delete_svc.html b/fs_selfservice/FS-SelfService/cgi/delete_svc.html
index 80a14f8..e2b2678 100644
--- a/fs_selfservice/FS-SelfService/cgi/delete_svc.html
+++ b/fs_selfservice/FS-SelfService/cgi/delete_svc.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', 'Remove service') %>
 
 <%= if ( $error ) {
diff --git a/fs_selfservice/FS-SelfService/cgi/finish_thirdparty_payment.html b/fs_selfservice/FS-SelfService/cgi/finish_thirdparty_payment.html
new file mode 100644
index 0000000..79c02cc
--- /dev/null
+++ b/fs_selfservice/FS-SelfService/cgi/finish_thirdparty_payment.html
@@ -0,0 +1,22 @@
+<%= include('header', 'Payment confirmation') %>
+
+<TABLE BGCOLOR="#cccccc">
+<%= if ( $error ) {
+  $OUT .= '<FONT SIZE=+1><B>Payment processing error</B></FONT><BR>'.$error;
+} else {
+  $OUT .= '
+<TR><TH COLSPAN=2><FONT SIZE=+1><B>Your payment details</B></FONT></TH></TR>
+<TR>
+  <TD ALIGN="right">Payment #</TD>
+  <TD BGCOLOR="#ffffff"><B>' . $paynum . '</B></TD>
+</TR>
+<TR>
+  <TD ALIGN="right">Payment amount</TH>
+  <TD BGCOLOR="#ffffff"><B>' . sprintf('$%.2f', $paid) . '</B></TD>
+</TR>
+<TR>
+  <TD ALIGN="right">Processing #</TD>
+  <TD BGCOLOR="#ffffff"><B>' . $order_number . '</B></TD>
+</TR>';
+} %>
+<%= include('footer') %>
diff --git a/fs_selfservice/FS-SelfService/cgi/invoices.html b/fs_selfservice/FS-SelfService/cgi/invoices.html
index d155b93..7528051 100644
--- a/fs_selfservice/FS-SelfService/cgi/invoices.html
+++ b/fs_selfservice/FS-SelfService/cgi/invoices.html
@@ -1,4 +1,4 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
+<%= $url = "$selfurl?action="; ''; %>
 <%= include('header', 'All Invoices') %>
 
 <%=
diff --git a/fs_selfservice/FS-SelfService/cgi/list_customers.html b/fs_selfservice/FS-SelfService/cgi/list_customers.html
index 7fe7fa4..9746347 100644
--- a/fs_selfservice/FS-SelfService/cgi/list_customers.html
+++ b/fs_selfservice/FS-SelfService/cgi/list_customers.html
@@ -1,6 +1,6 @@
 <HTML><HEAD><TITLE>Reseller</TITLE></HEAD>
 <BODY BGCOLOR="#eeeeee"><FONT SIZE=5>Reseller</FONT><BR><BR>
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
+<%= $url = "$selfurl?action="; ''; %>
 <TABLE BORDER=0 CELLPADDING=4><TR>
 <%= include('agent_menu') %>
 <TD VALIGN="top">
diff --git a/fs_selfservice/FS-SelfService/cgi/login.html b/fs_selfservice/FS-SelfService/cgi/login.html
index f7473b1..68f3ae4 100644
--- a/fs_selfservice/FS-SelfService/cgi/login.html
+++ b/fs_selfservice/FS-SelfService/cgi/login.html
@@ -10,7 +10,7 @@
 <FONT SIZE="+1" COLOR="#ff0000"><%= $error %></FONT>
 
 <FORM ACTION="<%= $self_url %>" METHOD=POST>
-<INPUT TYPE="hidden" NAME="session" VALUE="login">
+<INPUT TYPE="hidden" NAME="action" VALUE="myaccount">
 <INPUT TYPE="hidden" NAME="agentnum" VALUE="<%= $agentnum %>">
 
 <TABLE BGCOLOR="<%= $box_bgcolor || '#c0c0c0' %>" BORDER=0 CELLSPACING=2 CELLPADDING=0>
@@ -65,7 +65,6 @@ if ( $phone_login ) {
     <B>OR</B><BR><BR>
     
     <FORM ACTION="$self_url" METHOD=POST>
-    <INPUT TYPE="hidden" NAME="session" VALUE="login">
     <TABLE BGCOLOR="$box_bgcolor" BORDER=0 CELLSPACING=2 CELLPADDING=0>
     <TR>
       <TH ALIGN="right">Phone number </TH>
diff --git a/fs_selfservice/FS-SelfService/cgi/logout.html b/fs_selfservice/FS-SelfService/cgi/logout.html
index 5e22ad8..834ef13 100644
--- a/fs_selfservice/FS-SelfService/cgi/logout.html
+++ b/fs_selfservice/FS-SelfService/cgi/logout.html
@@ -1,5 +1,6 @@
 <HTML>
   <HEAD>
+    <META HTTP-EQUIV="refresh" CONTENT="5;URL=<%= $cgi->url(-absolute => 1) %>">
     <TITLE>MyAccount</TITLE>
     <%= $head %>
   </HEAD>
diff --git a/fs_selfservice/FS-SelfService/cgi/make_ach_payment.html b/fs_selfservice/FS-SelfService/cgi/make_ach_payment.html
index 5b81b00..e33ad57 100644
--- a/fs_selfservice/FS-SelfService/cgi/make_ach_payment.html
+++ b/fs_selfservice/FS-SelfService/cgi/make_ach_payment.html
@@ -1,8 +1,6 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= 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="ach_payment_results">
 <TABLE BGCOLOR="#cccccc">
 <TR>
diff --git a/fs_selfservice/FS-SelfService/cgi/make_payment.html b/fs_selfservice/FS-SelfService/cgi/make_payment.html
index defd4a5..915714c 100644
--- a/fs_selfservice/FS-SelfService/cgi/make_payment.html
+++ b/fs_selfservice/FS-SelfService/cgi/make_payment.html
@@ -1,8 +1,6 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= 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="payment_results">
 <TABLE BGCOLOR="#cccccc">
 <TR>
diff --git a/fs_selfservice/FS-SelfService/cgi/make_thirdparty_payment.html b/fs_selfservice/FS-SelfService/cgi/make_thirdparty_payment.html
index 59ee93b..9a5678e 100755
--- a/fs_selfservice/FS-SelfService/cgi/make_thirdparty_payment.html
+++ b/fs_selfservice/FS-SelfService/cgi/make_thirdparty_payment.html
@@ -1,15 +1,12 @@
-<%= $url = "$selfurl?session=$session_id;action="; 
-  $cgi = new CGI;
-  ''; %>
 <%= include('header', 'Make a payment') %>
+<%= if ( $error ) {
+  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">$error</FONT><BR><BR>!;
+} ''; %>
 
 <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|PAYPAL)/;
-$1 %>">
+<INPUT TYPE="hidden" NAME="payby_method" VALUE="<%= $payby_method %>">
 <TABLE BGCOLOR="#cccccc">
 <TR>
   <TH ALIGN="right">Balance due</TH>
diff --git a/fs_selfservice/FS-SelfService/cgi/myaccount.html b/fs_selfservice/FS-SelfService/cgi/myaccount.html
index a6352e0..66e2c69 100644
--- a/fs_selfservice/FS-SelfService/cgi/myaccount.html
+++ b/fs_selfservice/FS-SelfService/cgi/myaccount.html
@@ -1,4 +1,4 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
+<%= $url = "$selfurl?action="; ''; %>
 <%= include('header', 'My Account') %>
 
 Hello <%= $name %>!<BR><BR>
diff --git a/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html b/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html
index cf719e8..7d1a5f7 100644
--- a/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html
+++ b/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html
@@ -1,4 +1,4 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
+<%= $url = "$selfurl?action="; ''; %>
 <TABLE BORDER=0><TR>
 <TD VALIGN="top" BGCOLOR="<%= $menu_bgcolor || $box_bgcolor || '#c0c0c0' %>">
 
diff --git a/fs_selfservice/FS-SelfService/cgi/order_pkg.html b/fs_selfservice/FS-SelfService/cgi/order_pkg.html
index 79335a0..84a10ab 100644
--- a/fs_selfservice/FS-SelfService/cgi/order_pkg.html
+++ b/fs_selfservice/FS-SelfService/cgi/order_pkg.html
@@ -12,7 +12,6 @@ function enable_order_pkg () {
   $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">$error</FONT><BR><BR>!;
 } ''; %>
 <FORM NAME="OrderPkgForm" ACTION="<%= $selfurl %>" METHOD=POST>
-<INPUT TYPE="hidden" NAME="session" VALUE="<%= $session_id %>">
 <INPUT TYPE="hidden" NAME="action" VALUE="process_order_pkg">
 <INPUT TYPE="hidden" NAME="custnum" VALUE="<%= $custnum %>">
 <TABLE BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0>
diff --git a/fs_selfservice/FS-SelfService/cgi/payment_results.html b/fs_selfservice/FS-SelfService/cgi/payment_results.html
index be727cb..04a0611 100644
--- a/fs_selfservice/FS-SelfService/cgi/payment_results.html
+++ b/fs_selfservice/FS-SelfService/cgi/payment_results.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', 'Payment results') %>
 
 <%= if ( $error ) {
diff --git a/fs_selfservice/FS-SelfService/cgi/post_thirdparty_payment.html b/fs_selfservice/FS-SelfService/cgi/post_thirdparty_payment.html
index 17710b2..ed7c2a3 100644
--- a/fs_selfservice/FS-SelfService/cgi/post_thirdparty_payment.html
+++ b/fs_selfservice/FS-SelfService/cgi/post_thirdparty_payment.html
@@ -1,42 +1,21 @@
-<%= $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>!
+<HTML>
+  <HEAD>
+    <TITLE>Redirecting to payment processor...</TITLE>
+  </HEAD>
+  <BODY>
+    <H1>Redirecting to payment processor...</H1>
+    <FORM ID="autoform" ENCTYPE="multipart/form-data" ACTION="<%= $url %>" METHOD="POST" STYLE="display:none">
+<%= foreach my $name (keys %post_params) {
+  my $value = encode_entities($post_params{$name});
+  $OUT .= '
+      <INPUT NAME="' . $name . '" TYPE="hidden" VALUE="' . $value . '">';
+} %>
+    <INPUT TYPE="submit" VALUE="submit">
+    </FORM>
+    <SCRIPT TYPE="text/javascript">
+window.onload = function() {
+  document.getElementById('autoform').submit();
 }
-%>
-
-<%=
-#<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') %>
+    </SCRIPT>
+  </BODY>
+</HTML>
diff --git a/fs_selfservice/FS-SelfService/cgi/process_change_bill.html b/fs_selfservice/FS-SelfService/cgi/process_change_bill.html
index bf7ad77..795cc12 100644
--- a/fs_selfservice/FS-SelfService/cgi/process_change_bill.html
+++ b/fs_selfservice/FS-SelfService/cgi/process_change_bill.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', 'Information updated successfully') %>
 <FONT SIZE=4>Information updated successfully.</FONT>
 <%= include('footer') %>
diff --git a/fs_selfservice/FS-SelfService/cgi/process_change_password.html b/fs_selfservice/FS-SelfService/cgi/process_change_password.html
index 4eca91f..d16c460 100644
--- a/fs_selfservice/FS-SelfService/cgi/process_change_password.html
+++ b/fs_selfservice/FS-SelfService/cgi/process_change_password.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', "Password changed" ) %>
 
 <FONT SIZE=4>Password changed for <%= $value %> <%= $label %>.</FONT>
diff --git a/fs_selfservice/FS-SelfService/cgi/process_change_pay.html b/fs_selfservice/FS-SelfService/cgi/process_change_pay.html
index e399aea..8fb33b2 100644
--- a/fs_selfservice/FS-SelfService/cgi/process_change_pay.html
+++ b/fs_selfservice/FS-SelfService/cgi/process_change_pay.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', 'Information updated successfully' ) %>
 <FONT SIZE=4>Information updated successfully.</FONT>
 <%= include('footer') %>
diff --git a/fs_selfservice/FS-SelfService/cgi/process_change_pkg.html b/fs_selfservice/FS-SelfService/cgi/process_change_pkg.html
index bf15b6e..126e2a4 100644
--- a/fs_selfservice/FS-SelfService/cgi/process_change_pkg.html
+++ b/fs_selfservice/FS-SelfService/cgi/process_change_pkg.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', 'Package change successful') %>
 
 <%= include('footer') %>
diff --git a/fs_selfservice/FS-SelfService/cgi/process_change_ship.html b/fs_selfservice/FS-SelfService/cgi/process_change_ship.html
index bf7ad77..795cc12 100644
--- a/fs_selfservice/FS-SelfService/cgi/process_change_ship.html
+++ b/fs_selfservice/FS-SelfService/cgi/process_change_ship.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', 'Information updated successfully') %>
 <FONT SIZE=4>Information updated successfully.</FONT>
 <%= include('footer') %>
diff --git a/fs_selfservice/FS-SelfService/cgi/process_order_pkg.html b/fs_selfservice/FS-SelfService/cgi/process_order_pkg.html
index 649d920..b76dafb 100755
--- a/fs_selfservice/FS-SelfService/cgi/process_order_pkg.html
+++ b/fs_selfservice/FS-SelfService/cgi/process_order_pkg.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', 'Package order successful') %>
 
 <FONT SIZE=4>Package order successful.</FONT>
diff --git a/fs_selfservice/FS-SelfService/cgi/process_order_recharge.html b/fs_selfservice/FS-SelfService/cgi/process_order_recharge.html
index 4a16ec5..659f110 100644
--- a/fs_selfservice/FS-SelfService/cgi/process_order_recharge.html
+++ b/fs_selfservice/FS-SelfService/cgi/process_order_recharge.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', "$svc recharged successfully") %>
 
 <FONT SIZE=4><%= $svc %> recharged successfully.</FONT>
diff --git a/fs_selfservice/FS-SelfService/cgi/process_suspend_pkg.html b/fs_selfservice/FS-SelfService/cgi/process_suspend_pkg.html
index d5c62f4..2a9805f 100644
--- a/fs_selfservice/FS-SelfService/cgi/process_suspend_pkg.html
+++ b/fs_selfservice/FS-SelfService/cgi/process_suspend_pkg.html
@@ -1,3 +1,2 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', 'Package suspended') %>
 <%= include('footer') %>
diff --git a/fs_selfservice/FS-SelfService/cgi/process_svc_acct.html b/fs_selfservice/FS-SelfService/cgi/process_svc_acct.html
index d6515e7..48f6a85 100644
--- a/fs_selfservice/FS-SelfService/cgi/process_svc_acct.html
+++ b/fs_selfservice/FS-SelfService/cgi/process_svc_acct.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', "$svc setup successfully") %>
 
 <FONT SIZE=4><%= $svc %> setup successfully.</FONT>
diff --git a/fs_selfservice/FS-SelfService/cgi/process_svc_external.html b/fs_selfservice/FS-SelfService/cgi/process_svc_external.html
index c20aae0..48d70b0 100644
--- a/fs_selfservice/FS-SelfService/cgi/process_svc_external.html
+++ b/fs_selfservice/FS-SelfService/cgi/process_svc_external.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', "$svc setup successfully") %>
 
 <FONT SIZE=4><%= $svc %> setup successfully.</FONT>
diff --git a/fs_selfservice/FS-SelfService/cgi/process_svc_phone.html b/fs_selfservice/FS-SelfService/cgi/process_svc_phone.html
index d6515e7..48f6a85 100644
--- a/fs_selfservice/FS-SelfService/cgi/process_svc_phone.html
+++ b/fs_selfservice/FS-SelfService/cgi/process_svc_phone.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', "$svc setup successfully") %>
 
 <FONT SIZE=4><%= $svc %> setup successfully.</FONT>
diff --git a/fs_selfservice/FS-SelfService/cgi/provision.html b/fs_selfservice/FS-SelfService/cgi/provision.html
index cd8028a..808e4b5 100644
--- a/fs_selfservice/FS-SelfService/cgi/provision.html
+++ b/fs_selfservice/FS-SelfService/cgi/provision.html
@@ -1,5 +1,4 @@
-<%= $url = "$selfurl?session=$session_id;action="; 
-    $heading1 = "Setup my services";
+<%= $heading1 = "Setup my services";
     $heading1 = "Package list" if $wholesale_view;
     $provision_list = "provision_list";
     $provision_list = "ws_list" if $wholesale_view;
diff --git a/fs_selfservice/FS-SelfService/cgi/provision_svc_acct.html b/fs_selfservice/FS-SelfService/cgi/provision_svc_acct.html
index bae5730..c63a838 100644
--- a/fs_selfservice/FS-SelfService/cgi/provision_svc_acct.html
+++ b/fs_selfservice/FS-SelfService/cgi/provision_svc_acct.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', 'Setup account') %>
 
 <%= include('svc_acct') %>
diff --git a/fs_selfservice/FS-SelfService/cgi/provision_svc_phone.html b/fs_selfservice/FS-SelfService/cgi/provision_svc_phone.html
index 9a07e7d..9ac039d 100644
--- a/fs_selfservice/FS-SelfService/cgi/provision_svc_phone.html
+++ b/fs_selfservice/FS-SelfService/cgi/provision_svc_phone.html
@@ -1,5 +1,4 @@
-<%= $url = "$selfurl?session=$session_id;action="; 
- $heading2 = $lnp ? "Port-In Number" : "Setup phone number";
+<%= $heading2 = $lnp ? "Port-In Number" : "Setup phone number";
  '';
 %>
 <%= include('header', $heading2) %>
@@ -15,8 +14,7 @@ if($error) {
 }
 %>
 
-<FORM name="OneTrueForm" action="<%= $url %>" METHOD="POST">
-<INPUT TYPE="hidden" NAME="session" VALUE="<%= $session_id %>">
+<FORM name="OneTrueForm" action="<%= $selfurl %>" METHOD="POST">
 <INPUT TYPE="hidden" NAME="action" VALUE="process_svc_phone">
 <INPUT TYPE="hidden" NAME="pkgnum" VALUE="<%= $pkgnum %>">
 <INPUT TYPE="hidden" NAME="svcpart" VALUE="<%= $svcpart %>">
diff --git a/fs_selfservice/FS-SelfService/cgi/recharge_prepay.html b/fs_selfservice/FS-SelfService/cgi/recharge_prepay.html
index c716e82..e47f800 100644
--- a/fs_selfservice/FS-SelfService/cgi/recharge_prepay.html
+++ b/fs_selfservice/FS-SelfService/cgi/recharge_prepay.html
@@ -1,8 +1,6 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', 'Recharge with prepaid card') %>
 
 <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="recharge_results">
 <TABLE BGCOLOR="#cccccc">
 <!--
diff --git a/fs_selfservice/FS-SelfService/cgi/recharge_results.html b/fs_selfservice/FS-SelfService/cgi/recharge_results.html
index 147b66b..919977a 100644
--- a/fs_selfservice/FS-SelfService/cgi/recharge_results.html
+++ b/fs_selfservice/FS-SelfService/cgi/recharge_results.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', 'Recharge results') %>
 
 <%= if ( $error ) {
diff --git a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi
index 40fe98a..ea2a40b 100755
--- a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi
+++ b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi
@@ -1,10 +1,11 @@
-#!/usr/bin/perl -Tw
+#!/usr/bin/perl -w
 
 use strict;
 use vars qw($DEBUG $cgi $session_id $form_max $template_dir);
 use subs qw(do_template);
 use CGI;
 use CGI::Carp qw(fatalsToBrowser);
+use CGI::Cookie;
 use Text::Template;
 use HTML::Entities;
 use Date::Format;
@@ -20,6 +21,7 @@ use FS::SelfService qw(
   myaccount_passwd list_invoices create_ticket get_ticket did_report
   adjust_ticket_priority
   mason_comp port_graph
+  start_thirdparty finish_thirdparty
 );
 
 $template_dir = '.';
@@ -29,49 +31,85 @@ $DEBUG = 0;
 $form_max = 255;
 
 $cgi = new CGI;
+my %cookies = CGI::Cookie->fetch;
 
-unless ( defined $cgi->param('session') ) {
-  my $login_info = login_info( 'agentnum' => scalar($cgi->param('agentnum')) );
+my $login_rv;
 
-  do_template('login', $login_info );
-  exit;
-}
+if ( exists($cookies{'session'}) ) {
 
-if ( $cgi->param('session') eq 'login' ) {
+  $session_id = $cookies{'session'}->value;
 
-  $cgi->param('username') =~ /^\s*([a-z0-9_\-\.\&]{0,$form_max})\s*$/i
-    or die "illegal username";
-  my $username = $1;
+  if ( $session_id eq 'login' ) {
+    # then we've just come back from the login page
 
-  $cgi->param('domain') =~ /^\s*([\w\-\.]{0,$form_max})\s*$/
-    or die "illegal domain";
-  my $domain = $1;
+    $cgi->param('username') =~ /^\s*([a-z0-9_\-\.\&]{0,$form_max})\s*$/i;
+    my $username = $1;
 
-  $cgi->param('password') =~ /^(.{0,$form_max})$/
-    or die "illegal password";
-  my $password = $1;
+    $cgi->param('domain') =~ /^\s*([\w\-\.]{0,$form_max})\s*$/;
+    my $domain = $1;
 
-  my $rv = login(
-    'username' => $username,
-    'domain'   => $domain,
-    'password' => $password,
-  );
-  if ( $rv->{error} ) {
-    my $login_info = login_info( 'agentnum' => $cgi->param('agentnum') );
-    do_template('login', {
-      'error'    => $rv->{error},
-      'username' => $username,
-      'domain'   => $domain,
-      %$login_info,
-    } );
-    exit;
-  } else {
-    $cgi->param('session' => $rv->{session_id} );
-    $cgi->param('action'  => 'myaccount' );
-  }
+    $cgi->param('password') =~ /^(.{0,$form_max})$/;
+    my $password = $1;
+
+    if ( $username and $domain and $password ) {
+
+      # authenticate
+      $login_rv = login(
+        'username' => $username,
+        'domain'   => $domain,
+        'password' => $password,
+      );
+      $session_id = $login_rv->{'session_id'};
+
+    } elsif ( $username or $domain or $password ) {
+      
+      my $error = 'Illegal '; #XXX localization...
+      my $count = 0;
+      if ( !$username ) {
+        $error .= 'username';
+        $count++;
+      }
+      if ( !$domain )  {
+        $error .= ', ' if $count;
+        $error .= 'domain';
+        $count++;
+      }
+      if ( !$password ) {
+        $error .= ', ' if $count;
+        $error .= 'and ' if $count > 1;
+        $error .= 'password';
+        $count++;
+      }
+      $error .= '.';
+      $login_rv = {
+        'username'  => $username,
+        'domain'    => $domain,
+        'password'  => $password,
+        'error'     => $error,
+      };
+      $session_id = undef; # attempt login again
+
+    } # else there was no input, so show no error message
+  } # else session_id ne 'login'
+
+} else {
+  # there is no session cookie
+  $login_rv = {};
 }
 
-$session_id = $cgi->param('session');
+if ( !$session_id ) {
+  # XXX why are we getting agentnum from a CGI param? surely it should 
+  # be some kind of configuration option.
+  #
+  # show the login page
+  $session_id = 'login'; # set state
+  my $login_info = login_info( 'agentnum' => scalar($cgi->param('agentnum')) );
+
+  do_template('login', { %$login_rv, %$login_info });
+  exit;
+}
+
+# at this point $session_id is a real session
 
 #order|pw_list XXX ???
 my @actions = ( qw(
@@ -87,6 +125,8 @@ my @actions = ( qw(
   make_term_payment
   make_thirdparty_payment
   post_thirdparty_payment
+  finish_thirdparty_payment
+  cancel_thirdparty_payment
   payment_results
   ach_payment_results
   recharge_prepay
@@ -120,10 +160,15 @@ my @actions = ( qw(
   customer_suspend_pkg
   process_suspend_pkg
 ));
- 
-$cgi->param('action') =~ ( '^(' . join('|', @actions) . ')$' )
-  or die "unknown action ". $cgi->param('action');
-my $action = $1;
+
+my $action = 'myaccount'; # sensible default
+if ( $cgi->param('action') =~ /^(\w+)$/ ) {
+  if (grep {$_ eq $1} @actions) {
+    $action = $1;
+  } else {
+    warn "WARNING: unrecognized action '$1'\n";
+  }
+}
 
 warn "calling $action sub\n"
   if $DEBUG;
@@ -136,6 +181,7 @@ warn Dumper($result) if $DEBUG;
 if ( $result->{error} && ( $result->{error} eq "Can't resume session"
   || $result->{error} eq "Expired session") ) { #ick
 
+  $session_id = 'login';
   my $login_info = login_info();
   do_template('login', $login_info);
   exit;
@@ -663,7 +709,13 @@ sub ach_payment_results {
 }
 
 sub make_thirdparty_payment {
-  payment_info('session_id' => $session_id);
+  my $payment_info = payment_info('session_id' => $session_id);
+  $cgi->param('payby_method') =~ /^(CC|ECHECK|PAYPAL)$/
+    or die "illegal payby method";
+  $payment_info->{'payby_method'} = $1;
+  $payment_info->{'error'} = $cgi->param('error');
+
+  $payment_info;
 }
 
 sub post_thirdparty_payment {
@@ -673,17 +725,32 @@ sub post_thirdparty_payment {
   $cgi->param('amount') =~ /^(\d+(\.\d*)?)$/
     or die "illegal amount";
   my $amount = $1;
-  # realtime_collect() returns the result from FS::cust_main->realtime_collect
-  # which returns realtime_bop()
-  # which returns a hashref of popup_url, collectitems, and reference
-  my $result = realtime_collect( 
+  my $result = start_thirdparty(
     'session_id' => $session_id,
     'method' => $method, 
     'amount' => $amount,
   );
+  if ( $result->{error} ) {
+    $cgi->param('action', 'make_thirdparty_payment');
+    $cgi->param('error', $result->{error});
+    print $cgi->redirect( $cgi->self_url );
+    exit;
+  }
+
   $result;
 }
 
+sub finish_thirdparty_payment {
+  my %param = $cgi->Vars;
+  finish_thirdparty( 'session_id' => $session_id, %param );
+  # result contains either 'error' => error message, or the payment details
+}
+
+sub cancel_thirdparty_payment {
+  $action = 'make_thirdparty_payment';
+  finish_thirdparty( 'session_id' => $session_id, '_cancel' => 1 );
+}
+
 sub make_term_payment {
   $cgi->param('amount') =~ /^(\d+\.\d{2})$/
     or die "illegal payment amount";
@@ -933,54 +1000,63 @@ sub do_template {
   $cgi->delete_all();
   $fill_in->{'selfurl'} = $cgi->self_url;
   $fill_in->{'cgi'} = \$cgi;
+  $fill_in->{'error'} = $cgi->param('error') if $cgi->param('error');
 
-  my $access_info = $session_id
+  my $access_info = ($session_id and $session_id ne 'login')
                       ? access_info( 'session_id' => $session_id )
                       : {};
   $fill_in->{$_} = $access_info->{$_} foreach keys %$access_info;
 
-  
-    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'};
-    }
-    elsif($result && ref($result) && $result->{'format'} && $result->{'content'}
-    	 && $result->{'format'} eq 'png') {
-	print $cgi->header('-expires' => 'now',
-		    '-Content-Type' => 'image/png',
-		    ),
-		    $result->{'content'};
-    }
-    else {
-	my $source = "$template_dir/$name.html";
-        my $template = new Text::Template( TYPE       => 'FILE',
-					 SOURCE     => $source,
-					 DELIMITERS => [ '<%=', '%>' ],
-					 UNTAINT    => 1,
-				       )
-	or die $Text::Template::ERROR;
-
-	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;
+  # update the user's authentication
+  my $timeout = $access_info->{'timeout'} || '60';
+  my $cookie = CGI::Cookie->new('-name'     => 'session',
+                                '-value'    => $session_id,
+                                '-expires'  => '+'.$timeout,
+                                #'-secure'   => 1, # would be a good idea...
+                               );
+  if ( $name eq 'logout' ) {
+    $cookie->expires(0);
+  }
+
+  if ( $fill_in->{'format'} ) {
+    # then override content-type, and return $fill_in->{'content'} instead
+    # of filling in a template
+    if ( $fill_in->{'format'} eq 'csv') {
+      print $cgi->header('-expires' => 'now',
+        '-Content-Type' => 'text/csv',
+        '-Content-Disposition' => "attachment;filename=output.csv",
+      );
+    } elsif ( $fill_in->{'format'} eq 'xls' ) {
+      print $cgi->header('-expires' => 'now',
+        '-Content-Type' => 'application/vnd.ms-excel',
+        '-Content-Disposition' => "attachment;filename=output.xls",
+        '-Content-Length' => length($fill_in->{'content'}),
+      );
+    } elsif ( $fill_in->{'format'} eq 'png' ) {
+      print $cgi->header('-expires' => 'now',
+        '-Content-Type' => 'image/png',
+      );
     }
- }
+    print $fill_in->{'content'};
+  } else { # the usual case
+    my $source = "$template_dir/$name.html";
+    my $template = new Text::Template(
+      TYPE       => 'FILE',
+      SOURCE     => $source,
+      DELIMITERS => [ '<%=', '%>' ],
+      UNTAINT    => 1,
+    )
+      or die $Text::Template::ERROR;
+
+    my $data = $template->fill_in( 
+      PACKAGE => 'FS::SelfService::_selfservicecgi',
+      HASH    => $fill_in,
+    ) || "Error processing template $source"; # at least print _something_
+    print $cgi->header( '-cookie' => $cookie,
+                        '-expires' => 'now' );
+    print $data;
+  }
+}
 
 #*FS::SelfService::_selfservicecgi::include = \&Text::Template::fill_in_file;
 
@@ -1011,4 +1087,4 @@ sub include {
 
 }
 
-1;
+
diff --git a/fs_selfservice/FS-SelfService/cgi/svc_acct.html b/fs_selfservice/FS-SelfService/cgi/svc_acct.html
index 0024438..09d9163 100644
--- a/fs_selfservice/FS-SelfService/cgi/svc_acct.html
+++ b/fs_selfservice/FS-SelfService/cgi/svc_acct.html
@@ -5,7 +5,6 @@
           '</FONT><BR><BR>';
 } ''; %>
 <FORM ACTION="<%= $selfurl %>" METHOD=POST>
-<INPUT TYPE="hidden" NAME="session" VALUE="<%= $session_id %>">
 <INPUT TYPE="hidden" NAME="action" VALUE="process_svc_acct">
 <INPUT TYPE="hidden" NAME="custnum" VALUE="<%= $custnum %>">
 <INPUT TYPE="hidden" NAME="pkgnum" VALUE="<%= $pkgnum %>">
diff --git a/fs_selfservice/FS-SelfService/cgi/ticket_summary.html b/fs_selfservice/FS-SelfService/cgi/ticket_summary.html
index 4333c4e..94043bf 100644
--- a/fs_selfservice/FS-SelfService/cgi/ticket_summary.html
+++ b/fs_selfservice/FS-SelfService/cgi/ticket_summary.html
@@ -12,7 +12,6 @@ my $can_set_priority =
 if ( $can_set_priority ) {
 
   $OUT .= qq!<FORM ACTION="$selfurl" METHOD="POST">! .
-          qq!<INPUT TYPE="hidden" NAME="session" VALUE="$session_id">! .
           qq!<INPUT TYPE="hidden" NAME="action" VALUE="ticket_priority">!;
 }
 $date_format ||= '%Y-%m-%d';
diff --git a/fs_selfservice/FS-SelfService/cgi/tktcreate.html b/fs_selfservice/FS-SelfService/cgi/tktcreate.html
index de7ff60..1e1ecb6 100644
--- a/fs_selfservice/FS-SelfService/cgi/tktcreate.html
+++ b/fs_selfservice/FS-SelfService/cgi/tktcreate.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', 'Create a ticket') %>
 
 <%=
@@ -10,7 +9,6 @@ if ( $ticket_id ) {
     Please fill in both the subject and message
     <br><br>
     <FORM ACTION="$selfurl" METHOD=POST>
-    <input type="hidden" name="session" value="$session_id">
     <input type="hidden" name="action" value="tktcreate">
     <table>
 	<tr>
diff --git a/fs_selfservice/FS-SelfService/cgi/tktview.html b/fs_selfservice/FS-SelfService/cgi/tktview.html
index 72634fe..974dd6b 100644
--- a/fs_selfservice/FS-SelfService/cgi/tktview.html
+++ b/fs_selfservice/FS-SelfService/cgi/tktview.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', "View ticket #$ticket_id") %>
 
 <%=
@@ -20,7 +19,6 @@ else {
 %>
 <BR><BR><BR>
 <FORM ACTION="<%=$selfurl%>" METHOD=POST>
-    <input type="hidden" name="session" value="<%=$session_id%>">
     <input type="hidden" name="ticket_id" value="<%=$ticket_id%>">
 <%= if ( $edit_ticket_subject ) { $OUT .= '
     Subject:<BR><input type="text" name="subject" value="' . 
diff --git a/fs_selfservice/FS-SelfService/cgi/view_cdr_details.html b/fs_selfservice/FS-SelfService/cgi/view_cdr_details.html
index 0ee8e96..f396682 100644
--- a/fs_selfservice/FS-SelfService/cgi/view_cdr_details.html
+++ b/fs_selfservice/FS-SelfService/cgi/view_cdr_details.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', ($inbound ? 'Received calls' : 'Dialed calls' ) . 
                        ' for '.
                        Date::Format::time2str('%b %o %Y', $beginning).
diff --git a/fs_selfservice/FS-SelfService/cgi/view_customer.html b/fs_selfservice/FS-SelfService/cgi/view_customer.html
index 5bfb9b6..a40cd5a 100644
--- a/fs_selfservice/FS-SelfService/cgi/view_customer.html
+++ b/fs_selfservice/FS-SelfService/cgi/view_customer.html
@@ -1,6 +1,5 @@
 <HTML><HEAD><TITLE>Reseller</TITLE></HEAD>
 <BODY BGCOLOR="#eeeeee"><FONT SIZE=5>Reseller</FONT><BR><BR>
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <TABLE BORDER=0 CELLPADDING=4><TR>
 <%= include('agent_menu') %>
 <TD VALIGN="top">
diff --git a/fs_selfservice/FS-SelfService/cgi/view_invoice.html b/fs_selfservice/FS-SelfService/cgi/view_invoice.html
index 072a414..d49a466 100644
--- a/fs_selfservice/FS-SelfService/cgi/view_invoice.html
+++ b/fs_selfservice/FS-SelfService/cgi/view_invoice.html
@@ -1,4 +1,3 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
 <%= include('header', 'Invoice') %>
 
 <%= $invoice_html %>
diff --git a/fs_selfservice/FS-SelfService/cgi/view_port_graph.html b/fs_selfservice/FS-SelfService/cgi/view_port_graph.html
index d42f405..0d32a88 100644
--- a/fs_selfservice/FS-SelfService/cgi/view_port_graph.html
+++ b/fs_selfservice/FS-SelfService/cgi/view_port_graph.html
@@ -1,4 +1,4 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
+<%= $url = "$selfurl?action="; ''; %>
 <%= include('header', "Service usage details for $start - $end") %>
 
 <%= if ( $error ) {
diff --git a/fs_selfservice/FS-SelfService/cgi/view_support_details.html b/fs_selfservice/FS-SelfService/cgi/view_support_details.html
index 104b061..b401be4 100644
--- a/fs_selfservice/FS-SelfService/cgi/view_support_details.html
+++ b/fs_selfservice/FS-SelfService/cgi/view_support_details.html
@@ -1,4 +1,4 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
+<%= $url = "$selfurl?action="; ''; %>
 <%= include('header', 'Usage details') %>
 
 <FONT SIZE=4>Support usage details for
diff --git a/fs_selfservice/FS-SelfService/cgi/view_usage.html b/fs_selfservice/FS-SelfService/cgi/view_usage.html
index 35d1289..f50f770 100644
--- a/fs_selfservice/FS-SelfService/cgi/view_usage.html
+++ b/fs_selfservice/FS-SelfService/cgi/view_usage.html
@@ -1,4 +1,4 @@
-<%= $url = "$selfurl?session=$session_id;action=";
+<%= $url = "$selfurl?action=";
     %by_pkg_label = (); # not used yet, but I'm sure it will be...
     @svc_acct = ();
     @svc_phone = ();
@@ -196,8 +196,7 @@ foreach my $svc_port ( @svc_port ) {
   $OUT .= '<TR><TD>'. $svc_port->{'label'}. ': '. $svc_port->{'value'}.'</TD>';
   $OUT .= qq! <TD><FORM ACTION="$url" METHOD="GET">
 		<INPUT TYPE="hidden" name="svcnum" value="$svcnum">
-		<INPUT TYPE="hidden" name="action" value="view_port_graph">  
-		<INPUT TYPE="hidden" name="session" value="$session_id">  !;
+		<INPUT TYPE="hidden" name="action" value="view_port_graph"> !; 
   $OUT .= preset_range($default_start,$default_end,'Last Day',$date_format,$svcnum)
 	.' | '.preset_range($default_end-86400*7,$default_end,'Last Week',$date_format,$svcnum)
 	.' | '.preset_range($default_end-86400*30,$default_end,'Last Month',$date_format,$svcnum)
diff --git a/fs_selfservice/FS-SelfService/cgi/view_usage_details.html b/fs_selfservice/FS-SelfService/cgi/view_usage_details.html
index c4cc177..0388c2f 100644
--- a/fs_selfservice/FS-SelfService/cgi/view_usage_details.html
+++ b/fs_selfservice/FS-SelfService/cgi/view_usage_details.html
@@ -1,4 +1,4 @@
-<%= $url = "$selfurl?session=$session_id;action="; ''; %>
+<%= $url = "$selfurl?;action="; ''; %>
 <%= include('header', 'Service usage details for '.
                       Date::Format::time2str('%b %o %Y', $beginning).
                       ' - '.
diff --git a/httemplate/edit/payment_gateway.html b/httemplate/edit/payment_gateway.html
index 7cfab71..37618d6 100644
--- a/httemplate/edit/payment_gateway.html
+++ b/httemplate/edit/payment_gateway.html
@@ -93,9 +93,10 @@ my %modules = (
     'WorldPay',
   ],
   'Business::OnlineThirdPartyPayment' => [
-    'eWayShared',
-    'Interswitchng',
+    #'eWayShared', support currently broken
+    #'Interswitchng',
     'PayPal',
+    'FCMB',
   ],
   'Business::BatchPayment' => [
     'KeyBank',

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

Summary of changes:
 FS/FS/ClientAPI/MyAccount.pm                       |   48 ++++-
 FS/FS/Conf.pm                                      |    6 +
 FS/FS/Schema.pm                                    |    3 +
 FS/FS/agent.pm                                     |   30 ++-
 FS/FS/cust_main.pm                                 |    1 +
 FS/FS/cust_pay.pm                                  |    9 +
 FS/FS/cust_pay_pending.pm                          |  131 ++++++++++-
 FS/FS/payment_gateway.pm                           |   47 +++-
 fs_selfservice/FS-SelfService/SelfService.pm       |    3 +
 .../FS-SelfService/cgi/ach_payment_results.html    |    1 -
 .../FS-SelfService/cgi/agent_customer_menu.html    |    2 +-
 fs_selfservice/FS-SelfService/cgi/change_bill.html |    2 -
 .../FS-SelfService/cgi/change_password.html        |    2 -
 fs_selfservice/FS-SelfService/cgi/change_pay.html  |    3 +-
 fs_selfservice/FS-SelfService/cgi/change_pkg.html  |    1 -
 fs_selfservice/FS-SelfService/cgi/change_ship.html |    2 -
 .../FS-SelfService/cgi/customer_change_pkg.html    |    1 -
 .../FS-SelfService/cgi/customer_order_pkg.html     |    1 -
 fs_selfservice/FS-SelfService/cgi/delete_svc.html  |    1 -
 .../cgi/finish_thirdparty_payment.html             |   22 ++
 fs_selfservice/FS-SelfService/cgi/invoices.html    |    2 +-
 .../FS-SelfService/cgi/list_customers.html         |    2 +-
 fs_selfservice/FS-SelfService/cgi/login.html       |    3 +-
 fs_selfservice/FS-SelfService/cgi/logout.html      |    1 +
 .../FS-SelfService/cgi/make_ach_payment.html       |    2 -
 .../FS-SelfService/cgi/make_payment.html           |    2 -
 .../cgi/make_thirdparty_payment.html               |   11 +-
 fs_selfservice/FS-SelfService/cgi/myaccount.html   |    2 +-
 .../FS-SelfService/cgi/myaccount_menu.html         |    2 +-
 fs_selfservice/FS-SelfService/cgi/order_pkg.html   |    1 -
 .../FS-SelfService/cgi/payment_results.html        |    1 -
 .../cgi/post_thirdparty_payment.html               |   61 ++----
 .../FS-SelfService/cgi/process_change_bill.html    |    1 -
 .../cgi/process_change_password.html               |    1 -
 .../FS-SelfService/cgi/process_change_pay.html     |    1 -
 .../FS-SelfService/cgi/process_change_pkg.html     |    1 -
 .../FS-SelfService/cgi/process_change_ship.html    |    1 -
 .../FS-SelfService/cgi/process_order_pkg.html      |    1 -
 .../FS-SelfService/cgi/process_order_recharge.html |    1 -
 .../FS-SelfService/cgi/process_suspend_pkg.html    |    1 -
 .../FS-SelfService/cgi/process_svc_acct.html       |    1 -
 .../FS-SelfService/cgi/process_svc_external.html   |    1 -
 .../FS-SelfService/cgi/process_svc_phone.html      |    1 -
 fs_selfservice/FS-SelfService/cgi/provision.html   |    3 +-
 .../FS-SelfService/cgi/provision_svc_acct.html     |    1 -
 .../FS-SelfService/cgi/provision_svc_phone.html    |    6 +-
 .../FS-SelfService/cgi/recharge_prepay.html        |    2 -
 .../FS-SelfService/cgi/recharge_results.html       |    1 -
 fs_selfservice/FS-SelfService/cgi/selfservice.cgi  |  250 +++++++++++++-------
 fs_selfservice/FS-SelfService/cgi/svc_acct.html    |    1 -
 .../FS-SelfService/cgi/ticket_summary.html         |    1 -
 fs_selfservice/FS-SelfService/cgi/tktcreate.html   |    2 -
 fs_selfservice/FS-SelfService/cgi/tktview.html     |    2 -
 .../FS-SelfService/cgi/view_cdr_details.html       |    1 -
 .../FS-SelfService/cgi/view_customer.html          |    1 -
 .../FS-SelfService/cgi/view_invoice.html           |    1 -
 .../FS-SelfService/cgi/view_port_graph.html        |    2 +-
 .../FS-SelfService/cgi/view_support_details.html   |    2 +-
 fs_selfservice/FS-SelfService/cgi/view_usage.html  |    5 +-
 .../FS-SelfService/cgi/view_usage_details.html     |    2 +-
 httemplate/edit/payment_gateway.html               |    5 +-
 61 files changed, 492 insertions(+), 213 deletions(-)
 create mode 100644 fs_selfservice/FS-SelfService/cgi/finish_thirdparty_payment.html




More information about the freeside-commits mailing list