summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wells <mark@freeside.biz>2013-08-08 18:10:45 -0700
committerMark Wells <mark@freeside.biz>2013-08-08 18:10:45 -0700
commitc9d51796516657eebb115d6295ba3c0e2e08f697 (patch)
tree5d0d3fd98e7e952bb30f3d28ce01cc7d275b77a0
parent5a6c740c8152b1e8fa61d449808a50cdd7de07ab (diff)
new thirdparty payment framework, #22395, etc.
-rw-r--r--FS/FS/ClientAPI/MyAccount.pm48
-rw-r--r--FS/FS/Conf.pm6
-rw-r--r--FS/FS/Schema.pm3
-rw-r--r--FS/FS/agent.pm30
-rw-r--r--FS/FS/cust_main.pm1
-rw-r--r--FS/FS/cust_main/Billing_ThirdParty.pm266
-rw-r--r--FS/FS/cust_pay.pm9
-rw-r--r--FS/FS/cust_pay_pending.pm131
-rw-r--r--FS/FS/payment_gateway.pm47
-rw-r--r--fs_selfservice/FS-SelfService/SelfService.pm3
-rw-r--r--fs_selfservice/FS-SelfService/cgi/ach_payment_results.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/agent_customer_menu.html2
-rwxr-xr-xfs_selfservice/FS-SelfService/cgi/change_bill.html2
-rw-r--r--fs_selfservice/FS-SelfService/cgi/change_password.html2
-rw-r--r--fs_selfservice/FS-SelfService/cgi/change_pay.html3
-rw-r--r--fs_selfservice/FS-SelfService/cgi/change_pkg.html1
-rwxr-xr-xfs_selfservice/FS-SelfService/cgi/change_ship.html2
-rw-r--r--fs_selfservice/FS-SelfService/cgi/customer_change_pkg.html1
-rwxr-xr-xfs_selfservice/FS-SelfService/cgi/customer_order_pkg.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/delete_svc.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/finish_thirdparty_payment.html22
-rw-r--r--fs_selfservice/FS-SelfService/cgi/invoices.html2
-rw-r--r--fs_selfservice/FS-SelfService/cgi/list_customers.html2
-rw-r--r--fs_selfservice/FS-SelfService/cgi/login.html3
-rw-r--r--fs_selfservice/FS-SelfService/cgi/logout.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/make_ach_payment.html2
-rw-r--r--fs_selfservice/FS-SelfService/cgi/make_payment.html2
-rwxr-xr-xfs_selfservice/FS-SelfService/cgi/make_thirdparty_payment.html11
-rw-r--r--fs_selfservice/FS-SelfService/cgi/myaccount.html2
-rw-r--r--fs_selfservice/FS-SelfService/cgi/myaccount_menu.html2
-rw-r--r--fs_selfservice/FS-SelfService/cgi/order_pkg.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/payment_results.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/post_thirdparty_payment.html61
-rw-r--r--fs_selfservice/FS-SelfService/cgi/process_change_bill.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/process_change_password.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/process_change_pay.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/process_change_pkg.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/process_change_ship.html1
-rwxr-xr-xfs_selfservice/FS-SelfService/cgi/process_order_pkg.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/process_order_recharge.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/process_suspend_pkg.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/process_svc_acct.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/process_svc_external.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/process_svc_phone.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/provision.html3
-rw-r--r--fs_selfservice/FS-SelfService/cgi/provision_svc_acct.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/provision_svc_phone.html6
-rw-r--r--fs_selfservice/FS-SelfService/cgi/recharge_prepay.html2
-rw-r--r--fs_selfservice/FS-SelfService/cgi/recharge_results.html1
-rwxr-xr-xfs_selfservice/FS-SelfService/cgi/selfservice.cgi250
-rw-r--r--fs_selfservice/FS-SelfService/cgi/svc_acct.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/ticket_summary.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/tktcreate.html2
-rw-r--r--fs_selfservice/FS-SelfService/cgi/tktview.html2
-rw-r--r--fs_selfservice/FS-SelfService/cgi/view_cdr_details.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/view_customer.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/view_invoice.html1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/view_port_graph.html2
-rw-r--r--fs_selfservice/FS-SelfService/cgi/view_support_details.html2
-rw-r--r--fs_selfservice/FS-SelfService/cgi/view_usage.html5
-rw-r--r--fs_selfservice/FS-SelfService/cgi/view_usage_details.html2
-rw-r--r--httemplate/edit/payment_gateway.html5
62 files changed, 758 insertions, 213 deletions
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 bc6784d..de32ee3 100644
--- a/FS/FS/Conf.pm
+++ b/FS/FS/Conf.pm
@@ -2280,6 +2280,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 41d3d80..65e42e8 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -1541,6 +1541,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 9b32209..2312591 100644
--- a/FS/FS/agent.pm
+++ b/FS/FS/agent.pm
@@ -206,7 +206,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.
@@ -221,10 +222,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} ) {
@@ -252,8 +277,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}
}
@@ -274,7 +297,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 8bb1a35..a5450c1 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_main/Billing_ThirdParty.pm b/FS/FS/cust_main/Billing_ThirdParty.pm
new file mode 100644
index 0000000..faced8f
--- /dev/null
+++ b/FS/FS/cust_main/Billing_ThirdParty.pm
@@ -0,0 +1,266 @@
+package FS::cust_main::Billing_ThirdParty;
+
+use strict;
+use vars qw( $DEBUG $me );
+use FS::Record qw( qsearch qsearchs dbh );
+use FS::cust_pay;
+use FS::cust_pay_pending;
+
+$DEBUG = 0;
+$me = '[FS::cust_main::Billing_ThirdParty]';
+# arguably doesn't even belong under cust_main...
+
+=head1 METHODS
+
+=over 4
+
+=item create_payment OPTIONS
+
+Create a pending payment for a third-party gateway. OPTIONS must include:
+- method: a Business::OnlineThirdPartyPayment method argument. Currently
+ only supports PAYPAL.
+- amount: a decimal amount. Unlike in Billing_Realtime, there is NO default.
+- session_id: the customer's self-service session ID.
+
+and may optionally include:
+- invnum: the invoice that this payment will apply to
+- pkgnum: the package balance that this payment will apply to.
+- description: the transaction description for the gateway.
+- payip: the IP address the payment is initiated from
+
+On failure, returns a simple string error message. On success, returns
+a hashref of 'url' => the URL to redirect the user to to complete payment,
+and optionally 'post_params' => a hashref of name/value pairs to be POSTed
+to that URL.
+
+=cut
+
+my @methods = qw(PAYPAL CC);
+my %method2payby = ( 'PAYPAL' => 'PPAL', 'CC' => 'MCRD' );
+
+sub create_payment {
+ my $self = shift;
+ my %opt = @_;
+
+ # avoid duplicating this--we just need description and invnum
+ my $defaults;
+ $self->_bop_defaults($defaults);
+
+ my $method = $opt{'method'} or return 'method required';
+ my $amount = $opt{'amount'} or return 'amount required';
+ return "unknown method '$method'" unless grep {$_ eq $method} @methods;
+ return "amount must be > 0" unless $amount > 0;
+ return "session_id required" unless length($opt{'session_id'});
+
+ my $gateway = $self->agent->payment_gateway(
+ method => $method,
+ nofatal => 1,
+ thirdparty => 1,
+ );
+ return "no third-party gateway enabled for method $method" if !$gateway;
+
+ # create pending record
+ $self->select_for_update;
+ my @pending = qsearch('cust_pay_pending', {
+ 'custnum' => $self->custnum,
+ 'status' => { op=>'!=', value=>'done' }
+ });
+
+ # if there are pending payments in the 'thirdparty' state,
+ # we can safely remove them
+ foreach (@pending) {
+ if ( $_->status eq 'thirdparty' ) {
+ my $error = $_->delete;
+ return "Error deleting unfinished payment #".
+ $_->paypendingnum . ": $error\n" if $error;
+ } else {
+ return "A payment is already being processed for this customer.";
+ }
+ }
+
+ my $cpp = FS::cust_pay_pending->new({
+ 'custnum' => $self->custnum,
+ 'status' => 'new',
+ 'gatewaynum' => $gateway->gatewaynum,
+ 'paid' => sprintf('%.2f',$opt{'amount'}),
+ 'payby' => $method2payby{ $opt{'method'} },
+ 'pkgnum' => $opt{'pkgnum'},
+ 'invnum' => $opt{'invnum'} || $defaults->{'invnum'},
+ 'session_id' => $opt{'session_id'},
+ });
+
+ my $error = $cpp->insert;
+ return $error if $error;
+
+ my $transaction = $gateway->processor;
+ # Not included in this content hash:
+ # payinfo, paydate, paycvv, any kind of recurring billing indicator,
+ # paystate, paytype (account type), stateid, ss, payname
+ #
+ # Also, unlike bop_realtime, we don't allow the magical %options hash
+ # to override the customer's information. If they need to enter a
+ # different address or something for the billing provider, they can do
+ # that after the redirect.
+ my %content = (
+ 'action' => 'create',
+ 'description' => $opt{'description'} || $defaults->{'description'},
+ 'amount' => $amount,
+ 'customer_id' => $self->custnum,
+ 'email' => $self->invoicing_list_emailonly_scalar,
+ 'customer_ip' => $opt{'payip'},
+ 'first_name' => $self->first,
+ 'last_name' => $self->last,
+ 'address1' => $self->address1,
+ 'address2' => $self->address2,
+ 'city' => $self->city,
+ 'state' => $self->state,
+ 'zip' => $self->zip,
+ 'country' => $self->country,
+ 'phone' => ($self->daytime || $self->night),
+ );
+
+ {
+ local $@;
+ eval { $transaction->create(%content) };
+ if ( $@ ) {
+ warn "ERROR: Executing third-party payment:\n$@\n";
+ return { error => $@ };
+ }
+ }
+
+ if ($transaction->is_success) {
+ $cpp->status('thirdparty');
+ # for whatever is most identifiable as the "transaction ID"
+ $cpp->payinfo($transaction->token);
+ # for anything else the transaction needs to remember
+ $cpp->statustext($transaction->statustext);
+ $error = $cpp->replace;
+ return $error if $error;
+
+ return {url => $transaction->redirect,
+ post_params => $transaction->post_params};
+
+ } else {
+ $cpp->status('done');
+ $cpp->statustext($transaction->error_message);
+ $error = $cpp->replace;
+ return $error if $error;
+
+ return $transaction->error_message;
+ }
+
+}
+
+=item execute_payment SESSION_ID, PARAMS
+
+Complete the payment and get the status. Triggered from the return_url
+handler; PARAMS are all of the CGI parameters we received in the redirect.
+On failure, returns an error message. On success, returns a hashref of
+'paynum', 'paid', 'order_number', and 'auth'.
+
+=cut
+
+sub execute_payment {
+ my $self = shift;
+ my $session_id = shift;
+ my %params = @_;
+
+ my $cpp = qsearchs('cust_pay_pending', {
+ 'session_id' => uc($session_id),
+ 'custnum' => $self->custnum,
+ 'status' => 'thirdparty',
+ })
+ or return 'no payment in process for this session';
+
+ my $gateway = FS::payment_gateway->by_key( $cpp->gatewaynum );
+ my $transaction = $gateway->processor;
+ $transaction->token($cpp->payinfo);
+ $transaction->statustext($cpp->statustext);
+
+ {
+ local $@;
+ eval { $transaction->execute(%params) };
+ if ( $@ ) {
+ warn "ERROR: Executing third-party payment:\n$@\n";
+ return { error => $@ };
+ }
+ }
+
+ my $error;
+
+ if ( $transaction->is_success ) {
+
+ $error = $cpp->approve(
+ 'processor' => $gateway->gateway_module,
+ 'order_number' => $transaction->order_number,
+ 'auth' => $transaction->authorization,
+ 'payinfo' => '',
+ 'apply' => 1,
+ );
+ return $error if $error;
+
+ return {
+ 'paynum' => $cpp->paynum,
+ 'paid' => $cpp->paid,
+ 'order_number' => $transaction->order_number,
+ 'auth' => $transaction->authorization,
+ }
+
+ } else {
+
+ my $error = $gateway->gateway_module. " error: ".
+ $transaction->error_message;
+
+ my $jobnum = $cpp->jobnum;
+ if ( $jobnum ) {
+ my $placeholder = FS::queue->by_key($jobnum);
+
+ if ( $placeholder ) {
+ my $e = $placeholder->depended_delete || $placeholder->delete;
+ warn "error removing provisioning jobs after declined paypendingnum ".
+ $cpp->paypendingnum. ": $e\n\n"
+ if $e;
+ } else {
+ warn "error finding job $jobnum for declined paypendingnum ".
+ $cpp->paypendingnum. "\n\n";
+ }
+ }
+
+ # not needed here:
+ # the raw HTTP response thing when there's no error message
+ # decline notices (the customer has already seen the decline message)
+
+ # set the pending status
+ my $e = $cpp->decline($error);
+ if ( $e ) {
+ $e = "WARNING: payment declined but pending payment not resolved - ".
+ "error updating status for pendingnum :".$cpp->paypendingnum.
+ ": $e\n\n";
+ warn $e;
+ $error = "$e ($error)";
+ }
+
+ return $error;
+ }
+
+}
+
+=item cancel_payment SESSION_ID
+
+Cancel a pending payment attempt. This just cleans up the cust_pay_pending
+record.
+
+=cut
+
+sub cancel_payment {
+ my $self = shift;
+ my $session_id = shift;
+ my $cust_pay_pending = qsearchs('cust_pay_pending', {
+ 'session_id' => uc($session_id),
+ 'status' => 'thirdparty',
+ });
+ return { 'error' => $cust_pay_pending->delete };
+}
+
+1;
+
diff --git a/FS/FS/cust_pay.pm b/FS/FS/cust_pay.pm
index d3e0301..2e97429 100644
--- a/FS/FS/cust_pay.pm
+++ b/FS/FS/cust_pay.pm
@@ -192,6 +192,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&nbsp;#</TD>
+ <TD BGCOLOR="#ffffff"><B>' . $paynum . '</B></TD>
+</TR>
+<TR>
+ <TD ALIGN="right">Payment&nbsp;amount</TH>
+ <TD BGCOLOR="#ffffff"><B>' . sprintf('$%.2f', $paid) . '</B></TD>
+</TR>
+<TR>
+ <TD ALIGN="right">Processing&nbsp;#</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&nbsp;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&nbsp;%o&nbsp;%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&nbsp;%o&nbsp;%Y', $beginning).
' - '.
diff --git a/httemplate/edit/payment_gateway.html b/httemplate/edit/payment_gateway.html
index 17709c8..0cd93e4 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',