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