initial import
[Business-OnlinePayment-TransactionCentral.git] / lib / Business / OnlinePayment / TransactionCentral.pm
1 package Business::OnlinePayment::TransactionCentral;
2
3 use 5.005;
4 use strict;
5 use Carp;
6 use Business::OnlinePayment 3;
7 use Business::OnlinePayment::HTTPS 0.02;
8 use vars qw($VERSION @ISA $DEBUG);
9
10 @ISA = qw(Business::OnlinePayment::HTTPS);
11 $VERSION = '0.02';
12 $DEBUG = 0;
13
14 sub set_defaults {
15     my $self = shift;
16
17     $self->server('webservices.primerchants.com');
18     $self->port('443');
19     $self->path('/billing/TransactionCentral/');
20
21     $self->build_subs(qw( order_number avs_code cvv2_response ));
22 }
23
24 sub submit {
25   my($self) = @_;
26
27   $self->revmap_fields(
28     'MerchantID'    => 'login',
29     'RegKey'        => 'password',
30     'Amount'        => 'amount',
31 #    'CreditAmount'  => 'amount',
32     'AccountNo'     => 'card_number',
33     'NameonAccount' => 'name',
34     'AVSADDR'       => 'address',
35     'AVSZIP'        => 'zip',
36     'CCRURL'        => \'',
37     'CVV2'          => 'cvv2',
38     'TransID'       => 'order_number',
39     'TRANSROUTE'    => 'routing_code',
40   );
41
42   #XXX also set required fields here...
43
44   my @required_fields = qw(login password);
45   my %content = $self->content();
46   my $action = $content{'action'};
47   my $url = $self->path;
48   if (
49     $content{'type'} =~ /^(cc|visa|mastercard|american express|discover)$/i
50   ) {
51
52     if ( $action =~ /^\s*normal\s*authorization\s*$/i ) {
53       $url .= 'processCC.asp';
54
55       #REFID
56       $content{'REFID'} = int(rand(2**31));
57
58       #CCMonth & CCYear
59       $content{'expiration'} =~ /^(\d+)\D+\d*(\d{2})$/
60         or croak "unparsable expiration ". $content{'expiration'};
61       my( $month, $year ) = ( $1, $2 );
62       #$month = '0'. $month if $month =~ /^\d$/;
63       $content{'CCMonth'} = $month;
64       $content{'CCYear'} = $year;
65
66       #push @required_fields, qw( amount card_numb
67     } elsif ( $action =~ /^\s*authorization\s*only\s*$/i ) {
68       croak "Authorizaiton Only is not supported by Transaction Central";
69     } elsif ( $action =~ /^\s*post\s*authorization\s*$/i ) {
70       croak "Post Authorizaiton is not supported by Transaction Central";
71     } elsif ( $action =~ /^\s*(void|credit)\s*$/i ) {
72       $url .= 'voidcreditcconline.asp';
73
74       $content{'CreditAmount'} = delete $content{'Amount'};
75
76     } else {
77       croak "Unknown action $action";
78     }
79
80   } elsif ( $content{'type'} =~ /^check$/i ) {
81
82     if ( $action =~ /^\s*normal\s*authorization\s*$/i ) {
83       $url .= 'processcheck.asp';
84       $content{'AccountNo'} = $content{'account_number'};
85       $content{'TRANSTYPE'} = $content{'account_type'} =~ /^s/i ? 'SA' : 'CK';
86
87     } elsif ( $action =~ /^\s*authorization\s*only\s*$/i ) {
88       croak "Authorizaiton Only is not supported by Transaction Central";
89     } elsif ( $action =~ /^\s*post\s*authorization\s*$/i ) {
90       croak "Post Authorizaiton is not supported by Transaction Central";
91     } elsif ( $action =~ /^\s*(void|credit)\s*$/i ) {
92       $url .= 'addckcreditupdtonline.asp';
93     } else {
94       croak "Unknown action $action";
95     }
96
97   } else {
98     croak 'Unknown type: '. $content{'type'};
99   }
100   $self->path($url);
101   $self->content(%content);
102
103   my @fields = qw(
104     MerchantID RegKey Amount REFID AccountNo CCMonth CCYear NameonAccount
105     AVSADDR AVSZIP CCRURL CVV2 USER1 USER2 USER3 USER4 TrackData
106     TransID CreditAmount
107     DESCRIPTION DESCDATE TRANSTYPE TRANSROUTE
108   );
109
110   #my( $page, $response, %reply_headers ) =
111   my( $page, $response ) =
112     $self->https_post( $self->get_fields( @fields ) );
113
114   warn "\n" if $DEBUG > 1;
115   if ( $DEBUG > 2 ) {
116     warn "response: $response\n";
117    # warn "reply headers: ".
118    #      join(', ', map "$_ => $reply_headers{$_}", keys %reply_headers ). "\n";
119   }
120   warn "raw response: $page\n" if $DEBUG > 1;
121
122   my %return = map { /^(\w+)=(.*)$/ ? ( $1 => $2 ) : () } split(/&/, $page);
123
124   if ( $DEBUG ) { warn "$_ => $return{$_}\n" foreach keys %return; }
125
126   #$self->result_code(   $return{'AVSCode'} );
127   $self->avs_code(      $return{'AVSCode'} );
128   $self->cvv2_response( $return{'CVV2ResponseMsg'} );
129
130   if ( $return{'Auth'} =~ /^(\d+)$/ ) {
131
132     $self->is_success(1);
133     $self->authorization( $return{'Auth'}   );
134     $self->order_number(  $return{'TransID'} );
135
136   } else {
137
138     $self->is_success(0);
139     $self->error_message( $return{'Notes'} );
140
141   }
142
143 }
144
145 sub revmap_fields {
146     my($self, %map) = @_;
147     my %content = $self->content();
148     foreach(keys %map) {
149 #    warn "$_ = ". ( ref($map{$_})
150 #                         ? ${ $map{$_} }
151 #                         : $content{$map{$_}} ). "\n";
152         $content{$_} = ref($map{$_})
153                          ? ${ $map{$_} }
154                          : $content{$map{$_}};
155     }
156     $self->content(%content);
157 }
158
159 1;
160
161 __END__
162
163 =head1 NAME
164
165 Business::OnlinePayment::TransactionCentral - Transaction Central backend module for Business::OnlinePayment
166
167 =head1 SYNOPSIS
168
169   use Business::OnlinePayment::TransactionCentral;
170   blah blah blah
171
172 =head1 DESCRIPTION
173
174   use Business::OnlinePayment;
175
176   ####
177   # One step transaction, the simple case.
178   ####
179
180   my $tx = new Business::OnlinePayment("Capstone");
181   $tx->content(
182       type           => 'CC',
183       login          => '10011', #MerchantID
184       password       => 'KK48NPYEJHMAH6DK', #Regkey
185       action         => 'Normal Authorization',
186       description    => 'Business::OnlinePayment test',
187       amount         => '49.95',
188       name           => 'Tofu Beast',
189       address        => '123 Anystreet',
190       city           => 'Anywhere',
191       state          => 'UT',
192       zip            => '84058',
193       phone          => '420-867-5309',
194       email          => 'tofu.beast@example.com',
195       card_number    => '4012000000001',
196       expiration     => '08/06',
197       cvv2           => '1234', #optional
198   );
199   $tx->submit();
200
201   if($tx->is_success()) {
202       print "Card processed successfully: ".$tx->authorization."\n";
203   } else {
204       print "Card was rejected: ".$tx->error_message."\n";
205   }
206
207 =head1 SUPPORTED TRANSACTION TYPES
208
209 =head2 CC, Visa, MasterCard, American Express, Discover
210
211 Content required: type, login, password, action, amount, card_number, expiration.
212
213 =head1 PREREQUISITES
214
215   URI::Escape
216   #Tie::IxHash
217
218   Net::SSLeay _or_ ( Crypt::SSLeay and LWP )
219
220 =head1 DESCRIPTION
221
222 For detailed information see L<Business::OnlinePayment>.
223
224 =head1 NOTE
225
226 =head1 AUTHOR
227
228 Ivan Kohler <ivan-transactioncentral@420.am>
229
230 =head1 COPYRIGHT AND LICENSE
231
232 Copyright (C) 2005 by Ivan Kohler
233
234 This library is free software; you can redistribute it and/or modify
235 it under the same terms as Perl itself.
236
237 =head1 SEE ALSO
238
239 perl(1). L<Business::OnlinePayment>.
240
241 =cut