X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=FS%2FFS%2Fcust_main%2FBilling_Realtime.pm;h=78f2cbcbe3b2e565ca558610741c7701a4ed856f;hp=f089059aa387f709b1978576a9b81004e592a6e4;hb=4171d4440a6bf042f342095f13439a5f9d27487d;hpb=2ebfd5c5a550befcd4546edeed8de8300e0c59d2 diff --git a/FS/FS/cust_main/Billing_Realtime.pm b/FS/FS/cust_main/Billing_Realtime.pm index f089059aa..78f2cbcbe 100644 --- a/FS/FS/cust_main/Billing_Realtime.pm +++ b/FS/FS/cust_main/Billing_Realtime.pm @@ -6,6 +6,7 @@ use vars qw( $realtime_bop_decline_quiet ); #ugh use Carp; 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::payby; @@ -126,6 +127,13 @@ sub realtime_collect { $options{amount} = $self->balance unless exists( $options{amount} ); return '' unless $options{amount} > 0; + #huh, in v4, realtime_bop no longer will just process a card without passing + # payinfo or cust_payby... + if ( ! $options{'payinfo'} && ! $options{'cust_payby'} && $self->has_cust_payby_auto ) { + my @cust_payby = $self->cust_payby; + $options{'cust_payby'} = $cust_payby[0]; + } + return $self->realtime_bop({%options}); } @@ -413,6 +421,8 @@ sub realtime_bop { $options{amount} = $amount; } + return '' unless $options{amount} > 0; + # set fields from passed cust_payby _bop_cust_payby_options(\%options); @@ -446,16 +456,24 @@ sub realtime_bop { 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 + $cc_surcharge = $options{'amount'} - (($options{'amount'} - $cc_surcharge_flat) / ( 1 + $cc_surcharge_pct/100 )) if $options{'amount'} > 0; } $cc_surcharge = sprintf("%.2f",$cc_surcharge) if $cc_surcharge > 0; @@ -1185,6 +1203,7 @@ sub _realtime_bop_result { "resolved - error updating status for paypendingnum ". $cust_pay_pending->paypendingnum. ": $cpp_done_err \n"; warn $e; + #XXX internal system log $e (what's going on?) $perror = "$e ($perror)"; } @@ -2373,7 +2392,7 @@ is set, this will instead cause a critical error to be recorded in the log, and any other tokenizable records will still be committed. If the I flag is also set, detection of existing untokenized records will -record a critical error in the system log (because they should have never appeared +record an info message in the system log (because they should have never appeared in the first place.) Tokenization will still be attempted. If any configured gateways do NOT have the ability to tokenize, or if a @@ -2386,6 +2405,7 @@ sub token_check { #acts on all customers my %opt = @_; my $debug = !$opt{'quiet'} || $DEBUG; + my $hascritical = 0; warn "token_check called with opts\n".Dumper(\%opt) if $debug; @@ -2482,6 +2502,7 @@ CUSTLOOP: } my $error = "No gateway found for custnum ".$cust_main->custnum; if ($opt{'queue'}) { + $hascritical = 1; $log->critical($error); $dbh->commit or die $dbh->errstr; # commit error message next; # not next CUSTLOOP, want to record error for every cust_payby @@ -2518,6 +2539,7 @@ CUSTLOOP: if ($error) { $error = "Error tokenizing cust_payby ".$cust_payby->custpaybynum.": ".$error; if ($opt{'queue'}) { + $hascritical = 1; $log->critical($error); $dbh->commit or die $dbh->errstr; # commit log message, release mutex next; # not next CUSTLOOP, want to record error for every cust_payby @@ -2550,6 +2572,10 @@ CUSTLOOP: while (my $recnum = _token_check_next_recnum($dbh,$table,$step,\$offset,\@recnums)) { my $record = $tclass->by_key($recnum); + unless ($record->payby eq 'CARD') { + warn "Skipping non-card record for $table ".$record->get($record->primary_key) if $debug; + next; + } if (FS::cust_main::Billing_Realtime->tokenized($record->payinfo)) { warn "Skipping tokenized record for $table ".$record->get($record->primary_key) if $debug; next; @@ -2580,6 +2606,7 @@ CUSTLOOP: } else { my $error = "Could not load cust_main for $table ".$record->get($record->primary_key); if ($opt{'queue'}) { + $hascritical = 1; $log->critical($error); $dbh->commit or die $dbh->errstr; # commit log message next; @@ -2682,6 +2709,7 @@ CUSTLOOP: if ($error) { $error = "Error tokenizing $table ".$record->get($record->primary_key).": ".$error; if ($opt{'queue'}) { + $hascritical = 1; $log->critical($error); $dbh->commit or die $dbh->errstr; # commit log message, release mutex next; @@ -2697,7 +2725,7 @@ CUSTLOOP: $dbh->commit or die $dbh->errstr if $oldAutoCommit; - return ''; + return $hascritical ? 'Critical errors occurred on some records, see system log' : ''; } # not a method! @@ -2709,8 +2737,7 @@ sub _token_check_next_recnum { my $sth = $dbh->prepare( 'SELECT '.$tclass->primary_key. ' FROM '.$table. - " WHERE payby IN ( 'CARD', 'DCRD' ) ". - " AND ( length(payinfo) > 80 OR payinfo NOT LIKE '99%' )". + " WHERE ( is_tokenized IS NULL OR is_tokenized = '' ) ". ' ORDER BY '.$tclass->primary_key. ' LIMIT '.$step. ' OFFSET '.$$offset