1 package Business::OnlinePayment::Jety;
5 use Business::OnlinePayment 3;
6 use Business::OnlinePayment::HTTPS;
7 use vars qw($VERSION @ISA $me $DEBUG);
12 @ISA = qw(Business::OnlinePayment::HTTPS);
14 $me = 'Business::OnlinePayment::Jety';
19 'normal authorization' => 'echeck',
24 # 'function' will always be prepended
25 'normal authorization' => [ # note array-ness
26 'username' => 'login',
27 'password' => 'password',
28 'firstname' => 'first_name',
29 'lastname' => 'last_name',
30 'address1' => 'address',
31 'address2' => 'address2',
37 'programdesc' => 'description',
38 'ref' => sub { my %c = @_;
40 substr( time2str('%Y%m%d%H%M%S',time). int(rand(10000)), -15 )
42 'bankname' => 'bank_name',
43 'bankcity' => 'bank_city',
44 'bankstate' => 'bank_state',
45 'accountaba' => 'routing_code',
46 'accountdda' => 'account_number',
47 'amount' => sub { my %c = @_; sprintf("%.02f",$c{'amount'}) },
50 'username' => 'login',
51 'password' => 'password',
52 'ref' => 'order_number',
53 'accountdda' => 'account_number',
54 'amount' => sub { my %c = @_; sprintf("%.02f",$c{'amount'}) },
58 my %defaults = ( # using the B:OP names
59 'phone' => '111-111-1111',
60 'bank_name' => 'unknown',
61 'bank_city' => 'unknown',
66 'normal authorization' => [ qw(
96 $self->server('api.cardservicesportal.com');
98 $self->path('/servlet/drafts.echeck');
104 $Business::OnlinePayment::HTTPS::DEBUG = $DEBUG;
105 $DB::single = $DEBUG;
107 # strip existent but empty fields so that required_fields works right
108 foreach(keys(%{$self->{_content}})) {
109 delete $self->{_content}->{$_}
110 if (!defined($self->{_content}->{$_} ) or
111 $self->{_content}->{$_} eq '');
114 my %content = $self->content();
115 my $action = lc($content{'action'});
117 croak "Jety only supports ECHECK payments.\n"
118 if( lc($content{'type'}) ne 'echeck' );
119 croak "Unsupported transaction type: '$action'\n"
120 if( !exists($trans_type{$action}) );
122 $self->required_fields(@{ $required{$action} });
124 my @fields = @{ $map{$action} } ;
125 tie my %request, 'Tie::IxHash', ( 'function' => $trans_type{$action} );
127 my ($key, $value) = (shift (@fields), shift (@fields));
128 if( ref($value) eq 'CODE' ) {
129 $request{$key} = $value->(%content);
131 elsif (defined($content{$value}) and $content{$value} ne '') {
132 $request{$key} = $content{$value};
134 elsif (exists($defaults{$value})) {
135 $request{$key} = $defaults{$value};
139 $DB::single = $DEBUG;
140 if($self->test_transaction()) {
141 print "https://".$self->server.$self->path."\n";
142 print "$_\t".$request{$_}."\n" foreach keys(%request);
143 $self->error_message('test mode not supported');
144 $self->is_success(0);
147 my ($reply, $response, %reply_headers) = $self->https_post(\%request);
149 if(not $response =~ /^200/) {
150 croak "HTTPS error: '$response'";
153 # string looks like this:
154 # P1=1234&P2=General Status&P3=Specific Status
155 # P3 is not always there, though.
156 if($reply =~ /^P1=(\d+)&P2=([\w ]*)(&P3=(\S+))?/) {
158 $self->is_success(1);
159 $self->authorization($4);
162 $self->is_success(0);
163 $self->error_message($2.($4 ? "($4)" : ''));
167 croak "Malformed server response: '$reply'";
174 # Required parameters:
175 # ftp_user, ftp_pass, ftp_host, ftp_path
178 eval('use Date::Parse q!str2time!; use Net::FTP; use File::Temp q!tempdir!');
182 # $self->required_fields, for processor options
184 my ($user, $pass, $host, $path) = map {
185 if($self->can($_) and $self->$_) {
188 push @missing, $_; '';
190 } qw(ftp_user ftp_pass ftp_host);
191 die "missing gateway option(s): ".join(', ',@missing)."\n" if @missing;
192 my $ftp_path = $self->ftp_path if $self->can('ftp_path');
194 my $start = $self->{_content}->{start};
195 $start &&= str2time($start);
196 $start ||= time - 86400;
197 $start = time2str('%Y%m%d',$start);
199 my $end = $self->{_content}->{end};
200 $end &&= str2time($end);
202 $end = time2str('%Y%m%d',$end);
204 my $ftp = Net::FTP->new($host)
205 or die "FTP connection to '$host' failed.\n";
206 $ftp->login($user, $pass) or die "FTP login failed: ".$ftp->message."\n";
207 $ftp->cwd($path) or die "can't chdir to $path\n" if $path;
209 my $tmp = tempdir(CLEANUP => 1);
211 foreach my $filename ($ftp->ls) {
212 if($filename =~ /^\w+_RET(\d{8}).csv$/
215 $ftp->get($filename, "$tmp/$1") or die "Failed to download $filename: ".$ftp->message."\n";
222 foreach my $filename (@files) {
223 open IN, '<', "$tmp/$filename";
224 my @fields = split ',',<IN>; #fetch header row
225 my ($i) = grep { $fields[$_] eq 'AccountToID' } 0..(scalar @fields - 1);
228 my @fields = split ',', $_;
229 push @tids, $fields[$i];
241 Business::OnlinePayment::Jety - Jety Payments ACH backend for Business::OnlinePayment
245 use Business::OnlinePayment;
248 # Electronic check authorization. We only support
249 # 'Normal Authorization'.
252 my $tx = new Business::OnlinePayment("Jety");
255 login => 'testdrive',
256 password => 'testpass',
257 action => 'Normal Authorization',
258 description => '111-111-1111 www.example.com',
260 invoice_number => '100100',
261 first_name => 'Jason',
262 last_name => 'Kohles',
263 address => '123 Anystreet',
267 account_type => 'personal checking',
268 account_number => '1000468551234',
269 routing_code => '707010024',
270 check_number => '1001', # optional
274 if($tx->is_success()) {
275 print "Check processed successfully: ".$tx->authorization."\n";
277 print "Check was rejected: ".$tx->error_message."\n";
280 =head1 SUPPORTED TRANSACTION TYPES
284 Content required: type, login, password, action, amount, first_name, last_name, account_number, routing_code, description.
286 description should be set in the form "111-111-1111 www.example.com"
290 For detailed information see L<Business::OnlinePayment>.
292 =head1 METHODS AND FUNCTIONS
294 See L<Business::OnlinePayment> for the complete list. The following methods either override the methods in L<Business::OnlinePayment> or provide additional functions.
298 Returns the four-digit result code.
302 Returns a useful error message.
304 =head1 Handling of content(%content) data:
308 The following actions are valid:
314 Mark Wells <mark@freeside.biz>
318 perl(1). L<Business::OnlinePayment>.