From: ivan Date: Fri, 24 Oct 2003 19:30:44 +0000 (+0000) Subject: cvv! X-Git-Tag: NET_WHOIS_RAW_0_31~309 X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=commitdiff_plain;h=f63c0e821610c885f9f49d301eeccf804e1ca6d3 cvv! --- diff --git a/FS/FS/ClientAPI/Signup.pm b/FS/FS/ClientAPI/Signup.pm index 5ca1f93ed..92fc6361d 100644 --- a/FS/FS/ClientAPI/Signup.pm +++ b/FS/FS/ClientAPI/Signup.pm @@ -60,6 +60,8 @@ sub signup_info { 'payby' => [ $conf->config('signup_server-payby') ], + 'cvv_enabled' => defined dbdef->table('cust_main')->column('paycvv'), + 'msgcat' => { map { $_=>gettext($_) } qw( passwords_dont_match invalid_card unknown_card_type not_a ) }, @@ -116,7 +118,8 @@ sub new_customer { map { $_ => $packet->{$_} } qw( last first ss company address1 address2 city county state zip country - daytime night fax payby payinfo paydate payname referral_custnum comments + daytime night fax payby payinfo paycvv paydate payname referral_custnum + comments ), } ); diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index 2ba0ff046..0ab2aa50d 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'); } @@ -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,20 @@ 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) + ) { + 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() ) { diff --git a/FS/bin/freeside-setup b/FS/bin/freeside-setup index 375a63c2f..80b74c1f1 100755 --- a/FS/bin/freeside-setup +++ b/FS/bin/freeside-setup @@ -502,6 +502,7 @@ sub tables_hash_hack { 'ship_fax', 'varchar', 'NULL', 12, 'payby', 'char', '', 4, 'payinfo', 'varchar', 'NULL', $char_d, + 'paycvv', 'varchar', 'NULL', 4, #'paydate', @date_type, 'paydate', 'varchar', 'NULL', 10, 'payname', 'varchar', 'NULL', $char_d, diff --git a/fs_signup/FS-SignupClient/SignupClient.pm b/fs_signup/FS-SignupClient/SignupClient.pm index 1d91a418f..fb2b12fb0 100644 --- a/fs_signup/FS-SignupClient/SignupClient.pm +++ b/fs_signup/FS-SignupClient/SignupClient.pm @@ -43,6 +43,7 @@ FS::SignupClient - Freeside signup client API 'fax' => $fax, 'payby' => $payby, 'payinfo' => $payinfo, + 'paycvv' => $paycvv, 'paydate' => $paydate, 'payname' => $payname, 'invoicing_list' => $invoicing_list, @@ -125,6 +126,7 @@ a paramater with the following keys: fax payby payinfo + paycvv paydate payname invoicing_list diff --git a/fs_signup/FS-SignupClient/cgi/cvv2.html b/fs_signup/FS-SignupClient/cgi/cvv2.html new file mode 100644 index 000000000..b178c8513 --- /dev/null +++ b/fs_signup/FS-SignupClient/cgi/cvv2.html @@ -0,0 +1,25 @@ + + + + CVV2 information + + + + The CVV2 number (also called CVC2 or CID) is a three- or four-digit + security code used to reduce credit card fraud.

+ + + + + + + + +
Visa / MasterCard / DiscoverAmerican Express
+ Visa/MasterCard/Discover + + American Express +
+
(close window)
+ + diff --git a/fs_signup/FS-SignupClient/cgi/cvv2.png b/fs_signup/FS-SignupClient/cgi/cvv2.png new file mode 100644 index 000000000..4610dcbe6 Binary files /dev/null and b/fs_signup/FS-SignupClient/cgi/cvv2.png differ diff --git a/fs_signup/FS-SignupClient/cgi/cvv2_amex.png b/fs_signup/FS-SignupClient/cgi/cvv2_amex.png new file mode 100644 index 000000000..21c36a0ab Binary files /dev/null and b/fs_signup/FS-SignupClient/cgi/cvv2_amex.png differ diff --git a/fs_signup/FS-SignupClient/cgi/signup.cgi b/fs_signup/FS-SignupClient/cgi/signup.cgi index 2458bcf19..70facb570 100755 --- a/fs_signup/FS-SignupClient/cgi/signup.cgi +++ b/fs_signup/FS-SignupClient/cgi/signup.cgi @@ -1,6 +1,6 @@ #!/usr/bin/perl -Tw # -# $Id: signup.cgi,v 1.46 2003-10-14 17:00:00 ivan Exp $ +# $Id: signup.cgi,v 1.47 2003-10-24 19:28:49 ivan Exp $ use strict; use vars qw( @payby $cgi $locales $packages @@ -8,7 +8,7 @@ use vars qw( @payby $cgi $locales $packages $init_data $error $last $first $ss $company $address1 $address2 $city $state $county $country $zip $daytime $night $fax $invoicing_list $payby $payinfo - $paydate $payname $referral_custnum $init_popstate + $paycvv $paydate $payname $referral_custnum $init_popstate $pkgpart $username $password $password2 $sec_phrase $popnum $agentnum $ieak_file $ieak_template $cck_file $cck_template @@ -178,6 +178,9 @@ if ( defined $cgi->param('magic') ) { $paydate = $cgi->param( $payby. '_month' ). '-'. $cgi->param( $payby. '_year' ); $payname = $cgi->param( $payby. '_payname' ); + $paycvv = defined $cgi->param( $payby. '_paycvv' ) + ? $cgi->param( $payby. '_paycvv' ) + : ''; if ( $invoicing_list = $cgi->param('invoicing_list') ) { $invoicing_list .= ', POST' if $cgi->param('invoicing_list_POST'); @@ -252,6 +255,7 @@ if ( defined $cgi->param('magic') ) { 'fax' => $fax, 'payby' => $payby, 'payinfo' => $payinfo, + 'paycvv' => $paycvv, 'paydate' => $paydate, 'payname' => $payname, 'invoicing_list' => $invoicing_list, diff --git a/fs_signup/FS-SignupClient/cgi/signup.html b/fs_signup/FS-SignupClient/cgi/signup.html index 80774099c..dc4252c73 100755 --- a/fs_signup/FS-SignupClient/cgi/signup.html +++ b/fs_signup/FS-SignupClient/cgi/signup.html @@ -1,5 +1,18 @@ ISP Signup form -ISP Signup form

+ + +ISP Signup form

<%= $error %>
@@ -101,6 +114,12 @@ Contact Information 'PREPAY' => qq!Prepaid card
*!, ); + if ( $init_data->{'cvv_enabled'} ) { + foreach my $payby ( grep { exists $payby{$_} } qw(CARD DCRD) ) { #1.4/1.5 + $payby{$payby} .= qq!
CVV2 (help!; + } + } + my( $account, $aba ) = split('@', $payinfo); my %paybychecked = ( 'CARD' => qq!Credit card
*$cardselect
*Exp !. expselect("CARD", $paydate). qq!
*Name on card
!, @@ -113,6 +132,12 @@ Contact Information 'PREPAY' => qq!Prepaid card
*!, ); + if ( $init_data->{'cvv_enabled'} ) { + foreach my $payby ( grep { exists $payby{$_} } qw(CARD DCRD) ) { #1.4/1.5 + $paybychecked{$payby} .= qq!
CVV2 (help!; + } + } + for (@payby) { if ( scalar(@payby) == 1) { $OUT .= ''. diff --git a/httemplate/docs/cvv2.html b/httemplate/docs/cvv2.html new file mode 100644 index 000000000..fe8a17f6f --- /dev/null +++ b/httemplate/docs/cvv2.html @@ -0,0 +1,25 @@ + + + + CVV2 information + + + + The CVV2 number (also called CVC2 or CID) is a three- or four-digit + security code used to reduce credit card fraud.

+ + + + + + + + +
Visa / MasterCard / DiscoverAmerican Express
+ Visa/MasterCard/Discover + + American Express +
+
(close window)
+ + diff --git a/httemplate/docs/schema.html b/httemplate/docs/schema.html index bef567186..06be8960d 100644 --- a/httemplate/docs/schema.html +++ b/httemplate/docs/schema.html @@ -121,6 +121,7 @@
  • ship_fax
  • payby - CARD, DCHK, CHEK, DCHK, LECB, BILL, or COMP
  • payinfo - card number, P.O.#, or comp issuer +
  • 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
  • paydate - expiration date
  • payname - billing name (name on card)
  • tax - tax exempt, Y or null diff --git a/httemplate/docs/upgrade10.html b/httemplate/docs/upgrade10.html index 446090503..080528bac 100644 --- a/httemplate/docs/upgrade10.html +++ b/httemplate/docs/upgrade10.html @@ -1,7 +1,7 @@
     this is incomplete
     
    -install DBIx::DBSchema 0.21
    +install DBIx::DBSchema 0.22
     
     install NetAddr::IP and Chart::Base
     
    @@ -142,6 +142,8 @@ ALTER TABLE agent ADD username varchar(80) NULL;
     ALTER TABLE h_agent ADD username varchar(80) NULL;
     ALTER TABLE agent ADD _password varchar(80) NULL;
     ALTER TABLE h_agent ADD _password varchar(80) NULL;
    +ALTER TABLE cust_main ADD paycvv varchar(4) NULL;
    +ALTER TABLE h_cust_main ADD paycvv varchar(4) NULL;
     
     dump database, edit:
     - cust_main: increase otaker from 8 to 32
    diff --git a/httemplate/edit/cust_main.cgi b/httemplate/edit/cust_main.cgi
    index 73a0eef49..1909b5438 100755
    --- a/httemplate/edit/cust_main.cgi
    +++ b/httemplate/edit/cust_main.cgi
    @@ -39,6 +39,12 @@ if ( $cgi->param('error') ) {
       $query =~ /^(\d+)$/;
       $custnum=$1;
       $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } );
    +  if ( $cust_main->dbdef_table->column('paycvv')
    +       && length($cust_main->paycvv)             ) {
    +    my $paycvv = $cust_main->paycvv;
    +    $paycvv =~ s/./*/g;
    +    $cust_main->paycvv($paycvv);
    +  }
       $saved_pkgpart = 0;
       $username = '';
       $password = '';
    @@ -61,7 +67,7 @@ my $action = $custnum ? 'Edit' : 'Add';
     # top
     
     my $p1 = popurl(1);
    -print header("Customer $action", '');
    +print header("Customer $action", '', ' onUnload="myclose()"');
     print qq!Error: !, $error, ""
       if $error;
     
    @@ -400,7 +406,19 @@ if ( $payby_default eq 'HIDE' ) {
       print qq!Email invoice !;
     
       print "Billing type",
    -        "",
    +        "", '',
             &table("#cccccc"), "";
     
       my($payinfo, $payname)=(
    @@ -418,6 +436,12 @@ if ( $payby_default eq 'HIDE' ) {
         'COMP' => qq!Complimentary
    ${r}Approved by
    ${r}Exp !. expselect("COMP"), ); + if ( $cust_main->dbdef_table->column('paycvv') ) { + foreach my $payby ( grep { exists $payby{$_} } qw(CARD DCRD) ) { #1.4/1.5 bs + $payby{$payby} .= qq!
    CVV2 (help!; + } + } + my( $account, $aba ) = split('@', $payinfo); my %paybychecked = ( @@ -430,6 +454,15 @@ if ( $payby_default eq 'HIDE' ) { 'COMP' => qq!Complimentary
    ${r}Approved by
    ${r}Exp !. expselect("COMP", $cust_main->paydate), ); + if ( $cust_main->dbdef_table->column('paycvv') ) { + my $paycvv = $cust_main->paycvv; + + foreach my $payby ( grep { exists $payby{$_} } qw(CARD DCRD) ) { #1.4/1.5 bs + $paybychecked{$payby} .= qq!
    CVV2 (help!; + } + } + + $cust_main->payby($payby_default) unless $cust_main->payby; for (qw(CARD DCRD CHEK DCHK LECB BILL COMP)) { print qq!param('paydate', $cgi->param( $payby. '_month' ). '-'. $cgi->param( $payby. '_year' ) ); $cgi->param('payname', $cgi->param( $payby. '_payname' ) ); + $cgi->param('paycvv', $cgi->param( $payby. '_paycvv' ) ) + if defined $cgi->param( $payby. '_paycvv' ); } $cgi->param('otaker', &getotaker ); @@ -27,6 +29,7 @@ my @invoicing_list = split( /\s*\,\s*/, $cgi->param('invoicing_list') ); push @invoicing_list, 'POST' if $cgi->param('invoicing_list_POST'); $cgi->param('invoicing_list', join(',', @invoicing_list) ); + #create new record object my $new = new FS::cust_main ( { @@ -113,6 +116,11 @@ if ( $new->custnum eq '' ) { } else { #create old record object my $old = qsearchs( 'cust_main', { 'custnum' => $new->custnum } ); $error ||= "Old record not found!" unless $old; + if ( defined dbdef->table('cust_main')->column('paycvv') + && length($old->paycvv) + && $new->paycvv =~ /^\s*\*+\s*$/ ) { + $new->paycvv($old->paycvv); + } $error ||= $new->replace($old, \@invoicing_list); }