1 package Business::OnlinePayment::BankOfAmerica;
3 # $Id: BankOfAmerica.pm,v 1.1 2001-09-26 03:33:32 ivan Exp $
7 use Business::OnlinePayment;
8 use Net::SSLeay qw/make_form post_https make_headers/;
10 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
14 @ISA = qw(Exporter AutoLoader Business::OnlinePayment);
22 $self->server('cart.bamart.com');
29 my %content = $self->content();
31 # warn "$_ = ". ( ref($map{$_})
33 # : $content{$map{$_}} ). "\n";
34 $content{$_} = ref($map{$_})
38 $self->content(%content);
42 my($self,@fields) = @_;
44 my %content = $self->content();
46 foreach( grep defined $content{$_}, @fields) { $new{$_} = $content{$_}; }
53 $self->{order_number} = shift;
55 return $self->{order_number};
61 my %content = $self->content;
63 my $action = lc($content{'action'});
65 die 'Normal Authorization not supported'
66 if $action eq 'normal authorization';
69 my $ioc_indicator = '';
71 if ( $action eq 'authorization only' ) {
72 $self->path('/payment.mart');
74 ioc_merchant_id ioc_order_total_amount ioc_merchant_shopper_id
75 ioc_merchant_order_id ecom_billto_postal_name_first
76 ecom_billto_postal_name_last ecom_billto_postal_street_line1
77 ecom_billto_postal_street_line2 ecom_billto_postal_city
78 ecom_billto_postal_stateprov ecom_billto_postal_postalcode
79 ecom_billto_postal_countrycode ecom_billto_telecom_phone_number
80 ecom_billto_online_email ecom_payment_card_name
81 ecom_payment_card_number ecom_payment_card_expdate_month
82 ecom_payment_card_expdate_year
84 } elsif ( $action eq 'credit' ) {
85 $self->path('/Settlement.mart');
88 ioc_handshake_id ioc_merchant_id ioc_user_name ioc_password
89 ioc_order_number ioc_indicator ioc_settlement_amount
90 ioc_authorization_code ioc_email_flag
92 # ioc_email_flag ioc_close_flag ioc_invoice_notes ioc_email_notes_flag
93 } elsif ( $action eq 'post authorization' ) {
94 $self->path('/Settlement.mart');
97 ioc_handshake_id ioc_merchant_id ioc_user_name ioc_password
98 ioc_order_number ioc_indicator ioc_settlement_amount
99 ioc_authorization_code ioc_email_flag
101 # ioc_email_flag ioc_close_flag ioc_invoice_notes ioc_email_notes_flag
103 die "unknown action $action";
106 # $self->required_fields(qw/type login password action amount last_name
107 # first_name card_number expiration/);
110 unless ( $action eq 'post authorization' ) {
112 if ( $self->transaction_type() =~
113 /^(cc|visa|mastercard|american express|discover)$/i
116 Carp::croak("BankOfAmerica can't handle transaction type: ".
117 $self->transaction_type());
120 $content{'expiration'} =~ /^(\d+)\D+(\d+)$/
121 or croak "unparsable expiration $content{expiration}";
123 ( $month, $year ) = ( $1, $2 );
124 $year += 2000 if $year < 2000; #not y4k safe, oh shit
128 $self->revmap_fields(
129 ioc_merchant_id => \($self->merchant_id()),
130 ioc_user_name => 'login',
131 ioc_password => 'password',
132 ioc_invoice_notes => 'description',
133 ioc_order_total_amount => 'amount',
134 ioc_settlement_amount => 'amount',
135 ioc_merchant_order_id => 'invoice_number',
136 ioc_order_number => 'order_number',
137 ioc_merchant_shopper_id => 'customer_id',
138 ecom_billto_postal_name_last => 'last_name',
139 ecom_billto_postal_name_first => 'first_name',
140 ecom_billto_postal_street_line1 => 'address',
141 #!!! ecom_billto_postal_street_line2 => 'address',
142 ecom_billto_postal_city => 'city',
143 ecom_billto_postal_stateprov => 'state',
144 ecom_billto_postal_postalcode => 'zip',
145 ecom_payment_card_number => 'card_number',
146 ecom_billto_postal_countrycode => 'country',
147 ecom_billto_telecom_phone_number => 'phone',
148 ecom_billto_online_email => 'email',
150 ecom_payment_card_name =>
151 \( $content{'name'} || "$content{first_name} $content{last_name}" ),
153 ecom_payment_card_expdate_month => \$month,
154 ecom_payment_card_expdate_year => \$year,
156 ioc_authorization_code => 'authorization',
157 ioc_indicator => \$ioc_indicator,
158 ioc_handshake_id => 'order_number',
159 ioc_email_flag => \'No',
163 my %post_data = $self->get_fields( @fields );
165 warn "$_ => $post_data{$_}\n" for keys %post_data;
167 my $pd = make_form(%post_data);
168 my $s = $self->server();
169 my $p = $self->port();
170 my $t = $self->path();
171 my $headers = make_headers('Referer' => $content{'referer'} )
172 unless $action eq 'post authorization';
173 my($page,$server_response,%headers) = post_https($s,$p,$t,$headers,$pd);
176 if ( $action eq 'post authorization' ) {
177 $page =~ s/<HTML>.*//s;
180 map { /^(\w+)\=(.*)$/ or /^()()$/ or die $_; lc($1) => $2 }
184 map { /^(\w+)\=(.*)$/ or die $_; lc($1) => $2 } split(/\<BR\>/i, $page);
187 warn "$_ => $response{$_}\n" for keys %response;
189 $self->server_response($page);
191 if ( $response{'ioc_response_code'} eq '0' ) {
192 $self->is_success(1);
193 $self->result_code($response{'ioc_response_code'});
194 $self->authorization($response{'ioc_authorization_code'});
195 $self->order_number($response{'ioc_order_id'});
197 $self->is_success(0);
198 $self->result_code($response{'ioc_response_code'});
200 $action eq 'post authorization'
201 ? $response{'ioc_response_desc'}
202 : $response{'ioc_reject_description'};
203 $error .= ': '. $response{'ioc_missing_fields'}
204 if $response{'ioc_missing_fields'};
205 $error .= ': '. $response{'ioc_invalid_fields'}
206 if $response{'ioc_invalid_fields'};
207 $self->error_message($error);
217 Business::OnlinePayment::BankOfAmerica - Bank of America backend for Business::OnlinePayment
221 use Business::OnlinePayment;
223 my $tx = new Business::OnlinePayment("BankOfAmerica", 'merchant_id' => 'YOURMERCHANTID');
226 action => 'Authorization Only',
227 description => 'Business::OnlinePayment test',
229 invoice_number => '100100',
230 customer_id => 'jsk',
231 first_name => 'Jason',
232 last_name => 'Kohles',
233 address => '123 Anystreet',
237 email => 'ivan-bofa@420.am',
238 card_number => '4007000000027',
239 expiration => '09/99',
240 referer => 'http://cleanwhisker.420.am/',
244 if($tx->is_success()) {
245 print "Card processed successfully: ".$tx->authorization."\n";
247 print "Card was rejected: ".$tx->error_message."\n";
250 if($tx->is_success()) {
252 $auth = $tx->authorization;
253 $ordernum = $tx->order_number;
255 my $capture = new Business::OnlinePayment("BankOfAmerica", 'merchant_id' => 'YOURMERCHANTID' );
258 action => 'Post Authorization',
260 password => 'YOURPASSWORD',
261 order_number => $ordernum,
263 authorization => $auth,
264 description => 'Business::OnlinePayment::BankOfAmerica visa test',
269 if($capture->is_success()) {
270 print "Card captured successfully: ".$capture->authorization."\n";
272 print "Card was rejected: ".$capture->error_message."\n";
277 =head1 SUPPORTED TRANSACTION TYPES
279 =head2 Visa, MasterCard, American Express, JCB, Discover/Novus, Carte blanche/Diners Club
281 Content required for `Authorization Only': type, action, amount,
282 invoice_number, customer_id, first_name, last_name, address, city, state, zip,
283 email, card_number, expiration, referer
285 Content required for `Post Authorization': action, login, password,
286 order_number, amount, authorization, description
288 `Normal Authorization' is not supported by the Bank of America gateway.
290 `Credit' is untested.
294 For detailed information see L<Business::OnlinePayment>.
298 Unlike Business::OnlinePayment or early verisons of
299 Business::OnlinePayment::AuthorizeNet, Business::OnlinePayment::BankOfAmerica
300 requires separate I<first_name> and I<last_name> fields.
302 An additional I<name> field is optional. By default the I<first_name> and
303 I<last_name> fields will be concatenated.
307 Business::OnlinePayment::BankOfAmerica does not support the
308 B<Normal Authorization> mode which combines authorization and capture into a
309 single tranaction. You must use the B<Authorization Only> mode followed by the
310 B<Post Authorization> mode. The B<Credit> mode is supported.
314 This module implements the interface documented at
315 http://www.bankofamerica.com/merchantservices/index.cfm?template=merch_ic_estores_developer.cfm
317 The settlement API is documented at
318 https://manager.bamart.com/welcome/SettlementAPI.pdf
322 No login and password are required for B<Authorization Only> mode. Access
323 is restricted only by the merchant id (available in any public store webpage
324 which passes off to the backend system) and HTTP referer header.
326 There is no way to run test transactions against the settlement API.
330 Ivan Kohler <ivan-bofa@420.am>
332 Based on Businss::OnlinePayment::AuthorizeNet written by Jason Kohles.
336 perl(1). L<Business::OnlinePayment>.