7b307ffa6b74002827c3ff8d54671d86e1f63822
[Business-OnlinePayment-LinkPoint.git] / LinkPoint.pm
1 package Business::OnlinePayment::LinkPoint;
2
3 # $Id: LinkPoint.pm,v 1.3 2002-02-26 08:53:52 ivan Exp $
4
5 use strict;
6 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
7 use Carp qw(croak);
8 use AutoLoader;
9 use Business::OnlinePayment;
10
11 use lperl; #lperl.pm from Linkpoint.
12
13 require Exporter;
14
15 @ISA = qw(Exporter AutoLoader Business::OnlinePayment);
16 @EXPORT = qw();
17 @EXPORT_OK = qw();
18 $VERSION = '0.02';
19
20 sub set_defaults {
21     my $self = shift;
22
23     #$self->server('staging.linkpt.net');
24     $self->server('secure.linkpt.net');
25     $self->port('1139');
26
27 }
28
29 sub map_fields {
30     my($self) = @_;
31
32     my %content = $self->content();
33
34     #ACTION MAP
35     my %actions = ('normal authorization' => 'ApproveSale',
36                    'authorization only'   => 'CapturePayment',
37                    'credit'               => 'ReturnOrder',
38                    'post authorization'   => 'BillOrders',
39                   );
40     $content{'action'} = $actions{lc($content{'action'})} || $content{'action'};
41
42     # stuff it back into %content
43     $self->content(%content);
44 }
45
46 sub build_subs {
47     my $self = shift;
48     foreach(@_) {
49         no warnings;
50         eval "sub $_ { my \$self = shift; if(\@_) { \$self->{$_} = shift; } return \$self->{$_}; }";
51     }
52 }
53
54 sub remap_fields {
55     my($self,%map) = @_;
56
57     my %content = $self->content();
58     foreach(keys %map) {
59         $content{$map{$_}} = $content{$_};
60     }
61     $self->content(%content);
62 }
63
64 sub revmap_fields {
65     my($self, %map) = @_;
66     my %content = $self->content();
67     foreach(keys %map) {
68 #    warn "$_ = ". ( ref($map{$_})
69 #                         ? ${ $map{$_} }
70 #                         : $content{$map{$_}} ). "\n";
71         $content{$_} = ref($map{$_})
72                          ? ${ $map{$_} }
73                          : $content{$map{$_}};
74     }
75     $self->content(%content);
76 }
77
78 sub get_fields {
79     my($self,@fields) = @_;
80
81     my %content = $self->content();
82     my %new = ();
83     foreach( grep defined $content{$_}, @fields) { $new{$_} = $content{$_}; }
84     return %new;
85 }
86
87 sub submit {
88     my($self) = @_;
89
90
91     $self->map_fields();
92
93     my %content = $self->content;
94
95     my($month, $year);
96     unless ( $content{action} eq 'BillOrders' ) {
97
98         if (  $self->transaction_type() =~
99                 /^(cc|visa|mastercard|american express|discover)$/i
100            ) {
101         } else {
102             Carp::croak("LinkPoint can't handle transaction type: ".
103                         $self->transaction_type());
104         }
105
106       $content{'expiration'} =~ /^(\d+)\D+\d*(\d{2})$/
107         or croak "unparsable expiration $content{expiration}";
108
109       ( $month, $year ) = ( $1, $2 );
110       $month = '0'. $month if $month =~ /^\d$/;
111       $year += 2000 if $year < 2000; #not y4k safe, oh shit
112     }
113
114     $content{'address'} =~ /^(\S+)\s/;
115     my $addrnum = $1;
116
117     $self->server('staging.linkpt.net') if $self->test_transaction;
118
119     $self->revmap_fields(
120       hostname     => \( $self->server ),
121       port         => \( $self->port ),
122       storename    => \( $self->storename ),
123       keyfile      => \( $self->keyfile ),
124       addrnum      => \$addrnum,
125
126       cardNumber   => 'card_number',
127       cardExpMonth => \$month,
128       cardExpYear  => \$year,
129     );
130
131     my $lperl = new LPERL
132       $self->lbin,
133       'FILE',
134       $self->can('tmp')
135         ? $self->tmp
136         : '/tmp';
137     my $action = $content{action};
138
139     $self->required_fields(qw/
140       hostname port storename keyfile amount cardNumber cardExpMonth cardExpYear
141     /);
142
143     my %post_data = $self->get_fields(qw/
144       hostname port storename keyfile
145       result
146       amount cardNumber cardExpMonth cardExpYear
147       name email phone address city state zip country
148     /);
149
150     #print "$_ => $post_data{$_}\n" foreach keys %post_data;
151
152     my %response = $lperl->$action(\%post_data);
153
154     if ( $response{'statusCode'} == 0 ) {
155       $self->is_success(0);
156       $self->result_code('');
157       $self->error_message($response{'statusMessage'});
158     } else {
159       $self->is_success(1);
160       $self->result_code($response{'AVCCode'});
161       $self->authorization($response{'trackingID'});
162 #      $self->order_number($response{'neworderID'});
163     }
164
165 }
166
167 1;
168 __END__
169
170 =head1 NAME
171
172 Business::OnlinePayment::LinkPoint - LinkPoint backend for Business::OnlinePayment
173
174 =head1 SYNOPSIS
175
176   use Business::OnlinePayment;
177
178   my $tx = new Business::OnlinePayment( 'LinkPoint',
179     'storename' => 'your_store_number',
180     'keyfile'   => '/path/to/keyfile.pem',
181     'lbin'      => '/path/to/binary/lbin',
182     'tmp'       => '/secure/tmp',          # a secure tmp directory
183   );
184
185   $tx->content(
186       type           => 'VISA',
187       action         => 'Normal Authorization',
188       description    => 'Business::OnlinePayment test',
189       amount         => '49.95',
190       invoice_number => '100100',
191       customer_id    => 'jsk',
192       name           => 'Jason Kohles',
193       address        => '123 Anystreet',
194       city           => 'Anywhere',
195       state          => 'UT',
196       zip            => '84058',
197       email          => 'ivan-linkpoint@420.am',
198       card_number    => '4007000000027',
199       expiration     => '09/99',
200   );
201   $tx->submit();
202
203   if($tx->is_success()) {
204       print "Card processed successfully: ".$tx->authorization."\n";
205   } else {
206       print "Card was rejected: ".$tx->error_message."\n";
207   }
208
209 =head1 SUPPORTED TRANSACTION TYPES
210
211 =head2 Visa, MasterCard, American Express, JCB, Discover/Novus, Carte blanche/Diners Club
212
213 =head1 DESCRIPTION
214
215 For detailed information see L<Business::OnlinePayment>.
216
217 =head1 COMPATIBILITY
218
219 This module implements an interface to the LinkPoint Perl Wrapper
220 http://www.linkpoint.com/product_solutions/internet/lperl/lperl_main.html
221
222 =head1 BUGS
223
224 =head1 AUTHOR
225
226 Ivan Kohler <ivan-linkpoint@420.am>
227
228 Based on Busienss::OnlinePayment::AuthorizeNet written by Jason Kohles.
229
230 =head1 SEE ALSO
231
232 perl(1). L<Business::OnlinePayment>.
233
234 =cut
235