initial import
[Business-OnlinePayment-StGeorge.git] / StGeorge.pm
1 package Business::OnlinePayment::StGeorge;
2
3 use strict;
4 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
5 use Carp qw(croak);
6 use Business::OnlinePayment;
7
8 @ISA = qw(Business::OnlinePayment);
9 $VERSION = '0.01';
10
11 use webpayperl; #webpayperl.pm from St.George
12
13 sub set_defaults {
14     my $self = shift;
15
16     $self->server('www.gwipg.stgeorge.com.au');
17     $self->port('3006');
18
19     $self->build_subs(qw(order_number));
20
21 }
22
23 sub map_fields {
24     my($self) = @_;
25
26     my %content = $self->content();
27
28     #ACTION MAP
29     my %actions = ('normal authorization' => 'PURCHASE',
30                    'authorization only'   => 'PREAUTH',
31                    'credit'               => 'REFUND',
32                    'post authorization'   => 'COMPLETION',
33                   );
34     $content{'action'} = $actions{lc($content{'action'})} || $content{'action'};
35
36     # TYPE MAP
37     my %types = ('cc'                 => 'CREDITCARD',
38                  'visa'               => 'CREDITCARD',
39                  'mastercard'         => 'CREDITCARD',
40                  'american express'   => 'CREDITCARD',
41                  'discover'           => 'CREDITCARD',
42                 );
43     $content{'type'} = $types{lc($content{'type'})} || $content{'type'};
44     $self->transaction_type($content{'type'});
45
46     # stuff it back into %content
47     $self->content(%content);
48 }
49
50 sub build_subs {
51     my $self = shift;
52     foreach(@_) {
53         #no warnings; #not 5.005
54         local($^W)=0;
55         eval "sub $_ { my \$self = shift; if(\@_) { \$self->{$_} = shift; } return \$self->{$_}; }";
56     }
57 }
58
59 sub remap_fields {
60     my($self,%map) = @_;
61
62     my %content = $self->content();
63     foreach(keys %map) {
64         $content{$map{$_}} = $content{$_};
65     }
66     $self->content(%content);
67 }
68
69 sub revmap_fields {
70     my($self, %map) = @_;
71     my %content = $self->content();
72     foreach(keys %map) {
73 #    warn "$_ = ". ( ref($map{$_})
74 #                         ? ${ $map{$_} }
75 #                         : $content{$map{$_}} ). "\n";
76         $content{$_} = ref($map{$_})
77                          ? ${ $map{$_} }
78                          : $content{$map{$_}};
79     }
80     $self->content(%content);
81 }
82
83 sub get_fields {
84     my($self,@fields) = @_;
85
86     my %content = $self->content();
87     my %new = ();
88     foreach( grep defined $content{$_}, @fields) { $new{$_} = $content{$_}; }
89     return %new;
90 }
91
92 sub submit {
93     my($self) = @_;
94
95     $self->map_fields();
96
97     my %content = $self->content;
98
99     my $exp = '';
100     unless ( $content{action} eq 'STATUS' ) {
101
102       $content{'expiration'} =~ /^(\d+)\D+\d*(\d{2})$/
103         or croak "unparsable expiration $content{expiration}";
104
105       my( $month, $year ) = ( $1, $2 );
106       $month = '0'. $month if $month =~ /^\d$/;
107       $exp = "$month$year";
108
109     }
110
111     if ( $self->test_transaction) {
112       $self->port(3007);
113     }
114
115     my $terminal_type = 0;
116     $terminal_type = 4 if $content{'recurring_billing'};
117
118     $self->revmap_fields(
119       INTERFACE           => 'type',
120       TRANSACTIONTYPE     => 'action',
121       TOTALAMOUNT         => 'amount',
122       #TAXAMOUNT
123       CARDDATA            => 'card_number',
124       CARDEXPIRYDATE      => \$exp,
125       #TXNREFERENCE
126       #ORIGINALTXNREF
127       #AUTHORISATIONNUMBER
128       CLIENTREF           => 'customer_id',
129       COMMENT             => 'invoice_number',
130       TERMINALTYPE        => \$terminal_type,
131       CVC2                => 'cvv2',
132     );
133
134     my $action = $content{action};
135
136     if ( $action eq 'PURCHASE' || $action eq 'PREAUTH' ) {
137       $self->required_fields(qw/
138         login password
139         INTERFACE TRANSACTIONTYPE TOTALAMOUNT CARDDATA CARDEXPIRYDATE
140       /);
141     } elsif ( $action eq 'REFUND' ) {
142       $self->required_fields(qw/
143         login password
144         INTERFACE TRANSACTIONTYPE TOTALAMOUNT CARDDATA CARDEXPIRYDATE
145         ORIGINALTXNREF
146       /);
147     } elsif ( $action eq 'COMPLETION' ) {
148       $self->required_fields(qw/
149         login password
150         INTERFACE TRANSACTIONTYPE TOTALAMOUNT CARDDATA CARDEXPIRYDATE
151         AUTHORISATIONNUMBER
152       /);
153     } elsif ( $action eq 'STATUS' ) {
154       $self->required_fields(qw/
155         login password
156         TXNREFERENCE
157       /);
158     }
159
160     my %post = $self->get_fields(qw/
161       login password
162       INTERFACE TRANSACTIONTYPE TOTALAMOUNT CARDDATA CARDEXPIRYDATE
163     /);
164
165     # if ( $DEBUG ) { warn "$_ => $post{$_}\n" foreach keys %post; }
166
167     webpayperl::init_client or croak "St.George initialization failed\n";
168     #dd this to all exit places after here
169     #webpayperl::cleanup( $webpayRef );
170
171     my $webpayRef = webpayperl::newBundle;
172     webpayperl::addVersionInfo($webpayRef);
173     webpayperl::put($webpayRef, "DEBUG", "OFF");
174     #webpayperl::put($webpayRef, "LOGFILE", "webpay.log");
175     webpayperl::put_ClientID           ( $webpayRef, delete $post{'login'}    );
176     webpayperl::put_CertificatePath    ( $webpayRef, $self->cert_path         );
177     webpayperl::put_CertificatePassword( $webpayRef, delete $post{'password'} );
178     webpayperl::setPort                ( $webpayRef, $self->port              );
179     webpayperl::setServers             ( $webpayRef, $self->server            );
180
181     foreach my $key ( keys %post ) {
182       warn "$key undefined" unless defined($post{$key});
183       webpayperl::put($webpayRef, $key, $post{$key} );
184     }
185
186     my $tranProcessed = webpayperl::execute( $webpayRef );
187     unless ( $tranProcessed ) {
188       #St.George error handling is bunk
189       $self->is_success(0);
190       $self->error_message( webpayperl::get( $webpayRef, "ERROR").
191                             ' (transaction reference: '.
192                             webpayperl::get( $webpayRef, 'TXNREFERENCE' ).
193                             ')'
194                           );
195
196       webpayperl::cleanup( $webpayRef );
197       webpayperl::free_client();
198       return;
199     }
200
201     my $responseCode = webpayperl::get( $webpayRef, "RESPONSECODE"); 
202     $self->result_code($responseCode);
203
204     if ( grep { $responseCode eq $_ } qw( 00 08 77 ) ) {
205       $self->is_success(1);
206       $self->authorization(webpayperl::get( $webpayRef, "AUTHCODE"));
207       $self->order_number(webpayperl::get( $webpayRef, "TXNREFERENCE"));
208     } else {
209       $self->is_success(0);
210       $self->error_message( webpayperl::get( $webpayRef, "RESPONSETEXT"). ' - '.
211                             webpayperl::get( $webpayRef, "ERROR").
212                             ' (transaction reference: '.
213                             webpayperl::get( $webpayRef, 'TXNREFERENCE' ).
214                             ')'
215                           );
216     }
217  
218     webpayperl::cleanup( $webpayRef );
219     webpayperl::free_client();
220
221 }
222
223 1;
224 __END__
225
226 =head1 NAME
227
228 Business::OnlinePayment::StGeorge - St.George Bank backend for Business::OnlinePayment
229
230 =head1 SYNOPSIS
231
232   use Business::OnlinePayment;
233
234   my $tx = new Business::OnlinePayment( 'StGeorge',
235     'cert_path'     => '/home/StGeorge/client.cert',
236   );
237
238   $tx->content(
239       login          => '10000000', #The Client ID issued to you
240       password       => 'w0rd', #The password protecting your certificate file
241       type           => 'VISA',
242       action         => 'Normal Authorization',
243       description    => 'Business::OnlinePayment test',
244       amount         => '49.95',
245       invoice_number => '100100',
246       customer_id    => 'jsk',
247       name           => 'Jason Kohles',
248       address        => '123 Anystreet',
249       city           => 'Anywhere',
250       state          => 'UT',
251       zip            => '84058',
252       email          => 'ivan-stgeorge@420.am',
253       card_number    => '4007000000027',
254       expiration     => '09/99',
255   );
256   $tx->submit();
257
258   if($tx->is_success()) {
259       print "Card processed successfully: ".$tx->authorization."\n";
260   } else {
261       print "Card was rejected: ".$tx->error_message."\n";
262   }
263
264 =head1 SUPPORTED TRANSCTION TYPES
265
266 =head2 CC, Visa, MasterCard, American Express, Discover
267
268 =head1 DESCRIPTION
269
270 For detailed information see L<Business::OnlinePayment>.
271
272 =head1 COMPATIBILITY
273
274 This module implements an interface to the St. George Bank Internet Payment
275 Gateway Perl API.
276
277 https://www.ipg.stgeorge.com.au/
278
279 This module has been developed against webpayPerl version 2.8
280
281 =head1 BUGS
282
283 =head1 AUTHOR
284
285 Ivan Kohler <ivan-stgeorge@420.am>
286
287 Based on Busienss::OnlinePayment::AuthorizeNet written by Jason Kohles.
288
289 =head1 SEE ALSO
290
291 perl(1), L<Business::OnlinePayment>.
292
293 =cut
294