diff options
author | ivan <ivan> | 2002-10-12 10:15:55 +0000 |
---|---|---|
committer | ivan <ivan> | 2002-10-12 10:15:55 +0000 |
commit | eb9d5b215af1fbe867b75c12328126f650f9fb06 (patch) | |
tree | bfc994ef2819d9aea69e37f05a8a22e206682b2e /FS | |
parent | 5f062fcd57e44d412cdf036649c38db5353a72f9 (diff) |
ACH support
Diffstat (limited to 'FS')
-rw-r--r-- | FS/FS/Conf.pm | 4 | ||||
-rw-r--r-- | FS/FS/cust_bill.pm | 73 | ||||
-rw-r--r-- | FS/FS/cust_main.pm | 20 | ||||
-rw-r--r-- | FS/FS/cust_pay.pm | 7 | ||||
-rw-r--r-- | FS/FS/cust_refund.pm | 7 | ||||
-rw-r--r-- | FS/FS/part_bill_event.pm | 2 |
6 files changed, 77 insertions, 36 deletions
diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 20e42183b..204d26af3 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -870,7 +870,7 @@ httemplate/docs/config.html 'section' => '', 'description' => 'Acceptable payment types for the signup server', 'type' => 'selectmultiple', - 'select_enum' => [ qw(CARD PREPAY BILL COMP) ], + 'select_enum' => [ qw(CARD CHEK PREPAY BILL COMP) ], }, { @@ -957,7 +957,7 @@ httemplate/docs/config.html 'section' => 'UI', 'description' => 'Default payment type. HIDE disables display of billing information and sets customers to BILL.', 'type' => 'select', - 'select_enum' => [ '', 'CARD', 'BILL', 'COMP', 'HIDE' ], + 'select_enum' => [ '', qw(CARD CHEK BILL COMP HIDE) ], }, { diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index 296c8b6a6..e875f5229 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -583,32 +583,48 @@ sub comp { =item realtime_card -Attempts to pay this invoice with a Business::OnlinePayment realtime gateway. -See http://search.cpan.org/search?mode=module&query=Business%3A%3AOnlinePayment -for supproted processors. +Attempts to pay this invoice with a credit card payment via a +Business::OnlinePayment realtime gateway. See +http://search.cpan.org/search?mode=module&query=Business%3A%3AOnlinePayment +for supported processors. =cut sub realtime_card { my $self = shift; + $self->realtime_bop('CC', @_); +} + +=item realtime_ach + +Attempts to pay this invoice with an electronic check (ACH) payment via a +Business::OnlinePayment realtime gateway. See +http://search.cpan.org/search?mode=module&query=Business%3A%3AOnlinePayment +for supported processors. + +=cut + +sub realtime_ach { + my $self = shift; + $self->realtime_bop('ECHECK', @_); +} + +sub realtime_bop { + my $self = shift; + my $method = shift; my $cust_main = $self->cust_main; my $amount = $self->owed; unless ( $processor =~ /^Business::OnlinePayment::(.*)$/ ) { - return "Real-time card processing not enabled (processor $processor)"; + return "Real-time card/ACH processing not enabled (processor $processor)"; } my $bop_processor = $1; #hmm? my $address = $cust_main->address1; $address .= ", ". $cust_main->address2 if $cust_main->address2; - #fix exp. date - #$cust_main->paydate =~ /^(\d+)\/\d*(\d{2})$/; - $cust_main->paydate =~ /^\d{2}(\d{2})[\/\-](\d+)[\/\-]\d+$/; - my $exp = "$2/$1"; - my($payname, $payfirst, $paylast); - if ( $cust_main->payname ) { + if ( $cust_main->payname && $method ne 'ECHECK' ) { $payname = $cust_main->payname; $payname =~ /^\s*([\w \,\.\-\']*)?\s+([\w\,\.\-\']+)\s*$/ or do { @@ -646,11 +662,24 @@ sub realtime_card { $description = eval qq("$dtempl"); } + + my %content; + if ( $method eq 'CC' ) { + $content{card_number} = $cust_main->payinfo; + $cust_main->paydate =~ /^\d{2}(\d{2})[\/\-](\d+)[\/\-]\d+$/; + $content{expiration} = "$2/$1"; + } elsif ( $method eq 'ECHECK' ) { + my($account_number,$routing_code) = $cust_main->payinfo + ( $content{account_number}, $content{routing_code} ) = + split('@', $cust_main->payinfo); + $content{bank_name} = $cust_main->payname; + } my $transaction = new Business::OnlinePayment( $bop_processor, @bop_options ); $transaction->content( - 'type' => 'CC', + %content, + 'type' => $method, 'login' => $bop_login, 'password' => $bop_password, 'action' => $action1, @@ -666,8 +695,6 @@ sub realtime_card { 'state' => $cust_main->state, 'zip' => $cust_main->zip, 'country' => $cust_main->country, - 'card_number' => $cust_main->payinfo, - 'expiration' => $exp, 'referer' => 'http://cleanwhisker.420.am/', 'email' => $email, 'phone' => $cust_main->daytime || $cust_main->night, @@ -686,7 +713,8 @@ sub realtime_card { new Business::OnlinePayment( $bop_processor, @bop_options ); my %capture = ( - type => 'CC', + %content, + type => $method, action => $action2, login => $bop_login, password => $bop_password, @@ -694,8 +722,6 @@ sub realtime_card { amount => $amount, authorization => $auth, description => $description, - card_number => $cust_main->payinfo, - expiration => $exp, ); foreach my $field (qw( authorization_source_code returned_ACI transaction_identifier validation_code @@ -720,18 +746,23 @@ sub realtime_card { if ( $transaction->is_success() ) { + my %method2payby = ( + 'CC' => 'CARD', + 'ECHECK' => 'CHEK', + ); + my $cust_pay = new FS::cust_pay ( { 'invnum' => $self->invnum, 'paid' => $amount, '_date' => '', - 'payby' => 'CARD', + 'payby' => method2payby{$method}, 'payinfo' => $cust_main->payinfo, 'paybatch' => "$processor:". $transaction->authorization, } ); my $error = $cust_pay->insert; if ( $error ) { # gah, even with transactions. - my $e = 'WARNING: Card debited but database not updated - '. + my $e = 'WARNING: Card/ACH debited but database not updated - '. 'error applying payment, invnum #' . $self->invnum. " ($processor): $error"; warn $e; @@ -766,7 +797,7 @@ sub realtime_card { "Sender: $invoice_from", "Reply-To: $invoice_from", "Date: ". time2str("%a, %d %b %Y %X %z", time), - "Subject: Your credit card could not be processed", + "Subject: Your payment could not be processed", ] ); my $message = new Mail::Internet ( 'Header' => $header, @@ -838,7 +869,7 @@ sub print_text { # my $invnum = $self->invnum; my $cust_main = qsearchs('cust_main', { 'custnum', $self->custnum } ); $cust_main->payname( $cust_main->first. ' '. $cust_main->getfield('last') ) - unless $cust_main->payname; + unless $cust_main->payname && $cust_main->payby ne 'CHEK'; my( $pr_total, @pr_cust_bill ) = $self->previous; #previous balance # my( $cr_total, @cr_cust_credit ) = $self->cust_credit; #credits @@ -1043,7 +1074,7 @@ sub print_text { =head1 VERSION -$Id: cust_bill.pm,v 1.47 2002-10-04 12:09:21 ivan Exp $ +$Id: cust_bill.pm,v 1.48 2002-10-12 10:15:55 ivan Exp $ =head1 BUGS diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index 2701ac35d..d6e4bc1e3 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -158,7 +158,7 @@ FS::Record. The following fields are currently supported: =item ship_fax - phone (optional) -=item payby - `CARD' (credit cards), `BILL' (billing), `COMP' (free), or `PREPAY' (special billing type: applies a credit - see L<FS::prepay_credit> and sets billing type to BILL) +=item payby - `CARD' (credit cards), `CHEK' (electronic check), `BILL' (billing), `COMP' (free), or `PREPAY' (special billing type: applies a credit - see L<FS::prepay_credit> and sets billing type to BILL) =item payinfo - card number, P.O., comp issuer (4-8 lowercase alphanumerics; think username) or prepayment identifier (see L<FS::prepay_credit>) @@ -482,9 +482,9 @@ sub replace { $self->invoicing_list( $invoicing_list ); } - if ( $self->payby eq 'CARD' && + if ( $self->payby =~ /^(CARD|CHEK)$/ && grep { $self->get($_) ne $old->get($_) } qw(payinfo paydate payname) ) { - # card info has changed, want to retry realtime_card invoice events + # card/check info has changed, want to retry realtime_card invoice events #false laziness w/collect foreach my $cust_bill_event ( grep { @@ -664,7 +664,7 @@ sub check { } } - $self->payby =~ /^(CARD|BILL|COMP|PREPAY)$/ + $self->payby =~ /^(CARD|CHEK|BILL|COMP|PREPAY)$/ or return "Illegal payby: ". $self->payby; $self->payby($1); @@ -681,6 +681,14 @@ sub check { return gettext('unknown_card_type') if cardtype($self->payinfo) eq "Unknown"; + } elsif ( $self->payby eq 'CHEK' ) { + + my $payinfo = $self->payinfo; + $payinfo =~ s/[\D\@]//g; + $payinfo =~ /^(\d+)\@(\d{9})$/ or return 'invalid echeck account@aba'; + $payinfo = "$1\@$2"; + $self->payinfo($payinfo); + } elsif ( $self->payby eq 'BILL' ) { $error = $self->ut_textn('payinfo'); @@ -705,7 +713,7 @@ sub check { if ( $self->paydate eq '' || $self->paydate eq '-' ) { return "Expriation date required" - unless $self->payby eq 'BILL' || $self->payby eq 'PREPAY'; + unless $self->payby =~ /^(BILL|PREPAY|CHEK)$/; $self->paydate(''); } else { $self->paydate =~ /^(\d{1,2})[\/\-](\d{2}(\d{2})?)$/ @@ -717,7 +725,7 @@ sub check { if !$import && ( $y<$nowy || ( $y==$nowy && $1<$nowm ) ); } - if ( $self->payname eq '' && + if ( $self->payname eq '' && $self->payby ne 'CHEK' && ( ! $conf->exists('require_cardname') || $self->payby ne 'CARD' ) ) { $self->payname( $self->first. " ". $self->getfield('last') ); } else { diff --git a/FS/FS/cust_pay.pm b/FS/FS/cust_pay.pm index 98eba704b..222691408 100644 --- a/FS/FS/cust_pay.pm +++ b/FS/FS/cust_pay.pm @@ -60,7 +60,8 @@ currently supported: =item _date - specified as a UNIX timestamp; see L<perlfunc/"time">. Also see L<Time::Local> and L<Date::Parse> for conversion functions. -=item payby - `CARD' (credit cards), `BILL' (billing), or `COMP' (free) +=item payby - `CARD' (credit cards), `CHEK' (electronic check/ACH), +`BILL' (billing), or `COMP' (free) =item payinfo - card number, check #, or comp issuer (4-8 lowercase alphanumerics; think username), respectively @@ -346,7 +347,7 @@ sub check { $self->_date(time) unless $self->_date; - $self->payby =~ /^(CARD|BILL|COMP)$/ or return "Illegal payby"; + $self->payby =~ /^(CARD|CHEK|BILL|COMP)$/ or return "Illegal payby"; $self->payby($1); #false laziness with cust_refund::check @@ -405,7 +406,7 @@ sub unapplied { =head1 VERSION -$Id: cust_pay.pm,v 1.21 2002-06-04 14:35:52 ivan Exp $ +$Id: cust_pay.pm,v 1.22 2002-10-12 10:15:55 ivan Exp $ =head1 BUGS diff --git a/FS/FS/cust_refund.pm b/FS/FS/cust_refund.pm index 8fe6876d3..aac320e61 100644 --- a/FS/FS/cust_refund.pm +++ b/FS/FS/cust_refund.pm @@ -47,7 +47,8 @@ inherits from FS::Record. The following fields are currently supported: =item _date - specified as a UNIX timestamp; see L<perlfunc/"time">. Also see L<Time::Local> and L<Date::Parse> for conversion functions. -=item payby - `CARD' (credit cards), `BILL' (billing), or `COMP' (free) +=item payby - `CARD' (credit cards), `CHEK' (electronic check/ACH), +`BILL' (billing), or `COMP' (free) =item payinfo - card number, P.O.#, or comp issuer (4-8 lowercase alphanumerics; think username) @@ -234,7 +235,7 @@ sub check { unless $self->crednum || qsearchs( 'cust_main', { 'custnum' => $self->custnum } ); - $self->payby =~ /^(CARD|BILL|COMP)$/ or return "Illegal payby"; + $self->payby =~ /^(CARD|CHEK|BILL|COMP)$/ or return "Illegal payby"; $self->payby($1); #false laziness with cust_pay::check @@ -266,7 +267,7 @@ sub check { =head1 VERSION -$Id: cust_refund.pm,v 1.18 2002-02-19 03:22:39 jeff Exp $ +$Id: cust_refund.pm,v 1.19 2002-10-12 10:15:55 ivan Exp $ =head1 BUGS diff --git a/FS/FS/part_bill_event.pm b/FS/FS/part_bill_event.pm index a31b09b36..991616bb8 100644 --- a/FS/FS/part_bill_event.pm +++ b/FS/FS/part_bill_event.pm @@ -124,7 +124,7 @@ sub check { $c =~ /^\s*\$cust_main\->(suspend|cancel|invoicing_list_addpost|bill|collect)\(\);\s*("";)?\s*$/ - or $c =~ /^\s*\$cust_bill\->(comp|realtime_card|realtime_card_cybercash|batch_card|send)\(\);\s*$/ + or $c =~ /^\s*\$cust_bill\->(comp|realtime_card|realtime_ach|realtime_card_cybercash|batch_card|send)\(\);\s*$/ or $c =~ /^\s*\$cust_bill\->send\(\'\w+\'\);\s*$/ |