Added backwards-compatible support for sales_number
[Business-OnlinePayment-InternetSecure.git] / InternetSecure.pm
index 691d72b..b6632ed 100755 (executable)
@@ -12,17 +12,17 @@ use XML::Simple qw(xml_in xml_out);
 use base qw(Business::OnlinePayment Exporter);
 
 
 use base qw(Business::OnlinePayment Exporter);
 
 
-our $VERSION = '0.01';
+our $VERSION = '0.03';
 
 
 use constant SUCCESS_CODES => qw(2000 90000 900P1);
 
 use constant CARD_TYPES => {
 
 
 use constant SUCCESS_CODES => qw(2000 90000 900P1);
 
 use constant CARD_TYPES => {
-                               VI => 'Visa',
+                               AM => 'American Express',
+                               JB => 'JCB',
                                MC => 'MasterCard',
                                MC => 'MasterCard',
-                               AX => 'American Express', # FIXME: AM?
                                NN => 'Discover',
                                NN => 'Discover',
-                               # JB?
+                               VI => 'Visa',
                        };
 
 
                        };
 
 
@@ -39,36 +39,36 @@ sub set_defaults {
        $self->path('/process.cgi');
 
        $self->build_subs(qw(
        $self->path('/process.cgi');
 
        $self->build_subs(qw(
-                               receipt_number  sales_number    uuid    guid
+                               receipt_number  order_number    uuid    guid
                                date
                                card_type       cardholder
                                total_amount    tax_amounts
                                date
                                card_type       cardholder
                                total_amount    tax_amounts
-                               avs_response    cvv2_response
+                               avs_code        cvv2_response
                        ));
        
        # Just in case someone tries to call tax_amounts() *before* submit()
        $self->tax_amounts( {} );
 }
 
                        ));
        
        # 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. :(
-#
-sub get_fields {
-       my ($self, @fields) = @_;
+# Backwards-compatible support for renamed fields
+sub avs_response { shift()->avs_code(@_) }
+sub sales_number { shift()->order_number(@_) }
 
 
-       my %content = $self->content;
-
-       my %new = map +($_ => $content{$_}), @fields;
-
-       return %new;
-}
 
 
-# Combine get_fields and remap_fields for convenience
+# Combine get_fields and remap_fields for convenience.  Unlike OnlinePayment's
+# remap_fields, this doesn't modify content(), and can therefore be called
+# more than once.  Also, unlike OnlinePayment's get_fields in 3.x, this doesn't
+# exclude undefs.
 #
 sub get_remap_fields {
        my ($self, %map) = @_;
 
 #
 sub get_remap_fields {
        my ($self, %map) = @_;
 
-       $self->remap_fields(reverse %map);
-       my %data = $self->get_fields(keys %map);
+       my %content = $self->content();
+       my %data;
+
+       while (my ($to, $from) = each %map) {
+               $data{$to} = $content{$from};
+       }
 
        return %data;
 }
 
        return %data;
 }
@@ -140,11 +140,18 @@ sub to_xml {
 
        my %content = $self->content;
 
 
        my %content = $self->content;
 
-       $self->required_fields(qw(action card_number exp_date));
+       # Backwards-compatible support for exp_date
+       if (exists $content{exp_date} && ! exists $content{expiration}) {
+               $content{expiration} = delete $content{exp_date};
+               $self->content(%content);
+       }
+
+       $self->required_fields(qw(action card_number expiration));
 
 
-       croak 'Unsupported transaction type'
-               if $content{type} && $content{type} !~
-                       /^(Visa|MasterCard|American Express|Discover)$/i;
+       croak "Unsupported transaction type: $content{type}"
+               if $content{type} &&
+                       ! grep lc($content{type}) eq lc($_),
+                               values %{+CARD_TYPES};
        
        croak 'Unsupported action'
                unless $content{action} =~ /^Normal Authori[zs]ation$/i;
        
        croak 'Unsupported action'
                unless $content{action} =~ /^Normal Authori[zs]ation$/i;
@@ -182,7 +189,7 @@ sub to_xml {
        $data{xxxCard_Number} =~ tr/- //d;
        $data{xxxCard_Number} =~ s/^[^3-6]/4/ if $self->test_transaction;
 
        $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});
+       my ($y, $m) = $self->parse_expdate($content{expiration});
        $data{xxxCCYear} = sprintf '%.4u' => $y;
        $data{xxxCCMonth} = sprintf '%.2u' => $m;
 
        $data{xxxCCYear} = sprintf '%.4u' => $y;
        $data{xxxCCMonth} = sprintf '%.2u' => $m;
 
@@ -273,11 +280,11 @@ sub parse_response {
                        result_code     => 'Page',
                        error_message   => 'Verbiage',
                        authorization   => 'ApprovalCode',
                        result_code     => 'Page',
                        error_message   => 'Verbiage',
                        authorization   => 'ApprovalCode',
-                       avs_response    => 'AVSResponseCode',
+                       avs_code        => 'AVSResponseCode',
                        cvv2_response   => 'CVV2ResponseCode',
 
                        receipt_number  => 'ReceiptNumber',
                        cvv2_response   => 'CVV2ResponseCode',
 
                        receipt_number  => 'ReceiptNumber',
-                       sales_number    => 'SalesOrderNumber',
+                       order_number    => 'SalesOrderNumber',
                        uuid            => 'GUID',
                        guid            => 'GUID',
 
                        uuid            => 'GUID',
                        guid            => 'GUID',
 
@@ -351,7 +358,7 @@ Business::OnlinePayment::InternetSecure - InternetSecure backend for Business::O
 
        type            => 'Visa',                      # Optional
        card_number     => '4111 1111 1111 1111',
 
        type            => 'Visa',                      # Optional
        card_number     => '4111 1111 1111 1111',
-       exp_date        => '2004-07',
+       expiration      => '2004-07',
        cvv2            => '000',                       # Optional
 
        name            => "Fr\x{e9}d\x{e9}ric Bri\x{e8}re",
        cvv2            => '000',                       # Optional
 
        name            => "Fr\x{e9}d\x{e9}ric Bri\x{e8}re",
@@ -425,6 +432,8 @@ Transaction type, being one of the following:
 
 =item - Discover
 
 
 =item - Discover
 
+=item - JCB
+
 =back
 
 (This is actually ignored for the moment, and can be left blank or undefined.)
 =back
 
 (This is actually ignored for the moment, and can be left blank or undefined.)
@@ -433,7 +442,7 @@ Transaction type, being one of the following:
 
 Credit card number.  Spaces and dashes are automatically removed.
 
 
 Credit card number.  Spaces and dashes are automatically removed.
 
-=item exp_date (required)
+=item expiration (required)
 
 Credit card expiration date.  Since C<Business::OnlinePayment> does not specify
 any syntax, this module is rather lax regarding what it will accept.  The
 
 Credit card expiration date.  Since C<Business::OnlinePayment> does not specify
 any syntax, this module is rather lax regarding what it will accept.  The
@@ -514,7 +523,7 @@ B<is_success>() instead.)
 Receipt number (a string, actually) of this transaction, unique to all
 InternetSecure transactions.
 
 Receipt number (a string, actually) of this transaction, unique to all
 InternetSecure transactions.
 
-=item sales_number()
+=item order_number()
 
 Sales order number of this transaction.  This is a number, unique to each
 merchant, which is incremented by 1 each time.
 
 Sales order number of this transaction.  This is a number, unique to each
 merchant, which is incremented by 1 each time.
@@ -532,7 +541,7 @@ B<guid>() is provided as an alias to this method.
 
 Authorization code for this transaction.
 
 
 Authorization code for this transaction.
 
-=item avs_response() / cvv2_response()
+=item avs_code() / cvv2_response()
 
 Results of the AVS and CVV2 checks.  See the InternetSecure documentation for
 the list of possible values.
 
 Results of the AVS and CVV2 checks.  See the InternetSecure documentation for
 the list of possible values.
@@ -571,6 +580,8 @@ following:
 
 =item - Discover
 
 
 =item - Discover
 
+=item - JCB
+
 =back
 
 
 =back
 
 
@@ -588,7 +599,7 @@ the following fields:
 
 =over 4
 
 
 =over 4
 
-=item amount
+=item amount (required)
 
 Unit price of this product.
 
 
 Unit price of this product.
 
@@ -617,15 +628,13 @@ be left undefined.
 
 =head2 Character encoding
 
 
 =head2 Character encoding
 
-Since communication to/from InternetSecure is encoded with UTF-8, all Unicode
-characters are theoretically available when submitting information via
-B<submit>().  (Further restrictions may be imposed by InternetSecure itself.)
+When using non-ASCII characters, all data provided to B<contents>() should
+have been decoded beforehand via the C<Encode> module, unless your data is in
+ISO-8859-1 and you haven't meddled with the C<encoding> pragma.  (Please
+don't.)
 
 
-When using non-ASCII characters, all data provided to B<submit>() should either
-be in the current native encoding (typically latin-1, unless it was modified
-via the C<encoding> pragma), or be decoded via the C<Encode> module.
-Conversely, all data returned after calling B<submit>() will be automatically
-decoded.
+InternetSecure currently does not handle characters outside of ISO-8859-1, so
+these will be replaced with C<?> before being transmitted.
 
 
 =head1 EXPORT
 
 
 =head1 EXPORT