X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=InternetSecure.pm;h=b9ca589657c4ef15acaf6ad591ed35d406138ba2;hb=5de2c28522463bdf8da5f061119794799ea147b6;hp=13e18588c6278132b3ac453f1c98767166050911;hpb=7f44cb3984b0010885dbdb4daa301599c243053b;p=Business-OnlinePayment-InternetSecure.git diff --git a/InternetSecure.pm b/InternetSecure.pm index 13e1858..b9ca589 100755 --- a/InternetSecure.pm +++ b/InternetSecure.pm @@ -15,6 +15,8 @@ use base qw(Business::OnlinePayment Exporter); our $VERSION = '0.01'; +use constant SUCCESS_CODES => qw(2000 90000 900P1); + use constant CARD_TYPES => { VI => 'Visa', MC => 'MasterCard', @@ -40,9 +42,12 @@ sub set_defaults { receipt_number sales_number uuid guid date card_type cardholder - total_amount + total_amount tax_amounts avs_response cvv2_response )); + + # Just in case someone tries to call tax_amounts() *before* submit() + $self->tax_amounts( {} ); } # OnlinePayment's get_fields now filters out undefs in 3.x. :( @@ -103,9 +108,16 @@ sub prod_string { my @flags = ($currency); - foreach (split ' ' => uc($data{taxes} || '')) { - croak "Unknown tax code $_" unless /^(GST|PST|HST)$/; - push @flags, $_; + my @taxes; + if (ref $data{taxes}) { + @taxes = @{ $data{taxes} }; + } elsif ($data{taxes}) { + @taxes = split ' ' => $data{taxes}; + } + + foreach (@taxes) { + croak "Unknown tax code $_" unless /^(GST|PST|HST)$/i; + push @flags, uc $_; } if ($self->test_transaction) { @@ -141,8 +153,6 @@ sub to_xml { croak "Unknown currency code ", $content{currency} unless $content{currency} =~ /^(CAD|USD)$/; - $content{taxes} = uc($content{taxes} || ''); - my %data = $self->get_remap_fields(qw( xxxCard_Number card_number @@ -169,7 +179,7 @@ sub to_xml { $data{MerchantNumber} = $self->merchant_id; - $data{xxxCard_Number} =~ tr/ //d; + $data{xxxCard_Number} =~ tr/- //d; $data{xxxCard_Number} =~ s/^[^3-6]/4/ if $self->test_transaction; my ($y, $m) = $self->parse_expdate($content{exp_date}); @@ -200,13 +210,15 @@ sub to_xml { ); } - xml_out(\%data, + # The encode() is somewhat of a NOOP, but XML::Simple has some issues + # with the utf8 flag. + encode('ISO-8859-1', xml_out(\%data, NoAttr => 1, - NumericEscape => 2, + NumericEscape => 1, RootName => 'TranxRequest', SuppressEmpty => undef, XMLDecl => '', - ); + )); } # Map the various fields from the response, and put their values into our @@ -221,6 +233,27 @@ sub infuse { } } +sub extract_tax_amounts { + my ($self, $response) = @_; + + my %tax_amounts; + + my $products = $response->{Products}; + return unless $products; + + foreach my $node (@$products) { + my $flags = $node->{flags}; + if ($flags && + grep($_ eq '{TAX}', @$flags) && + grep($_ eq '{CALCULATED}', @$flags)) + { + $tax_amounts{ $node->{code} } = $node->{subtotal}; + } + } + + return %tax_amounts; +} + # Parse the server's response and set various fields # sub parse_response { @@ -237,9 +270,6 @@ sub parse_response { SuppressEmpty => undef, ); - my $code = $self->result_code($response->{Page}); - $self->is_success($code eq '2000' || $code eq '90000' || $code eq '900P1'); - $self->infuse($response, result_code => 'Page', error_message => 'Verbiage', @@ -258,12 +288,17 @@ sub parse_response { total_amount => 'TotalAmount', ); + $self->is_success(scalar grep $self->result_code eq $_, SUCCESS_CODES); + # Completely undocumented field that sometimes override $self->error_message($response->{Error}) if $response->{Error}; + + # Delete error_message if transaction was successful + $self->error_message(undef) if $self->is_success; $self->card_type(CARD_TYPES->{$self->card_type}); - $self->{products_raw} = $response->{Products}; + $self->tax_amounts( { $self->extract_tax_amounts($response) } ); return $self; } @@ -397,7 +432,7 @@ Transaction type, being one of the following: =item card_number (required) -Credit card number. Spaces are allowed, and will be automatically removed. +Credit card number. Spaces and dashes are automatically removed. =item exp_date (required) @@ -437,10 +472,12 @@ C (default) or C. =item taxes -Taxes to be added automatically to B by InternetSecure. +Taxes to be added automatically to B by InternetSecure. Available +taxes are C, C and C. -Available taxes are C, C and C. Multiple taxes can specified -by concatenating them with spaces, such as C. +This argument can either be a single string of taxes concatenated with spaces +(such as C), or a reference to an array of taxes (such as C<[ "GST", +"PST" ]>). =item name / company / address / city / state / zip / country / phone / email @@ -469,9 +506,9 @@ Response code returned by InternetSecure. =item error_message() -Text description of the response code. (Do not rely on this to check for -errors, as a description will also be returned for successful transactions. -Use B() instead.) +Error message if the transaction was unsuccessful; C otherwise. (You +should not rely on this to test whether a transaction was successful; use +B() instead.) =item receipt_number() @@ -509,6 +546,12 @@ Date and time of the transaction. Format is C. Total amount billed for this order, including taxes. +=item tax_amounts() + +Returns a I to a hash that maps taxes, which were listed under the +B argument to B(), to the amount that was calculated by +InternetSecure. + =item cardholder() Cardholder's name. This is currently a mere copy of the B field passed @@ -531,10 +574,6 @@ following: =back -=item products_raw() - -... - =back