$invoice_from = $conf->config('invoice_from');
$smtpmachine = $conf->config('smtpmachine');
- if ( $conf->exists('cybercash3.2') ) {
- require CCMckLib3_2;
- #qw($MCKversion %Config InitConfig CCError CCDebug CCDebug2);
- require CCMckDirectLib3_2;
- #qw(SendCC2_1Server);
- require CCMckErrno3_2;
- #qw(MCKGetErrorMessage $E_NoErr);
- import CCMckErrno3_2 qw($E_NoErr);
-
- my $merchant_conf;
- ($merchant_conf,$xaction)= $conf->config('cybercash3.2');
- my $status = &CCMckLib3_2::InitConfig($merchant_conf);
- if ( $status != $E_NoErr ) {
- warn "CCMckLib3_2::InitConfig error:\n";
- foreach my $key (keys %CCMckLib3_2::Config) {
- warn " $key => $CCMckLib3_2::Config{$key}\n"
- }
- my($errmsg) = &CCMckErrno3_2::MCKGetErrorMessage($status);
- die "CCMckLib3_2::InitConfig fatal error: $errmsg\n";
- }
- $processor='cybercash3.2';
- } elsif ( $conf->exists('business-onlinepayment') ) {
+ if ( $conf->exists('business-onlinepayment') ) {
( $bop_processor,
$bop_login,
$bop_password,
my @print_text = $self->print_text('', $template);
my @invoicing_list = $self->cust_main->invoicing_list;
- if ( grep { $_ ne 'POST' } @invoicing_list ) { #email invoice
+ if ( grep { $_ ne 'POST' } @invoicing_list or !@invoicing_list ) { #email
+
+ #better to notify this person than silence
+ @invoicing_list = ($invoice_from) unless @invoicing_list;
+
#false laziness w/FS::cust_pay::delete & fs_signup_server && ::realtime_card
#$ENV{SMTPHOSTS} = $smtpmachine;
$ENV{MAILADDRESS} = $invoice_from;
}
- if ( ! @invoicing_list || grep { $_ eq 'POST' } @invoicing_list ) { #postal
+ if ( grep { $_ eq 'POST' } @invoicing_list ) { #postal
open(LPR, "|$lpr")
or return "Can't open pipe to $lpr: $!";
print LPR @print_text;
(B<pkg> through B<edate>) are filled in.
=item invnum - invoice number
+
=item custnum - customer number
+
=item _date - invoice date
+
=item charged - total invoice amount
+
=item first - customer first name
+
=item last - customer first name
+
=item company - company name
+
=item address1 - address line 1
+
=item address2 - address line 1
+
=item city
+
=item state
+
=item zip
+
=item country
=item pkg - line item description
-=item setup - line item setup fee (only or both of B<setup> and B<recur> will be defined)
-=item recur - line item recurring fee (only or both of B<setup> and B<recur> will be defined)
+
+=item setup - line item setup fee (one or both of B<setup> and B<recur> will be defined)
+
+=item recur - line item recurring fee (one or both of B<setup> and B<recur> will be defined)
+
=item sdate - start date for recurring fee
+
=item edate - end date for recurring fee
=back
time2str("%x", $cust_bill_pkg->edate),
);
- } else { #pkgnum Tax
+ } else { #pkgnum tax
next unless $cust_bill_pkg->setup != 0;
+ my $itemdesc = defined $cust_bill_pkg->dbdef_table->column('itemdesc')
+ ? ( $cust_bill_pkg->itemdesc || 'Tax' )
+ : 'Tax';
($pkg, $setup, $recur, $sdate, $edate) =
- ( 'Tax', sprintf("%10.2f",$cust_bill_pkg->setup), '', '', '' );
+ ( $itemdesc, sprintf("%10.2f",$cust_bill_pkg->setup), '', '', '' );
}
$csv->combine(
=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('CHECK', @_);
+}
+
+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 'CHECK' ) {
$payname = $cust_main->payname;
$payname =~ /^\s*([\w \,\.\-\']*)?\s+([\w\,\.\-\']+)\s*$/
or do {
my @invoicing_list = grep { $_ ne 'POST' } $cust_main->invoicing_list;
if ( $conf->exists('emailinvoiceauto')
|| ( $conf->exists('emailinvoiceonly') && ! @invoicing_list ) ) {
- push @invoicing_list, $cust_main->default_invoicing_list;
+ push @invoicing_list, $cust_main->all_emails;
}
my $email = $invoicing_list[0];
$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 'CHECK' ) {
+ 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,
'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,
if ( $transaction->is_success() && $action2 ) {
my $auth = $transaction->authorization;
- my $ordernum = $transaction->order_number;
+ my $ordernum = $transaction->can('order_number')
+ ? $transaction->order_number
+ : '';
#warn "********* $auth ***********\n";
#warn "********* $ordernum ***********\n";
new Business::OnlinePayment( $bop_processor, @bop_options );
my %capture = (
- type => 'CC',
+ %content,
+ type => $method,
action => $action2,
login => $bop_login,
password => $bop_password,
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
if ( $transaction->is_success() ) {
+ my %method2payby = (
+ 'CC' => 'CARD',
+ 'CHECK' => '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;
"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,
}
-=item realtime_card_cybercash
-
-Attempts to pay this invoice with the CyberCash CashRegister realtime gateway.
-
-=cut
-
-sub realtime_card_cybercash {
- my $self = shift;
- my $cust_main = $self->cust_main;
- my $amount = $self->owed;
-
- return "CyberCash CashRegister real-time card processing not enabled!"
- unless $processor eq 'cybercash3.2';
-
- 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 $paybatch = $self->invnum.
- '-' . time2str("%y%m%d%H%M%S", time);
-
- my $payname = $cust_main->payname ||
- $cust_main->getfield('first').' '.$cust_main->getfield('last');
-
- my $country = $cust_main->country eq 'US' ? 'USA' : $cust_main->country;
-
- my @full_xaction = ( $xaction,
- 'Order-ID' => $paybatch,
- 'Amount' => "usd $amount",
- 'Card-Number' => $cust_main->getfield('payinfo'),
- 'Card-Name' => $payname,
- 'Card-Address' => $address,
- 'Card-City' => $cust_main->getfield('city'),
- 'Card-State' => $cust_main->getfield('state'),
- 'Card-Zip' => $cust_main->getfield('zip'),
- 'Card-Country' => $country,
- 'Card-Exp' => $exp,
- );
-
- my %result;
- %result = &CCMckDirectLib3_2::SendCC2_1Server(@full_xaction);
-
- if ( $result{'MStatus'} eq 'success' ) { #cybercash smps v.2 or 3
- my $cust_pay = new FS::cust_pay ( {
- 'invnum' => $self->invnum,
- 'paid' => $amount,
- '_date' => '',
- 'payby' => 'CARD',
- 'payinfo' => $cust_main->payinfo,
- 'paybatch' => "$processor:$paybatch",
- } );
- my $error = $cust_pay->insert;
- if ( $error ) {
- # gah, even with transactions.
- my $e = 'WARNING: Card debited but database not updated - '.
- 'error applying payment, invnum #' . $self->invnum.
- " (CyberCash Order-ID $paybatch): $error";
- warn $e;
- return $e;
- } else {
- return '';
- }
-# } elsif ( $result{'Mstatus'} ne 'failure-bad-money'
-# || $options{'report_badcard'}
-# ) {
- } else {
- return 'Cybercash error, invnum #' .
- $self->invnum. ':'. $result{'MErrMsg'};
- }
-
-}
-
=item batch_card
Adds a payment for this invoice to the pending credit card batch (see
# 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
}
#new charges
- foreach ( $self->cust_bill_pkg ) {
+ foreach ( ( grep { $_->pkgnum } $self->cust_bill_pkg ), #packages first
+ ( grep { ! $_->pkgnum } $self->cust_bill_pkg ), #then taxes
+ ) {
if ( $_->pkgnum ) {
map { [ " ". $_->[0]. ": ". $_->[1], '' ] } $cust_pkg->labels;
}
- } else { #pkgnum Tax
- push @buf,["Tax", $money_char. sprintf("%10.2f",$_->setup) ]
+ } else { #pkgnum tax
+ my $itemdesc = defined $_->dbdef_table->column('itemdesc')
+ ? ( $_->itemdesc || 'Tax' )
+ : 'Tax';
+ push @buf,[$itemdesc, $money_char. sprintf("%10.2f",$_->setup) ]
if $_->setup != 0;
}
}
=head1 VERSION
-$Id: cust_bill.pm,v 1.41 2002-09-05 16:51:49 ivan Exp $
+$Id: cust_bill.pm,v 1.50 2002-10-15 09:54:24 ivan Exp $
=head1 BUGS