use vars qw( $realtime_bop_decline_quiet ); #ugh
use Data::Dumper;
use Business::CreditCard 0.35;
+use Business::OnlinePayment;
use FS::UID qw( dbh myconnect );
use FS::Record qw( qsearch qsearchs );
use FS::Misc qw( send_email );
my $cc_surcharge = 0;
my $cc_surcharge_pct = 0;
- $cc_surcharge_pct = $conf->config('credit-card-surcharge-percentage')
- if $conf->config('credit-card-surcharge-percentage')
+ $cc_surcharge_pct = $conf->config('credit-card-surcharge-percentage', $self->agentnum)
+ if $conf->config('credit-card-surcharge-percentage', $self->agentnum)
+ && $options{method} eq 'CC';
+
+ my $cc_surcharge_flat = 0;
+ $cc_surcharge_flat = $conf->config('credit-card-surcharge-flatfee', $self->agentnum)
+ if $conf->config('credit-card-surcharge-flatfee', $self->agentnum)
&& $options{method} eq 'CC';
# 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;
+ if($options{'cc_surcharge_from_event'} && ($cc_surcharge_pct > 0 || $cc_surcharge_flat > 0)) {
+ if ($options{'amount'} > 0) {
+ $cc_surcharge = ($options{'amount'} * ($cc_surcharge_pct / 100)) + $cc_surcharge_flat;
$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 ));
+ elsif($cc_surcharge_pct > 0 || $cc_surcharge_flat > 0) {
+ # we're called not from event (i.e. from a
+ # payment screen), so consider the given
+ # amount as post-surcharge-processing_fee
+ $cc_surcharge = $options{'amount'} - $options{'processing-fee'} - (($options{'amount'} - ($cc_surcharge_flat + $options{'processing-fee'})) / ( 1 + $cc_surcharge_pct/100 )) if $options{'amount'} > 0;
}
$cc_surcharge = sprintf("%.2f",$cc_surcharge) if $cc_surcharge > 0;
my $dbh = dbh;
#start a transaction, insert the cust_pay and set cust_pay_pending.status to done in a single transction
-
- my $error = $cust_pay->insert($options{'manual'} ? ( 'manual' => 1 ) : () );
+ my $error = $cust_pay->insert(
+ $options{'manual'} ? ( 'manual' => 1 ) : (),
+ $options{'processing-fee'} > 0 ? ( 'processing-fee' => $options{'processing-fee'} ) : (),
+ );
if ( $error ) {
$dbh->rollback or die $dbh->errstr if $oldAutoCommit;
$cust_pay->invnum(''); #try again with no specific invnum
$cust_pay->paynum('');
- my $error2 = $cust_pay->insert( $options{'manual'} ?
- ( 'manual' => 1 ) : ()
- );
+ my $error2 = $cust_pay->insert(
+ $options{'manual'} ? ( 'manual' => 1 ) : (),
+ $options{'processing-fee'} > 0 ? ( 'processing-fee' => $options{'processing-fee'} ) : (),
+ );
if ( $error2 ) {
# gah. but at least we have a record of the state we had to abort in
# from cust_pay_pending now.
}
# have a CC surcharge portion --> one-time charge
- if ( $options{'cc_surcharge'} > 0 ) {
+ if ( $options{'cc_surcharge'} > 0 || $options{'processing-fee'} > 0) {
# XXX: this whole block needs to be in a transaction?
my $invnum;
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!';
+ warn 'CC SURCHARGE OR PROCESS FEE AND NO INVOICES PICKED TO APPLY IT!';
return '';
}
- my $cust_pkg;
- my $charge_error = $self->charge({
+ if ($options{'cc_surcharge'} > 0) {
+ my $cust_pkg;
+ my $cc_surcharge_text = 'Credit Card Surcharge';
+ $cc_surcharge_text = $conf->config('credit-card-surcharge-text', $self->agentnum) if $conf->exists('credit-card-surcharge-text', $self->agentnum);
+ my $charge_error = $self->charge({
'amount' => $options{'cc_surcharge'},
- 'pkg' => 'Credit Card Surcharge',
+ 'pkg' => $cc_surcharge_text,
'setuptax' => 'Y',
'cust_pkg_ref' => \$cust_pkg,
- });
- if($charge_error) {
- warn 'Unable to add CC surcharge cust_pkg';
- return '';
- }
+ });
+
+ if($charge_error) {
+ warn 'Unable to add CC surcharge cust_pkg';
+ return '';
+ }
+
+ $cust_pkg->setup(time);
+ my $cp_error = $cust_pkg->replace;
+ if($cp_error) {
+ warn 'Unable to set setup time on cust_pkg for cc surcharge';
+ # but keep going...
+ }
- $cust_pkg->setup(time);
- my $cp_error = $cust_pkg->replace;
- if($cp_error) {
- warn 'Unable to set setup time on cust_pkg for cc surcharge';
- # but keep going...
- }
-
- my $cust_bill = qsearchs('cust_bill', { 'invnum' => $invnum });
- unless ( $cust_bill ) {
- warn "race condition + invoice deletion just happened";
- return '';
- }
+ my $cust_bill = qsearchs('cust_bill', { 'invnum' => $invnum });
+ unless ( $cust_bill ) {
+ warn "race condition + invoice deletion just happened";
+ return '';
+ }
+
+ my $grand_error =
+ $cust_bill->add_cc_surcharge($cust_pkg->pkgnum,$options{'cc_surcharge'});
+
+ warn "cannot add CC surcharge to invoice #$invnum: $grand_error"
+ if $grand_error;
+ } # end if $options{'cc_surcharge'}
+
+ if ($options{'processing-fee'} > 0) {
+ my $pf_cust_pkg;
+ my $processing_fee_text = 'Payment Processing Fee';
- my $grand_error =
- $cust_bill->add_cc_surcharge($cust_pkg->pkgnum,$options{'cc_surcharge'});
+ my $conf = new FS::Conf;
- warn "cannot add CC surcharge to invoice #$invnum: $grand_error"
- if $grand_error;
+ my $pf_seperate_bill;
+ my $pf_bill_now;
+ if ($conf->exists('processing-fee_on_separate_invoice')) {
+ $pf_seperate_bill = 'Y';
+ $pf_bill_now = '1';
}
+ my $pf_change_error = $self->charge({
+ 'amount' => $options{'processing-fee'},
+ 'pkg' => $processing_fee_text,
+ 'setuptax' => 'Y',
+ 'cust_pkg_ref' => \$pf_cust_pkg,
+ 'separate_bill' => $pf_seperate_bill,
+ 'bill_now' => $pf_bill_now,
+ });
+
+ if($pf_change_error) {
+ warn 'Unable to add payment processing fee';
+ return '';
+ }
+
+ $pf_cust_pkg->setup(time);
+ my $pf_error = $pf_cust_pkg->replace;
+ if($pf_error) {
+ warn 'Unable to set setup time on cust_pkg for processing fee';
+ # but keep going...
+ }
+
+ if ($conf->exists('processing-fee_on_separate_invoice')) {
+ my $cust_bill_pkg = qsearchs( 'cust_bill_pkg', { 'pkgnum' => $pf_cust_pkg->pkgnum } );
+
+ my $pf_cust_bill = qsearchs('cust_bill', { 'invnum' => $cust_bill_pkg->invnum });
+ unless ( $pf_cust_bill ) {
+ warn "no processing fee inv found!";
+ return '';
+ }
+
+ my $pf_apply_error = $pf_cust_bill->apply_payments_and_credits;
+
+ my $cust_bill = qsearchs('cust_bill', { 'invnum' => $invnum });
+ unless ( $cust_bill ) {
+ warn "race condition + invoice deletion just happened";
+ return '';
+ }
+
+ my $grand_pf_error = $cust_bill->apply_payments_and_credits;
+
+ warn "cannot apply Processing fee to invoice #$invnum: $grand_pf_error - $pf_apply_error"
+ if $grand_pf_error || $pf_apply_error;
+ } ## processing-fee_on_separate_invoice
+ else {
+ my $cust_bill = qsearchs('cust_bill', { 'invnum' => $invnum });
+ unless ( $cust_bill ) {
+ warn "race condition + invoice deletion just happened";
+ return '';
+ }
+
+ my $grand_pf_error =
+ $cust_bill->add_cc_surcharge($pf_cust_pkg->pkgnum,$options{'processing-fee'});
+
+ warn "cannot add Processing fee to invoice #$invnum: $grand_pf_error"
+ if $grand_pf_error;
+ } ## no processing-fee_on_separate_invoice
+ } #end if $options{'processing-fee'}
+
+ } #end if ( $options{'cc_surcharge'} > 0 || $options{'processing-fee'} > 0)
+
return ''; #no error
}
$self->agent->payment_gateway( 'method' => $options{method},
#'payinfo' => $payinfo,
);
- my( $processor, $login, $password, $namespace ) =
+ ( $processor, $login, $password, $namespace ) =
map { my $method = "gateway_$_"; $payment_gateway->$method }
qw( module username password namespace );