From: levinse Date: Fri, 21 Jan 2011 22:17:30 +0000 (+0000) Subject: add (unfinished) credit card surcharge, part 1 X-Git-Tag: freeside_2_3_0~718 X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=commitdiff_plain;h=0f7643c1af2d909e0c3172e5bec0c01855fca1b9 add (unfinished) credit card surcharge, part 1 --- diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm index ad40b1760..633d74d6c 100644 --- a/FS/FS/ClientAPI/MyAccount.pm +++ b/FS/FS/ClientAPI/MyAccount.pm @@ -533,6 +533,8 @@ sub payment_info { 'show_paystate' => $conf->exists('show_bankstate'), 'save_unchecked' => $conf->exists('selfservice-save_unchecked'), + + 'credit_card_surcharge_percentage' => $conf->config('credit-card-surcharge-percentage'), }; } diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index d8321b926..fc7e5c87b 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -655,6 +655,13 @@ my %payment_gateway_options = ( }, { + 'key' => 'credit-card-surcharge-percentage', + 'section' => 'billing', + 'description' => 'Add a credit card surcharge to invoices, as a % of the invoice total. WARNING: this is usually prohibited by merchant account / other agreements and/or law, but is currently lawful in AU and UK.', + 'type' => 'text', + }, + + { 'key' => 'discount-show-always', 'section' => 'billing', 'description' => 'Generate a line item on an invoice even when a package is discounted 100%', diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index f07834297..62ab87f0f 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -1958,7 +1958,8 @@ sub realtime_lec { } sub realtime_bop { - my( $self, $method ) = @_; + my( $self, $method ) = (shift,shift); + my %opt = @_; my $cust_main = $self->cust_main; my $balance = $cust_main->balance; @@ -1987,6 +1988,7 @@ sub realtime_bop { #this didn't do what we want, it just calls apply_payments_and_credits # 'apply' => 1, 'apply_to_invoice' => 1, + %opt, #what we want: #this changes application behavior: auto payments #triggered against a specific invoice are now applied diff --git a/FS/FS/cust_main/Billing_Realtime.pm b/FS/FS/cust_main/Billing_Realtime.pm index 10b898db0..ea09379ba 100644 --- a/FS/FS/cust_main/Billing_Realtime.pm +++ b/FS/FS/cust_main/Billing_Realtime.pm @@ -19,7 +19,7 @@ $realtime_bop_decline_quiet = 0; # 1 is mostly method/subroutine entry and options # 2 traces progress of some operations # 3 is even more information including possibly sensitive data -$DEBUG = 0; +$DEBUG = 1; $me = '[FS::cust_main::Billing_Realtime]'; install_callback FS::UID sub { @@ -186,6 +186,13 @@ sub _payment_gateway { } } + if ( $options->{'fake_gatewaynum'} ) { + $options->{payment_gateway} = + qsearchs('payment_gateway', + { 'gatewaynum' => $options->{'fake_gatewaynum'}, } + ); + } + $options->{payment_gateway} = $self->agent->payment_gateway( %$options ) unless exists($options->{payment_gateway}); @@ -308,13 +315,39 @@ sub realtime_bop { $options{method} = $method; $options{amount} = $amount; } + + + ### + # optional credit card surcharge + ### + + my $cc_surcharge = 0; + my $cc_surcharge_pct = $conf->config('credit-card-surcharge-percentage'); + # always add cc surcharge if called from event + if($options{'cc_surcharge_from_event'} && $cc_surcharge_pct > 0) { + $cc_surcharge = $options{'amount'} * $cc_surcharge_pct / 100; + $options{'amount'} += $cc_surcharge; + $options{'amount'} = sprintf("%.2f", $options{'amount'}); # round (again)? + } + elsif($cc_surcharge_pct > 0) { # we're called not from event (i.e. from a + # payment screen), so consider the given + # amount as post-surcharge + $cc_surcharge = $options{'amount'} - ($options{'amount'} / ( 1 + $cc_surcharge_pct/100 )); + } + if ( $cc_surcharge > 0) { + $cc_surcharge = sprintf("%.2f",$cc_surcharge); + $options{'cc_surcharge'} = $cc_surcharge; + } + + if ( $DEBUG ) { warn "$me realtime_bop (new): $options{method} $options{amount}\n"; + warn " cc_surcharge = $cc_surcharge\n"; warn " $_ => $options{$_}\n" foreach keys %options; } - return $self->fake_bop(%options) if $options{'fake'}; + return $self->fake_bop(\%options) if $options{'fake'}; $self->_bop_defaults(\%options); @@ -709,6 +742,11 @@ sub fake_bop { } ); $cust_pay->payunique( $options{payunique} ) if length($options{payunique}); + if ( $DEBUG ) { + warn "fake_bop\n cust_pay: ". Dumper($cust_pay) . "\n options: "; + warn " $_ => $options{$_}\n" foreach keys %options; + } + my $error = $cust_pay->insert($options{'manual'} ? ( 'manual' => 1 ) : () ); if ( $error ) { @@ -872,6 +910,60 @@ sub _realtime_bop_result { } } + # have a CC surcharge portion --> one-time charge + if ( $options{'cc_surcharge'} > 0 ) { + my $invnum; + $invnum = $options{'invnum'} if $options{'invnum'}; + unless ( $invnum ) { # probably from a payment screen + # do we have any open invoices? pick earliest + # uses the fact that cust_main->cust_bill sorts by date ascending + my @open = $self->open_cust_bill; + $invnum = $open[0]->invnum if scalar(@open); + } + + unless ( $invnum ) { # still nothing? pick last closed invoice + # again uses fact that cust_main->cust_bill sorts by date ascending + my @closed = $self->cust_bill; + $invnum = $closed[$#closed]->invnum if scalar(@closed); + } + + unless ( $invnum ) { + # XXX: unlikely case - pre-paying before any invoices generated + # what it should do is create a new invoice and pick it + warn 'CC SURCHARGE AND NO INVOICES PICKED TO APPLY IT!'; + return ''; + } + + my $cust_pkg; + my $charge_error = $self->charge({ + 'amount' => $options{'cc_surcharge'}, + 'pkg' => 'Credit Card Surcharge', + 'setuptax' => 'Y', + 'cust_pkg_ref' => \$cust_pkg, + }); + if($charge_error) { + warn 'Unable to add CC surcharge'; + return ''; + } + + my $cust_bill_pkg = new FS::cust_bill_pkg({ + 'invnum' => $invnum, + 'pkgnum' => $cust_pkg->pkgnum, + 'setup' => $options{'cc_surcharge'}, + }); + my $cbp_error = $cust_bill_pkg->insert; + + if ( $cbp_error) { + warn 'Cannot add CC surcharge line item to invoice #'.$invnum; + return ''; + } else { + my $cust_bill = qsearchs('cust_bill', { 'invnum' => $invnum }); + warn 'invoice for cc surcharge: ' . Dumper($cust_bill) if $DEBUG; + $cust_bill->apply_payments_and_credits; + } + + } + return ''; #no error } diff --git a/FS/FS/part_event/Action/cust_bill_realtime_card.pm b/FS/FS/part_event/Action/cust_bill_realtime_card.pm index c1fdba96a..1a2d04632 100644 --- a/FS/FS/part_event/Action/cust_bill_realtime_card.pm +++ b/FS/FS/part_event/Action/cust_bill_realtime_card.pm @@ -22,7 +22,8 @@ sub do_action { #my $cust_main = $self->cust_main($cust_bill); my $cust_main = $cust_bill->cust_main; - $cust_bill->realtime_card; + my %opt = ('cc_surcharge_from_event' => 1); + $cust_bill->realtime_card(%opt); } 1; diff --git a/fs_selfservice/FS-SelfService/cgi/make_payment.html b/fs_selfservice/FS-SelfService/cgi/make_payment.html index 645b68ec7..3bce67433 100644 --- a/fs_selfservice/FS-SelfService/cgi/make_payment.html +++ b/fs_selfservice/FS-SelfService/cgi/make_payment.html @@ -17,7 +17,13 @@ Payment amount
- $"> +<%= + $amt = $balance; + $amt += $amt * $credit_card_surcharge_percentage/100 + if $credit_card_surcharge_percentage > 0; + ''; +%> + $">
diff --git a/httemplate/misc/payment.cgi b/httemplate/misc/payment.cgi index bcab68aae..aec68af45 100644 --- a/httemplate/misc/payment.cgi +++ b/httemplate/misc/payment.cgi @@ -332,6 +332,10 @@ if ( $balance > 0 ) { $amount = $balance; $amount += $fee if $fee && $fee_display eq 'subtract'; + + my $cc_surcharge_pct = $conf->config('credit-card-surcharge-percentage'); + $amount += $amount * $cc_surcharge_pct/100 if $cc_surcharge_pct > 0; + $amount = sprintf("%.2f", $amount); }