X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=FS%2FFS%2Fcust_main.pm;h=1d2e9edcd162b36a73d861ddea7aca577c871a15;hp=0283e3d04759fe6c6a06639861cb651834afab38;hb=3da1a075bdfba74af39b52a468241bc2e12d2692;hpb=ea1d9968a9439272b58593e6b2ccbb3869002b20 diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index 0283e3d04..1d2e9edcd 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -172,6 +172,8 @@ FS::Record. The following fields are currently supported: =item payinfo - card number, P.O., comp issuer (4-8 lowercase alphanumerics; think username) or prepayment identifier (see L) +=item paycvv - Card Verification Value, "CVV2" (also known as CVC2 or CID), the 3 or 4 digit number on the back (or front, for American Express) of the credit card + =item paydate - expiration date, mm/yyyy, m/yyyy, mm/yy or m/yy =item payname - name on card or billing name @@ -773,6 +775,21 @@ sub check { or return gettext('invalid_card'); # . ": ". $self->payinfo; return gettext('unknown_card_type') if cardtype($self->payinfo) eq "Unknown"; + if ( defined $self->dbdef_table->column('paycvv') ) { + if ( length($self->paycvv) ) { + if ( cardtype($self->payinfo) eq 'American Express card' ) { + $self->paycvv =~ /^(\d{4})$/ + or return "CVV2 (CID) for American Express cards is four digits."; + $self->paycvv($1); + } else { + $self->paycvv =~ /^(\d{3})$/ + or return "CVV2 (CVC2/CID) is three digits."; + $self->paycvv($1); + } + } else { + $self->paycvv(''); + } + } } elsif ( $self->payby eq 'CHEK' || $self->payby eq 'DCHK' ) { @@ -781,6 +798,7 @@ sub check { $payinfo =~ /^(\d+)\@(\d{9})$/ or return 'invalid echeck account@aba'; $payinfo = "$1\@$2"; $self->payinfo($payinfo); + $self->paycvv('') if $self->dbdef_table->column('paycvv'); } elsif ( $self->payby eq 'LECB' ) { @@ -789,11 +807,13 @@ sub check { $payinfo =~ /^1?(\d{10})$/ or return 'invalid btn billing telephone number'; $payinfo = $1; $self->payinfo($payinfo); + $self->paycvv('') if $self->dbdef_table->column('paycvv'); } elsif ( $self->payby eq 'BILL' ) { $error = $self->ut_textn('payinfo'); return "Illegal P.O. number: ". $self->payinfo if $error; + $self->paycvv('') if $self->dbdef_table->column('paycvv'); } elsif ( $self->payby eq 'COMP' ) { @@ -804,6 +824,7 @@ sub check { $error = $self->ut_textn('payinfo'); return "Illegal comp account issuer: ". $self->payinfo if $error; + $self->paycvv('') if $self->dbdef_table->column('paycvv'); } elsif ( $self->payby eq 'PREPAY' ) { @@ -814,6 +835,7 @@ sub check { return "Illegal prepayment identifier: ". $self->payinfo if $error; return "Unknown prepayment identifier" unless qsearchs('prepay_credit', { 'identifier' => $self->payinfo } ); + $self->paycvv('') if $self->dbdef_table->column('paycvv'); } @@ -1215,7 +1237,7 @@ sub bill { || $tax->recurtax =~ /^Y$/i; next unless $taxable_charged; - if ( $tax->exempt_amount ) { + if ( $tax->exempt_amount > 0 ) { my ($mon,$year) = (localtime($sdate) )[4,5]; $mon++; my $freq = $part_pkg->freq || 1; @@ -1666,15 +1688,20 @@ sub realtime_bop { my %content; if ( $method eq 'CC' ) { + $content{card_number} = $self->payinfo; $self->paydate =~ /^\d{2}(\d{2})[\/\-](\d+)[\/\-]\d+$/; $content{expiration} = "$2/$1"; - if ( qsearch('cust_pay', { 'custnum' => $self->custnum, + + $content{cvv2} = $self->paycvv + if defined $self->dbdef_table->column('paycvv') + && length($self->paycvv); + + $content{recurring_billing} = 'YES' + if qsearch('cust_pay', { 'custnum' => $self->custnum, 'payby' => 'CARD', - 'payinfo' => $self->payinfo, } ) - ) { - $content{recurring_billing} = 'YES'; - } + 'payinfo' => $self->payinfo, } ); + } elsif ( $method eq 'ECHECK' ) { my($account_number,$routing_code) = $self->payinfo; ( $content{account_number}, $content{routing_code} ) = @@ -1759,6 +1786,21 @@ sub realtime_bop { } + #remove paycvv after initial transaction + #make this disable-able via a config option if anyone insists? + # (though that probably violates cardholder agreements) + if ( defined $self->dbdef_table->column('paycvv') + && length($self->paycvv) + && ! grep { $_ eq cardtype($self->payinfo) } $conf->config('cvv-save') + ) { + my $new = new FS::cust_main { $self->hash }; + $new->paycvv(''); + my $error = $new->replace($self); + if ( $error ) { + warn "error removing cvv: $error\n"; + } + } + #result handling if ( $transaction->is_success() ) {