Merge branch 'master' of git.freeside.biz:/home/git/Business-OnlineThirdPartyPayment
[Business-OnlineThirdPartyPayment.git] / OnlineThirdPartyPayment.pm
1 package Business::OnlineThirdPartyPayment;
2
3 use strict;
4 use vars qw($VERSION);
5 use Carp;
6 use base qw(Business::OnlinePayment);
7
8 require 5.005;
9
10 $VERSION = '0.10';
11 $VERSION = eval $VERSION; # modperlstyle: convert the string into a number
12
13 my %fields = (
14     is_success          => undef,
15     token               => undef,
16     redirect            => undef,
17     post_params         => undef,
18     statustext          => undef,
19     order_number        => undef,
20     authorization       => undef,
21     error_message       => undef,
22     test_transaction    => undef,
23     return_url          => undef,
24     cancel_url          => undef,
25 );
26
27 sub new {
28     my($class,$processor,%data) = @_;
29
30     croak("unspecified processor") unless $processor;
31
32     my $subclass = "${class}::$processor";
33     eval "use $subclass";
34     croak("unknown processor $processor ($@)") if $@;
35
36     my $self = bless {processor => $processor}, $subclass;
37     $self->build_subs(keys %fields);
38
39     if($self->can("set_defaults")) {
40         $self->set_defaults(%data);
41     }
42
43     foreach(keys %data) {
44         my $key = lc($_);
45         my $value = $data{$_};
46         $key =~ s/^\-+//;
47         $self->build_subs($key);
48         $self->$key($value);
49     }
50
51     return $self;
52 }
53
54 1;
55
56 __END__
57
58 =head1 NAME
59
60 Business::OnlineThirdPartyPayment - Common interface to browser-based 
61 online payment processors
62
63 =head1 SYNOPSIS
64
65   use Business::OnlineThirdPartyPayment;
66   use CGI;
67
68   my %processor_info = (
69     'return_url'  => 'https://www.example.com/payment/return',
70     'cancel_url'  => 'https://www.example.com/payment/cancel',
71     # ... other processor-specific values
72   );
73
74   my $txn = Business::OnlineThirdPartyPayment->new('MyBank', %processor_info);
75   # start a payment
76   $txn->create( customer_id     => 4030,
77                 invoice_number  => 10318,
78                 amount          => 49.95,
79                 currency        => 'CAD',
80                 description     => 'Internet Services',
81               );
82
83   if ( $txn->is_success} ) {
84     store_payment_id($txn->token); # keep it somewhere
85     print CGI->redirect( $txn->redirect );
86   } else {
87     die $txn->error_message;
88   }
89
90   ...
91   # then, at /payment/return...
92   my $txn = Business::OnlineThirdPartyPayment->new('MyBank', %processor_info);
93   $txn->token( get_payment_id($cgi) ); # probably from a session cookie
94   my %params = $cgi->Vars;
95
96   $txn->execute(%params);
97   
98   if ( $txn->is_success ) {
99     store_payment_success($txn->order_number, $txn->authorization);
100     print "Your payment was successful!\n";
101   } else {
102     store_payment_failure($txn->order_number, $txn->error_message);
103     print "Your payment failed.\n";
104   }
105
106 =head1 DESCRIPTION
107
108 Business::OnlineThirdPartyPayment is a generic module for processing payments
109 through online credit card processors, electronic cash systems, etc. through
110 which the payer's web browser is redirected.
111
112 =head1 METHODS
113
114 =head2 new($module, %processor_options)
115
116 Class method.  Create a Business::OnlineThirdPartyPayment object.
117 $module is required, and defines the gateway module to use.  The 
118 other options are processor-specific, but should always include:
119
120 =over 4
121
122 =item return_url - The callback URL to redirect the user to after completing 
123 a payment.
124
125 =item cancel_url - The URL to redirect the user to if they choose not to 
126 complete the payment.
127
128 =back
129
130 =head2 create(%content)
131
132 Tell the gateway module to start a transaction.  This may involve 
133 communicating with the gateway, or it may happen entirely locally.
134 %content is a hash containing some of the following:
135
136 =head3 TRANSACTION FIELDS
137
138 =over 4
139
140 =item amount - The amount of the transaction, as a decimal number. Required.
141
142 =item description - A description of the purchase. Required.
143
144 =item invoice_number - Your invoice number, if this payment is associated
145 with a specific invoice.
146
147 =item currency - Currency, specified as an ISO 4217 three-letter code, such 
148 as USD, CAD, EUR, AUD, DKK, GBP, JPY, NZD, etc.
149
150 =item customer_id - The customer number, if any.
151
152 =item email - Customer's email address.
153
154 =item customer_ip - IP address from which the transaction originated.
155
156 =back
157
158 For additional fields, see L<Business::OnlinePayment> and the specific
159 processor module used.
160
161 C<create()> sets properties of the transaction object to indicate the 
162 result.  These will always include:
163
164 =over 4
165
166 =item is_success - 1 if the transaction was created successfully, 0 
167 otherwise.
168
169 =item error_message - a text description of any error that occurred.
170 Since the payer hasn't provided a payment account or any other 
171 information at this stage, this is probably not meaningful to them.
172
173 =item token - a reference string that will be used to identify
174 this transaction later.  If is_success is true, you I<must> store this 
175 value in your merchant system and pass it to execute() later.  Merchant 
176 systems should allow at least 256 characters for this string.
177
178 =item statustext - a freeform text field for any state information 
179 that the gateway needs to receive to complete the transaction.
180
181 =item redirect - a URL to redirect the payer to.
182
183 =item post_params - the content of an HTTP POST request to send to the 
184 URL.  Since HTTP redirects can't include POST content, in this case the 
185 front-end system must provide another way (a self-submitting form) to 
186 induce the purchaser's browser to make the request.
187
188 =back
189
190 =head2 execute(%params)
191
192 Complete the transaction.  This should be called from the web server
193 (from 'return_url').  %params must contain any query parameters passed 
194 in the redirect, and token should be set on the object.
195
196 execute() will set the transaction fields to indicate the result:
197
198 =over 4
199
200 =item is_success: 1 if the payment was successful, 0 if it was not.
201
202 =item error_message: An error message describing the reason for failure.
203 Unlike the message returned from C<create()>, this probably is meaningful
204 to the user, though the gateway may already have shown it to them.
205
206 =item order_number: The transaction ID number assigned by the processor.
207
208 =item authorization: The credit card or other authorization number 
209 returned by the gateway.  This may be needed to refund the payment or 
210 for other customer service issues.
211
212 =back
213
214 If C<is_success> is true, the merchant system should record this as 
215 a successful payment and apply it to the customer's account.
216
217 =head1 AUTHOR
218
219 Mark Wells <mark@freeside.biz>, based in part on code by Jeff Finucane.
220
221 =head1 COPYRIGHT
222
223 Copyright (c) 1999-2004 Jason Kohles.
224 Copyright (c) 2007-2013 Freeside Internet Services, Inc.
225
226 All rights reserved. This program is free software; you can redistribute
227 it and/or modify it under the same terms as Perl itself.
228
229 =head1 DISCLAIMER
230
231 THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
232 WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
233 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
234
235 =head1 SEE ALSO
236
237 L<Business::OnlinePayment>, http://420.am/business-onlinepayment/
238
239 =cut