working against test server!
[Business-OnlinePayment-CardFortress.git] / lib / Business / OnlinePayment / CardFortress.pm
index 513ed26..1946624 100644 (file)
@@ -5,6 +5,8 @@ use base qw( Business::OnlinePayment::HTTPS );
 use warnings;
 use strict;
 #use vars qw( $DEBUG $me );
+use MIME::Base64;
+use Crypt::OpenSSL::RSA;
 
 our $VERSION = 0.01;
 
@@ -38,20 +40,23 @@ sub set_defaults {
 
   $self->build_subs(qw( order_number avs_code cvv2_response
                         response_page response_code response_headers
-                        card_token
+                        card_token private_key
                    ));
 }
 
 sub submit {
   my $self = shift;
 
-  $self->server('test.cardfortress.com');
+  $self->server('test.cardfortress.com') if $self->test_transaction;
 
-  my ($page,$server_response,%headers) = $self->https_post($self->content);
+  my %content = $self->content;
+  $content{$_} = $self->$_() for qw( gateway gateway_login gateway_password );
 
-  die $server_response unless $server_response =~ /^200/;
+  my ($page,$server_response,%headers) = $self->https_post(%content);
 
-  my %response = {};
+  die "$server_response\n" unless $server_response =~ /^200/;
+
+  my %response = ();
   #this encoding good enough?  wfm... if something's easier for other
   #languages they can always use a different URL
   foreach my $line ( grep /^\w+=/, split(/\n/, $page) ) {
@@ -73,6 +78,26 @@ sub submit {
   # response_headers()
   # response_page()
 
+  #handle the challenge/response handshake
+  if ( $self->error_message eq '_challenge' ) { #XXX infinite loop protection?
+
+    die "no private key available" unless $self->private_key;
+
+    #decrypt the challenge with the private key
+    my $challenge = decode_base64($response{'card_challenge'});
+
+    #here is the hardest part to implement at each client side
+    my $rsa_priv = Crypt::OpenSSL::RSA->new_private_key($self->private_key);
+    my $response = $rsa_priv->decrypt($challenge);
+
+    #try the transaction again with the challenge response
+    # (B:OP could sure use a better way to alter one value)
+    my %content = $self->content;
+    $content{'card_response'} = encode_base64($response, '');
+    $self->content(%content);
+    $self->submit;
+  }
+
 }
 
 1;
@@ -127,7 +152,7 @@ Business::OnlinePayment::CardFortress - CardFortress backend for Business::Onlin
                                           'gateway' => 'ProcessingGateway',
                                           'gateway_login' => 'gwlogin',
                                           'gateway_password' => 'gwpass',
-                                          'private_key' => '/path/to/keyfile',
+                                          'private_key' => $private_key_string,
                                       );
 
   $rx->content(