RT# 81961 Repair broken links in POD documentation
[freeside.git] / FS / bin / freeside-paymentech-download
1 #!/usr/bin/perl
2
3 use strict;
4 use Getopt::Std;
5 use Date::Format qw(time2str);
6 use File::Temp qw(tempdir); #0.19 for ->newdir() interface, not in 5.10.0
7 use Net::SFTP::Foreign;
8 use Expect;
9 use FS::UID qw(adminsuidsetup datasrc);
10 use FS::Record qw(qsearch qsearchs);
11 use FS::pay_batch;
12 use FS::cust_pay_batch;
13 use FS::Conf;
14 use FS::Log;
15
16 use vars qw( $opt_t $opt_v $opt_a );
17 getopts('vta:');
18
19 #$Net::SFTP::Foreign::debug = -1;
20
21 sub log_and_die {
22   my $message = shift;
23   my $log = FS::Log->new('freeside-paymentech-download');
24   $log->error($message);
25   die $message; 
26 }
27
28 sub usage { "
29   Usage:
30       freeside-paymentech-download [ -v ] [ -t ] [ -a archivedir ] user\n
31 " }
32
33 my $user = shift or die &usage;
34 adminsuidsetup $user;
35
36 if ( $opt_a ) {
37   log_and_die("no such directory: $opt_a\n")
38     unless -d $opt_a;
39   log_and_die("archive directory $opt_a is not writable by the freeside user\n")
40     unless -w $opt_a;
41 }
42
43 my $unzip_check = `which unzip` or log_and_die("can't find unzip executable\n");
44
45 #my $tmpdir = File::Temp->newdir();
46 my $tmpdir = tempdir( CLEANUP => 1 ); #DIR=>somewhere?
47
48 my $conf = new FS::Conf;
49 my @batchconf = $conf->config('batchconfig-paymentech');
50 # BIN, terminalID, merchantID, username, password
51 my $username = $batchconf[3] or log_and_die("no Paymentech batch username configured\n");
52 my $password = $batchconf[4] or log_and_die("no Paymentech batch password configured\n");
53
54 my $host = ($opt_t ? 'orbitalbatchvar.paymentech.net'
55                    : 'orbitalbatch.paymentech.net');
56 print STDERR "Connecting to $username\@$host...\n" if $opt_v;
57
58 my $sftp;
59 my $ssh_retry      = 25;   # number of times to try connection, needs to be >= 1
60 my $ssh_retry_wait = 60*5; # seconds to wait between tries
61 while ($ssh_retry > 0) {
62   $sftp = Net::SFTP::Foreign->new( host => $host,
63                                    user => $username,
64                                    password => $password,
65                                    timeout => 300,
66                                  );
67   last unless $sftp->error;
68   $ssh_retry -= 1;
69   sleep($ssh_retry_wait) if $ssh_retry > 0;
70 }
71
72 log_and_die("failed to connect to '$username\@$host'\n(".$sftp->error.")\n") if $sftp->error;
73
74 my @files = map { $_->{filename} } @{ $sftp->ls('.', wanted => qr/_resp\.zip$/) };
75 log_and_die("no response files found\n") if !@files;
76
77 BATCH: foreach my $filename (@files) {
78
79   #get file
80   $filename =~ s/_resp\.zip$//;
81   print STDERR "Retrieving $filename\n" if $opt_v;
82   $sftp->get("$filename\_resp.zip", "$tmpdir/${filename}_resp.zip");
83   if($sftp->error) {
84     warn "failed to download $filename\n";
85     next BATCH;
86   }
87
88   #unzip file
89   system('unzip', '-P', $password, '-q',
90            "$tmpdir/${filename}_resp.zip", '-d', $tmpdir);
91   if(! -f "$tmpdir/${filename}_resp.xml") {
92     warn "failed to extract ${filename}_resp.xml from ${filename}_resp.zip\n";
93     next BATCH;
94   }
95
96   #copy to archive dir
97   if ( $opt_a ) {
98     print STDERR "Copying $tmpdir/${filename}_resp.xml to archive dir $opt_a\n"
99       if $opt_v;
100     system 'cp', "$tmpdir/${filename}_resp.xml", $opt_a;
101     warn "failed to copy $tmpdir/${filename}_resp.xml to $opt_a: $@" if $@;
102   }
103
104   #get batchnum & retrieve pending batch
105   open my $fh, "<$tmpdir/${filename}_resp.xml";
106   my ($batchnum) = split ('-', $filename); 
107   $batchnum = sprintf("%d", $batchnum); # remove leading zeroes
108   my $batch = qsearchs('pay_batch', { batchnum => $batchnum });
109   if(! $batch) {
110     warn "batch '$batchnum' not found\n";
111     next BATCH;
112   }
113
114   #and import results
115   print STDERR "Importing batch #$batchnum\n" if $opt_v;
116   my $error = $batch->import_results( filehandle => $fh,
117                                       format     => 'paymentech' );
118   warn "error: $error\n" if $error;
119
120 }
121
122 print STDERR "Finished!\n" if $opt_v;
123
124 =head1 NAME
125
126 freeside-paymentech-download - Retrieve payment batch responses from Chase Paymentech.
127
128 =head1 SYNOPSIS
129
130   paymentech-download [ -v ] [ -t ] [ -a archivedir ] user
131
132 =head1 DESCRIPTION
133
134 Command line tool to download payment batch responses from the Chase Paymentech
135 gateway.  These are XML files packaged in ZIP files.  This script downloads them 
136 by SFTP, extracts the contents, and passes them to L<FS::pay_batch/import_results>.
137
138 -v: Be verbose.
139
140 -t: Use the test server.
141
142 -a directory: Archive response files in the provided directory.
143
144 user: freeside username
145
146 =head1 BUGS
147
148 =head1 SEE ALSO
149
150 L<FS::pay_batch>
151
152 =cut
153
154 1;
155