X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fpayinfo_Mixin.pm;h=6023aa2174278271e9332b1c408a07e4de43a86d;hb=5744a93e395c6d7b4203795ca2aec2527b225ee5;hp=b030bd73493b75a9a92a06e4f4d08e7562f69bae;hpb=22df3382a4cd84771550dad390321b150509138f;p=freeside.git diff --git a/FS/FS/payinfo_Mixin.pm b/FS/FS/payinfo_Mixin.pm index b030bd734..6023aa217 100644 --- a/FS/FS/payinfo_Mixin.pm +++ b/FS/FS/payinfo_Mixin.pm @@ -4,8 +4,11 @@ use strict; use Business::CreditCard; use FS::payby; use FS::Record qw(qsearch); +use FS::UID qw(driver_name); +use FS::Cursor; +use Time::Local qw(timelocal); -use vars qw($ignore_masked_payinfo); +use vars qw( $ignore_masked_payinfo $allow_closed_replace ); =head1 NAME @@ -38,14 +41,15 @@ For Customers (cust_main): For Refunds (cust_refund): 'CARD' (credit cards), 'CHEK' (electronic check/ACH), 'LECB' (Phone bill billing), 'BILL' (billing), 'CASH' (cash), -'WEST' (Western Union), 'MCRD' (Manual credit card), 'CBAK' Chargeback, or 'COMP' (free) +'WEST' (Western Union), 'MCRD' (Manual credit card), 'MCHK' (Manual electronic +check), 'CBAK' Chargeback, or 'COMP' (free) For Payments (cust_pay): 'CARD' (credit cards), 'CHEK' (electronic check/ACH), 'LECB' (phone bill billing), 'BILL' (billing), 'PREP' (prepaid card), -'CASH' (cash), 'WEST' (Western Union), 'MCRD' (Manual credit card), -'PPAL' (PayPal) +'CASH' (cash), 'WEST' (Western Union), 'MCRD' (Manual credit card), 'MCHK' +(Manual electronic check), 'PPAL' (PayPal) 'COMP' (free) is depricated as a payment type in cust_pay =cut @@ -133,7 +137,11 @@ sub mask_payinfo { return 'N/A (tokenized)'; #? } else { # if not, mask it... - if ($payby eq 'CARD' || $payby eq 'DCRD' || $payby eq 'MCRD') { + if ($payby eq 'CARD' || $payby eq 'DCRD') { + #|| $payby eq 'MCRD') { + #MCRD isn't a card in payinfo, + #its a record of an _offline_ + #card # Credit Cards @@ -181,23 +189,6 @@ sub mask_payinfo { Checks payby and payinfo. -For Customers (cust_main): -'CARD' (credit card - automatic), 'DCRD' (credit card - on-demand), -'CHEK' (electronic check - automatic), 'DCHK' (electronic check - on-demand), -'LECB' (Phone bill billing), 'BILL' (billing), 'COMP' (free), or -'PREPAY' (special billing type: applies a credit - see L and sets billing type to I) - -For Refunds (cust_refund): -'CARD' (credit cards), 'CHEK' (electronic check/ACH), -'LECB' (Phone bill billing), 'BILL' (billing), 'CASH' (cash), -'WEST' (Western Union), 'MCRD' (Manual credit card), 'CBAK' (Chargeback), or 'COMP' (free) - -For Payments (cust_pay): -'CARD' (credit cards), 'CHEK' (electronic check/ACH), -'LECB' (phone bill billing), 'BILL' (billing), 'PREP' (prepaid card), -'CASH' (cash), 'WEST' (Western Union), or 'MCRD' (Manual credit card) -'COMP' (free) is depricated as a payment type in cust_pay - =cut sub payinfo_check { @@ -207,10 +198,27 @@ sub payinfo_check { or return "Illegal payby: ". $self->payby; if ( $self->payby eq 'CARD' && ! $self->is_encrypted($self->payinfo) ) { - my $payinfo = $self->payinfo; + + unless ( $self->paycardtype ) { + + if ( $self->payinfo =~ /^99\d{14}$/ ) { + if ( $self->paymask =~ /^\d+x/ ) { + $self->set('paycardtype', cardtype($self->paymask)); + } else { + $self->set('paycardtype', ''); + # return "paycardtype required ". + # "(can't derive from a token and no paymask w/prefix provided)"; + } + } else { + $self->set('paycardtype', cardtype($self->payinfo)); + } + + } + if ( $ignore_masked_payinfo and $self->mask_payinfo eq $self->payinfo ) { # allow it } else { + my $payinfo = $self->payinfo; $payinfo =~ s/\D//g; $self->payinfo($payinfo); if ( $self->payinfo ) { @@ -218,13 +226,27 @@ sub payinfo_check { or return "Illegal (mistyped?) credit card number (payinfo)"; $self->payinfo($1); validate($self->payinfo) or return "Illegal credit card number"; - return "Unknown card type" if $self->payinfo !~ /^99\d{14}$/ #token - && cardtype($self->payinfo) eq "Unknown"; + return "Unknown card type" if $self->paycardtype eq "Unknown"; } else { $self->payinfo('N/A'); #??? } } + } else { + + unless ( $self->paycardtype ) { + + if ( $self->payby eq 'CARD' && $self->paymask =~ /^\d+x/ ) { + # if we can't decrypt the card, at least detect the cardtype + $self->set('paycardtype', cardtype($self->paymask)); + } else { + $self->set('paycardtype', ''); + # return "paycardtype required ". + # "(can't derive from a token and no paymask w/prefix provided)"; + } + + } + if ( $self->is_encrypted($self->payinfo) ) { #something better? all it would cause is a decryption error anyway? my $error = $self->ut_anything('payinfo'); @@ -235,6 +257,7 @@ sub payinfo_check { } } + return ''; } =item payby_payinfo_pretty [ LOCALE ] @@ -255,7 +278,11 @@ sub payby_payinfo_pretty { my $locale = shift; my $lh = FS::L10N->get_handle($locale); if ( $self->payby eq 'CARD' ) { - $lh->maketext('Card #') . $self->paymask; + if ($self->paymask =~ /tokenized/) { + $lh->maketext('Tokenized Card'); + } else { + $lh->maketext('Card #') . $self->paymask; + } } elsif ( $self->payby eq 'CHEK' ) { #false laziness w/view/cust_main/payment_history.html::translate_payinfo @@ -280,6 +307,8 @@ sub payby_payinfo_pretty { $lh->maketext('Western Union'); } elsif ( $self->payby eq 'MCRD' ) { $lh->maketext('Manual credit card'); + } elsif ( $self->payby eq 'MCHK' ) { + $lh->maketext('Manual electronic check'); } elsif ( $self->payby eq 'EDI' ) { $lh->maketext('EDI') . ' ' . $self->paymask; } elsif ( $self->payby eq 'PPAL' ) { @@ -301,18 +330,39 @@ sub payinfo_used { my $payinfo = shift || $self->payinfo; my %hash = ( 'custnum' => $self->custnum, - 'payby' => 'CARD', + 'payby' => $self->payby, ); return 1 if qsearch('cust_pay', { %hash, 'payinfo' => $payinfo } ) - || qsearch('cust_pay', - { %hash, 'paymask' => $self->mask_payinfo('CARD', $payinfo) } ) + || qsearch('cust_pay', { %hash, 'paymask' => $self->mask_payinfo } ) ; return 0; } +=item upgrade_set_cardtype + +Find all records with a credit card payment type and no paycardtype, and +replace them in order to set their paycardtype. + +=cut + +sub upgrade_set_cardtype { + my $class = shift; + # assign cardtypes to CARD/DCRDs that need them; check_payinfo_cardtype + # will do this. ignore any problems with the cards. + local $ignore_masked_payinfo = 1; + my $search = FS::Cursor->new({ + table => $class->table, + extra_sql => q[ WHERE payby IN('CARD','DCRD') AND paycardtype IS NULL ], + }); + while (my $record = $search->fetch) { + my $error = $record->replace; + die $error if $error; + } +} + =back =head1 BUGS