clean up parameters
[Business-OnlinePayment-Jety.git] / lib / Business / OnlinePayment / Jety.pm
1 package Business::OnlinePayment::Jety;
2
3 use strict;
4 use Carp;
5 use Business::OnlinePayment 3;
6 use Business::OnlinePayment::HTTPS;
7 use vars qw($VERSION @ISA $me $DEBUG);
8
9 use Date::Format;
10 use Tie::IxHash;
11
12 @ISA = qw(Business::OnlinePayment::HTTPS);
13 $VERSION = '0.01';
14 $me = 'Business::OnlinePayment::Jety';
15
16 $DEBUG = 0;
17
18 my @fields = (qw(
19   username
20   password
21   function
22   firstname
23   lastname
24   address1
25   address2
26   city
27   state
28   zip
29   email
30   phone
31   programdesc
32   ref
33   bankname
34   bankcity
35   bankstate
36   accountaba
37   accountdda
38   amount
39 ));
40
41 my %map = (
42   login      => 'username',
43   first_name => 'firstname',
44   last_name  => 'lastname',
45   address    => 'address1',
46   bank_name  => 'bankname',
47   bank_city  => 'bankcity',
48   bank_state => 'bankstate',
49   account_number => 'accountdda',
50   routing_code => 'accountaba',
51 );
52   
53
54 sub set_defaults {
55   my $self = shift;
56   $self->server('api.cardservicesportal.com');
57   $self->port(443);
58   $self->path('/servlet/drafts.echeck');
59   return;
60 }
61
62 sub map_fields {
63   my $self = shift;
64   my $content = $self->{_content};
65
66   $self->remap_fields(%map);
67
68   die "Jety API only supports ECHECK payments.\n" 
69     if(lc($content->{type}) ne 'echeck');
70   die "Jety interface only supports Normal Authorization.\n"
71     if(lc($content->{action}) ne 'normal authorization');
72
73   $content->{'function'} = 'echeck';
74   $content->{'programdesc'} = '415-462-1624 Business::OnlinePayment::Jety';
75   $content->{'ref'} = time2str('%Y%m%d',time).'-'.int(rand(1000000));
76
77   $content->{'bankname'} ||= 'unknown';
78   $content->{'bankcity'} ||= 'unknown';
79   $content->{'bankstate'} ||= 'XX';
80
81   return;
82 }
83
84 sub submit {
85   my $self = shift;
86   $Business::OnlinePayment::HTTPS::DEBUG = $DEBUG;
87   $DB::single = $DEBUG; 
88
89   # strip existent but empty fields so that required_fields works right
90   foreach(keys(%{$self->{_content}})) {
91     delete $self->{_content}->{$_} 
92       if (!defined($self->{_content}->{$_} ) or
93            $self->{_content}->{$_} eq '');
94   }
95
96   $self->required_fields(qw(
97     type
98     action
99     first_name
100     last_name
101     address
102     city
103     state
104     zip
105     email
106     phone
107     account_number
108     routing_code
109     amount
110     ) );
111   $self->map_fields;
112   tie my %request, 'Tie::IxHash', (
113     map { $_, $self->{_content}->{$_} } @fields
114     );
115
116   $DB::single = $DEBUG;
117   if($self->test_transaction()) {
118     print "https://".$self->server.$self->path."\n";
119     print "$_\t".$request{$_}."\n" foreach keys(%request);
120     $self->error_message('test mode not supported');
121     $self->is_success(0);
122     return;
123   }
124   my ($reply, $response, %reply_headers) = $self->https_post(\%request);
125   
126   if(not $response =~ /^200/) {
127     croak "HTTPS error: '$response'";
128   }
129
130   # string looks like this:
131   # P1=1234&P2=General Status&P3=Specific Status
132   # P3 is not always there, though.
133   if($reply =~ /^P1=(\d+)&P2=([\w ]*)(&P3=(\S+))?/) {
134     if($1 == 0) {
135       $self->is_success(1);
136       $self->authorization($4);
137     }
138     else {
139       $self->is_success(0);
140       $self->error_message($2.($4 ? "($4)" : ''));
141     }
142   }
143   else {
144     croak "Malformed server response: '$reply'";
145   }
146
147   return;
148 }
149
150 1;
151 __END__
152
153 =head1 NAME
154
155 Business::OnlinePayment::Jety - Jety Payments ACH backend for Business::OnlinePayment
156
157 =head1 SYNOPSIS
158
159   use Business::OnlinePayment;
160
161   ####
162   # Electronic check authorization.  We only support 
163   # 'Normal Authorization'.
164   ####
165
166   my $tx = new Business::OnlinePayment("Jety");
167   $tx->content(
168       type           => 'ECHECK',
169       login          => 'testdrive',
170       password       => 'testpass',
171       action         => 'Normal Authorization',
172       description    => 'Business::OnlinePayment test',
173       amount         => '49.95',
174       invoice_number => '100100',
175       first_name     => 'Jason',
176       last_name      => 'Kohles',
177       address        => '123 Anystreet',
178       city           => 'Anywhere',
179       state          => 'UT',
180       zip            => '84058',
181       account_type   => 'personal checking',
182       account_number => '1000468551234',
183       routing_code   => '707010024',
184       check_number   => '1001', # optional
185   );
186   $tx->submit();
187
188   if($tx->is_success()) {
189       print "Check processed successfully: ".$tx->authorization."\n";
190   } else {
191       print "Check was rejected: ".$tx->error_message."\n";
192   }
193
194 =head1 SUPPORTED TRANSACTION TYPES
195
196 =head2 ECHECK
197
198 Content required: type, login, password, action, amount, first_name, last_name, account_number, routing_code.
199
200 =head1 DESCRIPTION
201
202 For detailed information see L<Business::OnlinePayment>.
203
204 =head1 METHODS AND FUNCTIONS
205
206 See L<Business::OnlinePayment> for the complete list. The following methods either override the methods in L<Business::OnlinePayment> or provide additional functions.  
207
208 =head2 result_code
209
210 Returns the four-digit result code.
211
212 =head2 error_message
213
214 Returns a useful error message.
215
216 =head1 Handling of content(%content) data:
217
218 =head2 action
219
220 The following actions are valid:
221
222   normal authorization
223
224 =head1 AUTHOR
225
226 Mark Wells <mark@freeside.biz>
227
228 =head1 SEE ALSO
229
230 perl(1). L<Business::OnlinePayment>.
231
232 =cut
233