our $ignore_expired_card = 0;
our $ignore_banned_card = 0;
our $ignore_invalid_card = 0;
+our $ignore_cardtype = 0;
our $conf;
install_callback FS::UID sub {
? shift
: $self->replace_old;
- if ( length($old->paycvv) && $self->paycvv =~ /^\s*[\*x]*\s*$/ ) {
- $self->paycvv($old->paycvv);
- }
-
if ( $self->payby =~ /^(CARD|DCRD)$/
&& ( $self->payinfo =~ /xx/
|| $self->payinfo =~ /^\s*N\/A\s+\(tokenized\)\s*$/
$self->payinfo($new_account.'@'.$new_aba);
}
+ # only unmask paycvv if payinfo stayed the same
+ if ( $self->payby =~ /^(CARD|DCRD)$/ and $self->paycvv =~ /^\s*[\*x]+\s*$/ ) {
+ if ( $old->payinfo eq $self->payinfo
+ && $old->paymask eq $self->paymask
+ ) {
+ $self->paycvv($old->paycvv);
+ } else {
+ $self->paycvv('');
+ }
+ }
+
local($ignore_expired_card) = 1
if $old->payby =~ /^(CARD|DCRD)$/
&& $self->payby =~ /^(CARD|DCRD)$/
{
my $error = $self->check_payinfo_cardtype;
return $error if $error;
+
+ if ( $conf->exists('business-onlinepayment-verification') ) {
+ $error = $self->verify;
+ return $error if $error;
+ }
}
local $SIG{HUP} = 'IGNORE';
}
- ###
+ if ( ! $self->custpaybynum
+ && $conf->exists('business-onlinepayment-verification') ) {
+ $error = $self->verify;
+ return $error if $error;
+ }
$self->SUPER::check;
}
sub check_payinfo_cardtype {
my $self = shift;
+ return '' if $ignore_cardtype;
+
return '' unless $self->payby =~ /^(CARD|CHEK)$/;
my $payinfo = $self->payinfo;
}
+=item verify
+
+=cut
+
+sub verify {
+ my $self = shift;
+ return '' unless $self->payby =~ /^(CARD|DCRD)$/;
+
+ my %opt = ();
+
+ # false laziness with check
+ my( $m, $y );
+ if ( $self->paydate =~ /^(\d{1,2})[\/\-](\d{2}(\d{2})?)$/ ) {
+ ( $m, $y ) = ( $1, length($2) == 4 ? $2 : "20$2" );
+ } elsif ( $self->paydate =~ /^19(\d{2})[\/\-](\d{1,2})[\/\-]\d+$/ ) {
+ ( $m, $y ) = ( $2, "19$1" );
+ } elsif ( $self->paydate =~ /^(20)?(\d{2})[\/\-](\d{1,2})[\/\-]\d+$/ ) {
+ ( $m, $y ) = ( $3, "20$2" );
+ } else {
+ return "Illegal expiration date: ". $self->paydate;
+ }
+ $m = sprintf('%02d',$m);
+ $opt{paydate} = "$y-$m-01";
+
+ $opt{$_} = $self->$_() for qw( payinfo payname paycvv );
+
+ if ( $self->locationnum ) {
+ my $cust_location = $self->cust_location;
+ $opt{$_} = $cust_location->$_() for qw( address1 address2 city state zip );
+ }
+
+ $self->cust_main->realtime_verify_bop({
+ 'method' => FS::payby->payby2bop( $self->payby ),
+ %opt,
+ });
+
+}
+
=item paytypes
Returns a list of valid values for the paytype field (bank account type for
'CARD' => 'DCRD',
'CHEK' => 'DCHK',
);
+ # the payby selector gives the choice of CARD or CHEK (or others, but
+ # those are the ones with auto and on-demand versions). if the user didn't
+ # choose a weight, then they mean DCRD/DCHK.
$hashref->{payby} = $noauto{$hashref->{payby}}
if ! $hashref->{weight} && exists $noauto{$hashref->{payby}};
' LEFT JOIN cust_location AS '.$pre.'location '.
'ON (cust_main.'.$pre.'locationnum = '.$pre.'location.locationnum) ';
}
+ # always make referral available in results
+ # (maybe we should be using FS::UI::Web::join_cust_main instead?)
+ $addl_from .= ' LEFT JOIN (select refnum, referral from part_referral) AS part_referral_x ON (cust_main.refnum = part_referral_x.refnum) ';
my $count_query = "SELECT COUNT(*) FROM cust_payby $addl_from $extra_sql";