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