1 package FS::pay_batch::paymentech;
4 use vars qw(@ISA %import_info %export_info $name);
5 use FS::Record 'qsearchs';
7 use Date::Format 'time2str';
8 use Date::Parse 'str2time';
13 my ($bin, $merchantID, $terminalID, $username, $password, $with_recurringInd);
20 xmlrow => [ qw(transResponse newOrderResp) ],
43 # find a gateway configuration that has the same merchantID
44 # as the batch config, if there is one. If not, leave
45 # gateway out entirely.
46 my $merchant = (FS::Conf->new->config('batchconfig-paymentech'))[2];
48 'table' => 'payment_gateway',
49 'addl_from' => ' JOIN payment_gateway_option USING (gatewaynum) ',
50 'hashref' => { disabled => '',
51 optionname => 'merchant_id',
52 optionvalue => $merchant,
56 my ($hash, $oldhash) = @_;
57 $hash->{'gatewaynum'} = $gateway->gatewaynum if $gateway;
58 $hash->{'processor'} = 'PaymenTech';
59 my ($mon, $day, $year, $hour, $min, $sec) =
60 $hash->{'_date'} =~ /^(..)(..)(....)(..)(..)(..)$/;
61 $hash->{'_date'} = timelocal($sec, $min, $hour, $day, $mon-1, $year);
62 $hash->{'paid'} = $oldhash->{'amount'};
64 my $gateway_label = $hash->{'processor'};
65 $gateway_label = $hash->{'gatewaynum'} . '-' . $gateway_label
66 if $hash->{'gatewaynum'};
67 $hash->{'paybatch'} = join(':',
70 $hash->{'order_number'},
72 if ( $hash->{'procStatus'} == 0 ) {
73 $hash->{'error_message'} = $hash->{'respCodeMessage'};
75 $hash->{'error_message'} = $hash->{'procStatusMessage'};
78 'approved' => sub { my $hash = shift;
79 $hash->{'approvalStatus'}
81 'declined' => sub { my $hash = shift;
82 ! $hash->{'approvalStatus'}
87 'personal checking' => 'C',
88 'personal savings' => 'S',
89 'business checking' => 'X',
90 'business savings' => 'X',
93 my %paymentech_countries = map { $_ => 1 } qw( US CA GB UK );
97 # Load this at run time
98 eval "use XML::Writer";
101 ($bin, $terminalID, $merchantID, $username, $password, $with_recurringInd) =
102 $conf->config('batchconfig-paymentech');
104 # Here we do all the work in the header function.
106 my $pay_batch = shift;
107 my @cust_pay_batch = @{(shift)};
110 my $xml = new XML::Writer(OUTPUT => \$output, DATA_MODE => 1, DATA_INDENT => 2);
111 $xml->startTag('transRequest', RequestCount => scalar(@cust_pay_batch) + 1);
112 $xml->startTag('batchFileID');
113 $xml->dataElement(userID => $username);
114 $xml->dataElement(fileDateTime => time2str('%Y%m%d%H%M%S', time));
115 $xml->dataElement(fileID => 'FILEID');
116 $xml->endTag('batchFileID');
118 foreach (@cust_pay_batch) {
119 $xml->startTag('newOrder', BatchRequestNo => $count++);
120 my $status = $_->cust_main->status;
121 tie my %order, 'Tie::IxHash', (
122 industryType => 'EC',
125 merchantID => $merchantID,
126 terminalID => $terminalID,
127 ($_->payby eq 'CARD') ? (
128 ccAccountNum => $_->payinfo,
129 ccExp => $_->expmmyy,
131 ecpCheckRT => ($_->payinfo =~ /@(\d+)/),
132 ecpCheckDDA => ($_->payinfo =~ /(\d+)@/),
133 ecpBankAcctType => $paytype{lc($_->cust_main->paytype)},
134 ecpDelvMethod => 'A',
136 avsZip => substr($_->zip, 0, 10),
137 avsAddress1 => substr($_->address1, 0, 30),
138 avsAddress2 => substr($_->address2, 0, 30),
139 avsCity => substr($_->city, 0, 20),
140 avsState => substr($_->state, 0, 2),
141 avsName => substr($_->first. ' '. $_->last, 0, 30),
142 ( $paymentech_countries{ $_->country }
143 ? ( avsCountryCode => $_->country )
146 orderID => $_->paybatchnum,
147 amount => $_->amount * 100,
149 # only do this if recurringInd is enabled in config,
150 # and the customer has at least one non-canceled recurring package
151 if ( $with_recurringInd and $status =~ /^active|suspended|ordered$/ ) {
152 # then send RF if this is the first payment on this payinfo,
154 $order{'recurringInd'} = $_->payinfo_used ? 'RS' : 'RF';
156 foreach my $key (keys %order) {
157 $xml->dataElement($key, $order{$key})
159 $xml->endTag('newOrder');
161 $xml->startTag('endOfDay', BatchRequestNo => $count);
162 $xml->dataElement(bin => $bin);
163 $xml->dataElement(merchantID => $merchantID);
164 $xml->dataElement(terminalID => $terminalID);
165 $xml->endTag('endOfDay');
166 $xml->endTag('transRequest');