'extra_sql' => ' AND '. $curuser->agentnums_sql,
}) or die "unknown custnum $custnum";
+my $invoice = ($cgi->param('invoice') =~ /^(\d+)$/) ? $cgi->param('invoice') : '';
+
$cgi->param('amount') =~ /^\s*(\d*(\.\d\d)?)\s*$/
or errorpage("illegal amount ". $cgi->param('amount'));
my $amount = $1;
or errorpage("illegal discount_term");
my $discount_term = $1;
-my( $payinfo, $paycvv, $month, $year, $payname );
+my( $cust_payby, $payinfo, $paycvv, $month, $year, $payname );
my $paymask = '';
if ( (my $custpaybynum = scalar($cgi->param('custpaybynum'))) > 0 ) {
# use stored cust_payby info
##
- my $cust_payby = qsearchs('cust_payby', { custnum => $custnum,
+ $cust_payby = qsearchs('cust_payby', { custnum => $custnum,
custpaybynum => $custpaybynum, } )
or die "unknown custpaybynum $custpaybynum";
+ # not needed for realtime_bop, but still needed for batch_card
$payinfo = $cust_payby->payinfo;
$paymask = $cust_payby->paymask;
- $paycvv = '';
+ $paycvv = $cust_payby->paycvv; # pass it if we got it, running a transaction will clear it
( $month, $year ) = $cust_payby->paydate_mon_year;
$payname = $cust_payby->payname;
+ $cgi->param(-name=>"paytype", -value=>$cust_payby->paytype) unless $cgi->param("paytype");
} else {
$payinfo = $cgi->param('payinfo');
$payinfo =~ s/\D//g;
- $payinfo =~ /^(\d{13,16}|\d{8,9})$/
+ $payinfo =~ /^(\d{13,19}|\d{8,9})$/
or errorpage(gettext('invalid_card'));
$payinfo = $1;
validate($payinfo)
or errorpage(gettext('invalid_card'));
- unless ( $payinfo =~ /^99\d{14}$/ ) { #token
+ unless ( $cust_main->tokenized($payinfo) ) { #token
my $cardtype = cardtype($payinfo);
die "unknown payby $payby";
}
- # save first, for proper tokenization later
+ # save first, for proper tokenization
if ( $cgi->param('save') ) {
my %saveopt;
if ( $payby eq 'CARD' ) {
my $bill_location = FS::cust_location->new;
- $bill_location->set( $_ => $cgi->param($_) )
+ $bill_location->set( $_ => scalar($cgi->param($_)) )
foreach @{$payby2fields{$payby}};
$saveopt{'bill_location'} = $bill_location;
$saveopt{'paycvv'} = $paycvv; # save_cust_payby contains conf logic for when to use this
}
my $error = $cust_main->save_cust_payby(
+ 'saved_cust_payby' => \$cust_payby,
'payment_payby' => $payby,
'auto' => scalar($cgi->param('auto')),
'weight' => scalar($cgi->param('weight')),
errorpage("error saving info, payment not processed: $error")
if $error;
+
+ } elsif ( $payby eq 'CARD' ) { # not saving
+
+ $paymask = FS::payinfo_Mixin->mask_payinfo('CARD',$payinfo); # for untokenized but tokenizable payinfo
+
}
}
my $error = '';
my $paynum = '';
+my $paydate;
+if ($cust_payby->paydate) { $paydate = "$year-$month-01"; }
+else { $paydate = "2037-12-01"; }
+
if ( $cgi->param('batch') ) {
$error = 'Prepayment discounts not supported with batched payments'
'payby' => $payby,
'amount' => $amount,
'payinfo' => $payinfo,
- 'paydate' => "$year-$month-01",
+ 'paydate' => $paydate,
'payname' => $payname,
+ 'invnum' => $invoice,
map { $_ => scalar($cgi->param($_)) }
@{$payby2fields{$payby}}
);
} else {
$error = $cust_main->realtime_bop( $FS::payby::payby2bop{$payby}, $amount,
+ 'cust_payby' => $cust_payby, # if defined, will override passed payinfo, etc
'quiet' => 1,
'manual' => 1,
'balance' => $balance,
'paynum_ref' => \$paynum,
'discount_term' => $discount_term,
'no_auto_apply' => ($cgi->param('apply') eq 'never') ? 'Y' : '',
+ 'no_invnum' => 1,
+ 'invnum' => $invoice,
map { $_ => scalar($cgi->param($_)) } @{$payby2fields{$payby}}
);
errorpage($error) if $error;
#and generate an invoice for it now too
$error = $cust_main->bill( 'pkg_list' => [ $cust_pkg ] );
- errorpage("payment processed and fee ordered sucessfully, but error billing fee: $error")
+ errorpage("payment processed and fee ordered successfully, but error billing fee: $error")
if $error;
}