Don't default programdesc to our real phone number.
[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.03';
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   'description'    => 'programdesc',
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->{'ref'} = time2str('%Y%m%d',time).'-'.int(rand(1000000));
75
76   $content->{'phone'} ||= '111-111-1111';
77
78   $content->{'bankname'} ||= 'unknown';
79   $content->{'bankcity'} ||= 'unknown';
80   $content->{'bankstate'} ||= 'XX';
81
82   return;
83 }
84
85 sub submit {
86   my $self = shift;
87   $Business::OnlinePayment::HTTPS::DEBUG = $DEBUG;
88   $DB::single = $DEBUG; 
89
90   # strip existent but empty fields so that required_fields works right
91   foreach(keys(%{$self->{_content}})) {
92     delete $self->{_content}->{$_} 
93       if (!defined($self->{_content}->{$_} ) or
94            $self->{_content}->{$_} eq '');
95   }
96
97   $self->required_fields(qw(
98     type
99     action
100     first_name
101     last_name
102     address
103     city
104     state
105     zip
106     email
107     phone
108     account_number
109     routing_code
110     amount
111     ) );
112   $self->map_fields;
113   tie my %request, 'Tie::IxHash', (
114     map { $_, $self->{_content}->{$_} } @fields
115     );
116
117   $DB::single = $DEBUG;
118   if($self->test_transaction()) {
119     print "https://".$self->server.$self->path."\n";
120     print "$_\t".$request{$_}."\n" foreach keys(%request);
121     $self->error_message('test mode not supported');
122     $self->is_success(0);
123     return;
124   }
125   my ($reply, $response, %reply_headers) = $self->https_post(\%request);
126   
127   if(not $response =~ /^200/) {
128     croak "HTTPS error: '$response'";
129   }
130
131   # string looks like this:
132   # P1=1234&P2=General Status&P3=Specific Status
133   # P3 is not always there, though.
134   if($reply =~ /^P1=(\d+)&P2=([\w ]*)(&P3=(\S+))?/) {
135     if($1 == 0) {
136       $self->is_success(1);
137       $self->authorization($4);
138     }
139     else {
140       $self->is_success(0);
141       $self->error_message($2.($4 ? "($4)" : ''));
142     }
143   }
144   else {
145     croak "Malformed server response: '$reply'";
146   }
147
148   return;
149 }
150
151 1;
152 __END__
153
154 =head1 NAME
155
156 Business::OnlinePayment::Jety - Jety Payments ACH backend for Business::OnlinePayment
157
158 =head1 SYNOPSIS
159
160   use Business::OnlinePayment;
161
162   ####
163   # Electronic check authorization.  We only support 
164   # 'Normal Authorization'.
165   ####
166
167   my $tx = new Business::OnlinePayment("Jety");
168   $tx->content(
169       type           => 'ECHECK',
170       login          => 'testdrive',
171       password       => 'testpass',
172       action         => 'Normal Authorization',
173       description    => 'Business::OnlinePayment test',
174       amount         => '49.95',
175       invoice_number => '100100',
176       first_name     => 'Jason',
177       last_name      => 'Kohles',
178       address        => '123 Anystreet',
179       city           => 'Anywhere',
180       state          => 'UT',
181       zip            => '84058',
182       account_type   => 'personal checking',
183       account_number => '1000468551234',
184       routing_code   => '707010024',
185       check_number   => '1001', # optional
186   );
187   $tx->submit();
188
189   if($tx->is_success()) {
190       print "Check processed successfully: ".$tx->authorization."\n";
191   } else {
192       print "Check was rejected: ".$tx->error_message."\n";
193   }
194
195 =head1 SUPPORTED TRANSACTION TYPES
196
197 =head2 ECHECK
198
199 Content required: type, login, password, action, amount, first_name, last_name, account_number, routing_code.
200
201 =head1 DESCRIPTION
202
203 For detailed information see L<Business::OnlinePayment>.
204
205 =head1 METHODS AND FUNCTIONS
206
207 See L<Business::OnlinePayment> for the complete list. The following methods either override the methods in L<Business::OnlinePayment> or provide additional functions.  
208
209 =head2 result_code
210
211 Returns the four-digit result code.
212
213 =head2 error_message
214
215 Returns a useful error message.
216
217 =head1 Handling of content(%content) data:
218
219 =head2 action
220
221 The following actions are valid:
222
223   normal authorization
224
225 =head1 AUTHOR
226
227 Mark Wells <mark@freeside.biz>
228
229 =head1 SEE ALSO
230
231 perl(1). L<Business::OnlinePayment>.
232
233 =cut
234