initial import
[Business-OnlinePayment-PXPost.git] / PXPost.pm
1 package Business::OnlinePayment::PXPost;
2
3 use strict;
4 use Carp;
5 use Tie::IxHash;
6 use Business::OnlinePayment 3;
7 use Business::OnlinePayment::HTTPS 0.03;
8 use vars qw($VERSION $DEBUG @ISA);
9
10 @ISA = qw(Business::OnlinePayment::HTTPS);
11 $VERSION = '0.01';
12 $DEBUG = 0;
13
14 sub set_defaults {
15     my $self = shift;
16
17     $self->server('www.paymentexpress.com');
18     $self->port('443');
19     $self->path('/pxpost.asp');
20
21     $self->build_subs(qw( order_number ));
22      #avs_code order_type md5 cvv2_response cavv_response
23 }
24
25 sub submit {
26     my($self) = @_;
27
28     $self->remap_fields(
29         'login'       => 'PostUsername',
30         'password'    => 'PostPassword',
31         'name'        => 'CardHolderName',
32         'card_number' => 'CardNumber',
33         #'expiration'  => 'DateExpiry',
34         'amount'      => 'Amount',
35         'cvv2'        => 'Cvc2',
36         'action'      => 'TxnType',
37         'currency'    => 'InputCurrency',
38         #''            => 'TxnId',
39         #''            => 'MerchantReference',
40         #''            => 'TxnData1',
41         #''            => 'TxnData2',
42         #''            => 'TxnData3',
43         #''            => 'DpsTxnRef', #XXX
44         #''            => 'DpsBillingId',
45         #''            => 'BillingId',
46         #''            => 'EnableAddBillCard',
47     );
48
49     my $action = $self->{_content}{'TxnType'};
50     if ( $action =~ /^\s*normal\s*authorization\s*$/i ) {
51       $action = 'Purchase';
52     } elsif ( $action =~ /^\s*authorization\s*only\s*$/i ) {
53       $action = 'Auth';
54     } elsif ( $action =~ /^\s*post\s*authorization\s*$/i ) {
55       $action = 'Complete';
56     } elsif ( $action =~ /^\s*void\s*$/i ) {
57       die "DPS PXPost does not support void transactions\n";
58     } elsif ( $action =~ /^\s*credit\s*$/i ) {
59       $action = 'Refund';
60     }
61     $self->{_content}{'TxnType'} = $action;
62
63     if ( $action =~ /^(Purchase|Auth)$/ ) {
64 #
65       $self->required_fields(
66         qw( login password name card_number expiration amount )
67       );
68
69       #exp
70       $self->{_content}{'expiration'} =~ /^(\d+)\D+\d*(\d{2})$/
71         or croak "unparsable expiration ". $self->{_content}{expiration};
72       my( $month, $year ) = ( $1, $2 );
73       $month = '0'. $month if $month =~ /^\d$/;
74       $self->{_content}{'DateExpiry'} = $month.$year;
75
76     } elsif ( $action eq 'Complete' || $action eq 'Refund' ) {
77
78       $self->required_fields(
79         qw( login password name order_number amount )
80       );
81
82     }
83
84
85     tie my %fields, 'Tie::IxHash', $self->get_fields( $self->fields );
86     my $post_data = join("\n",
87       '<Txn>',
88       ( map "<$_>$fields{$_}</$_>", keys %fields ),
89       '</Txn>',
90     ). "\n";
91
92     warn $post_data if $DEBUG > 1;
93
94     my( $page, $response, @reply_headers ) = $self->https_post( $post_data );
95
96     $self->server_response($page);
97
98     my $result = $self->GetXMLProp($page, 'Authorized');
99
100     if ( $result =~ /^\s*1\s*$/ ) {
101       $self->is_success(1);
102       $self->result_code( $self->GetXMLProp( $page, 'ReCo' ) );
103       $self->authorization( $self->GetXMLProp( $page, 'AuthCode' ) );
104       $self->order_number( $self->GetXMLProp( $page, 'DpsTxnRef' ) );
105     } elsif ( $result =~ /^\s*0\s*$/ ) {
106       $self->is_success(0);
107       $self->result_code( $self->GetXMLProp( $page, 'ReCo' ) );
108       $self->error_message( $self->GetXMLProp( $page, 'ResponseText' ). ': '.
109                             $self->GetXMLProp( $page, 'HelpText'     )
110                           );
111     } else {
112       die "unparsable response received from gateway (response $result)".
113           ( $DEBUG ? ": $page" : '' );
114     }
115
116 }
117
118 sub fields {
119         my $self = shift;
120
121         #order is important to this processor
122         qw(
123           PostUsername
124           PostPassword
125           CardHolderName
126           CardNumber
127           DateExpiry
128           Amount
129           Cvc2
130           TxnType
131           InputCurrency
132           TxnId
133           MerchantReference
134           TxnData1
135           TxnData2
136           TxnData3
137           DpsTxnRef
138           DpsBillingId
139           BillingId
140           EnableAddBillCard
141         );
142 }
143
144 sub GetXMLProp {
145         my( $self, $raw, $prop ) = @_;
146         local $^W=0;
147
148         my $data;
149         ($data) = $raw =~ m"<$prop>(.*?)</$prop>"gsi;
150         #$data =~ s/<.*?>/ /gs;
151         chomp $data;
152         return $data;
153 }
154
155 1;
156
157 __END__
158
159 =head1 NAME
160
161 Business::OnlinePayment::PXPost - Direct Payment Solutions PX Post backend module for Business::OnlinePayment
162
163 =head1 SYNOPSIS
164
165   use Business::OnlinePayment;
166
167   ####
168   # One step transaction, the simple case.
169   ####
170
171   my $tx = new Business::OnlinePayment("PXPost");
172   $tx->content(
173       type           => 'VISA',
174       login          => 'PXPost Username',
175       password       => 'PXPost Password',
176       action         => 'Normal Authorization',
177       #description    => 'Business::OnlinePayment test',
178       amount         => '49.95',
179       name           => 'Tofu Beast',
180       card_number    => '4005550000000019',
181       expiration     => '08/06',
182       cvv2           => '1234', #optional
183   );
184   $tx->submit();
185
186   if($tx->is_success()) {
187       print "Card processed successfully: ".$tx->authorization."\n";
188   } else {
189       print "Card was rejected: ".$tx->error_message."\n";
190   }
191
192 =head1 SUPPORTED TRANSACTION TYPES
193
194 =head2 CC, Visa, MasterCard, American Express, Discover
195
196 Content required: type, login, password, action, amount, card_number, expiration, name.
197
198 =head1 PREREQUISITES
199
200   URI::Escape
201   Tie::IxHash
202
203   Net::SSLeay _or_ ( Crypt::SSLeay and LWP )
204
205 =head1 DESCRIPTION
206
207 For detailed information see L<Business::OnlinePayment>.
208
209 =head1 NOTE
210
211 =head1 AUTHOR
212
213 Ivan Kohler <ivan-pxpost@420.am>
214
215 =head1 SEE ALSO
216
217 perl(1). L<Business::OnlinePayment>.
218
219 =cut
220