1 package Business::OnlinePayment::LinkPoint;
4 use vars qw($VERSION @ISA $DEBUG @EXPORT @EXPORT_OK);
6 use Business::OnlinePayment;
8 @ISA = qw(Business::OnlinePayment);
10 $VERSION = eval $VERSION; # modperlstyle: convert the string into a number
13 use lpperl; #3; #lpperl.pm from LinkPoint
14 $LPPERL::VERSION =~ /^(\d+\.\d+)/
15 or die "can't parse lpperl.pm version: $LPPERL::VERSION";
16 die "lpperl.pm minimum version 3 required\n" unless $1 >= 3;
21 #$self->server('staging.linkpt.net');
22 $self->server('secure.linkpt.net');
25 $self->build_subs(qw(order_number avs_code));
32 my %content = $self->content();
35 my %actions = ('normal authorization' => 'SALE',
36 'authorization only' => 'PREAUTH',
38 'post authorization' => 'POSTAUTH',
41 $content{'action'} = $actions{lc($content{'action'})} || $content{'action'};
44 my %account_types = ('personal checking' => 'pc',
45 'personal savings' => 'ps',
46 'business checking' => 'bc',
47 'business savings' => 'bs',
49 $content{'account_type'} = $account_types{lc($content{'account_type'})}
50 || $content{'account_type'};
52 # stuff it back into %content
53 $self->content(%content);
59 #no warnings; #not 5.005
61 eval "sub $_ { my \$self = shift; if(\@_) { \$self->{$_} = shift; } return \$self->{$_}; }";
68 my %content = $self->content();
70 $content{$map{$_}} = $content{$_};
72 $self->content(%content);
77 my %content = $self->content();
79 # warn "$_ = ". ( ref($map{$_})
81 # : $content{$map{$_}} ). "\n";
82 $content{$_} = ref($map{$_})
86 $self->content(%content);
90 my($self,@fields) = @_;
92 my %content = $self->content();
94 foreach( grep defined $content{$_}, @fields) { $new{$_} = $content{$_}; }
103 my %content = $self->content;
106 unless ( $content{action} eq 'POSTAUTH'
107 || ( $content{'action'} =~ /^(CREDIT|VOID)$/
108 && exists $content{'order_number'} )
109 || $self->transaction_type() =~ /^e?check$/i
112 if ( $self->transaction_type() =~
113 /^(cc|visa|mastercard|american express|discover)$/i
116 Carp::croak("LinkPoint can't handle transaction type: ".
117 $self->transaction_type());
120 $content{'expiration'} =~ /^(\d+)\D+\d*(\d{2})$/
121 or croak "unparsable expiration $content{expiration}";
123 ( $month, $year ) = ( $1, $2 );
124 $month = '0'. $month if $month =~ /^\d$/;
127 $content{'address'} =~ /^(\d+)\s/;
130 my $result = $content{'result'};
131 if ( $self->test_transaction) {
133 #$self->server('staging.linkpt.net');
138 #docs disagree with lpperl.pm here
139 $content{'voidcheck'} = 1
140 if ($self->transaction_type() =~ /^e?check$/i
141 && $content{'action'} =~ /^VOID$/);
143 #strip phone numbers of non-digits for ACH/echeck
144 #as per undocumented suggestion from LinkPoint
145 if ( $self->transaction_type =~ /^e?check$/i ) {
146 foreach my $field (qw( phone fax )) {
147 $content{$field} =~ s/\D//g;
151 $self->revmap_fields(
152 host => \( $self->server ),
153 port => \( $self->port ),
154 #storename => \( $self->storename ),
155 configfile => \( $self->storename ),
156 keyfile => \( $self->keyfile ),
158 chargetotal => 'amount',
160 addrnum => \$addrnum,
161 oid => 'order_number',
163 userid => 'customer_id',
164 ponumber => 'invoice_number',
165 comments => 'description',
166 #reference_number => 'reference_number',
168 cardnumber => 'card_number',
169 cardexpmonth => \$month,
170 cardexpyear => \$year,
172 bankname => 'bank_name',
173 bankstate => 'bank_state',
174 routing => 'routing_code',
175 account => 'account_number',
176 accounttype => 'account_type',
177 name => 'account_name',
179 dlstate => 'state_id_state',
182 my $lperl = new LPPERL;
184 my @required_fields = qw(host port configfile keyfile amount);
185 if ($self->transaction_type() =~ /^(cc|visa|mastercard|american express|discover)$/i) {
186 push @required_fields, qw(cardnumber cardexpmonth cardexpyear);
187 }elsif ($self->transaction_type() =~ /^e?check$/i) {
188 push @required_fields, qw(
189 dl dlstate routing account accounttype bankname bankstate name
192 $self->required_fields(@required_fields);
194 my %post_data = $self->get_fields(qw/
195 host port configfile keyfile
197 chargetotal cardnumber cardexpmonth cardexpyear
198 name company email phone fax addrnum city state zip country
200 dl dlstate routing account accounttype bankname bankstate name void
204 $post_data{'ordertype'} = $content{action};
206 if ( $content{'cvv2'} ) {
207 $post_data{cvmindicator} = 'provided';
208 $post_data{cvmvalue} = $content{'cvv2'};
212 warn "$_ => $post_data{$_}\n" foreach keys %post_data;
213 $post_data{debug} = 'true';
216 $post_data{'cargs'} = '-k -m 300 -s -S' if $self->test_transaction;
218 # avoid some uninitialized warnings in lpperl.pm
219 foreach (qw(webspace debug debugging)) { $post_data{$_} ||= '' }
224 # %response = $lperl->$action(\%post_data);
226 my %response = $lperl->curl_process(\%post_data);
229 warn "$_ => $response{$_}\n" for keys %response;
232 if ( $response{'r_approved'} eq 'APPROVED' ) {
233 $self->is_success(1);
234 $self->result_code($response{'r_code'});
235 $self->authorization($response{'r_ref'});
236 $self->order_number($response{'r_ordernum'});
237 $self->avs_code($response{'r_avs'});
239 $self->is_success(0);
240 $self->result_code('');
241 if ( $response{'r_error'} =~ /\S/ ) {
242 $self->error_message($response{'r_error'});
244 $self->error_message($response{'r_approved'}); # no r_error for checks
255 Business::OnlinePayment::LinkPoint - LinkPoint (Cardservice) backend for Business::OnlinePayment
259 use Business::OnlinePayment;
261 my $tx = new Business::OnlinePayment( 'LinkPoint',
262 'storename' => 'your_store_number',
263 'keyfile' => '/path/to/keyfile.pem',
268 action => 'Normal Authorization',
269 description => 'Business::OnlinePayment test',
271 invoice_number => '100100',
272 customer_id => 'jsk',
273 name => 'Jason Kohles',
274 address => '123 Anystreet',
278 email => 'ivan-linkpoint@420.am',
279 card_number => '4007000000027',
280 expiration => '09/99',
284 if($tx->is_success()) {
285 print "Card processed successfully: ".$tx->authorization."\n";
287 print "Card was rejected: ".$tx->error_message."\n";
290 =head1 SUPPORTED TRANSACTION TYPES
292 =head2 Visa, MasterCard, American Express, JCB, Discover/Novus, Carte blanche/Diners Club
296 For detailed information see L<Business::OnlinePayment>.
300 This module implements an interface to the LinkPoint Perl Wrapper "lpperl",
301 which you need to download and install separately.
302 http://www.linkpoint.com/product_solutions/internet/lperl/lperl_main.html
303 http://www.linkpoint.com/viewcart/down_index.htm
305 Versions 0.4 and on of this module support the LinkPoint Perl Wrapper version
312 Ivan Kohler <ivan-linkpoint@420.am>
314 Contributions from Mark D. Anderson <mda@discerning.com>
316 Echeck work by Jeff Finucane <jeff@cmh.net>
318 Based on Busienss::OnlinePayment::AuthorizeNet written by Jason Kohles.
322 perl(1), L<Business::OnlinePayment>.