finally working
authorivan <ivan>
Tue, 17 Dec 2002 19:14:09 +0000 (19:14 +0000)
committerivan <ivan>
Tue, 17 Dec 2002 19:14:09 +0000 (19:14 +0000)
MANIFEST
PaymentsGateway.pm
README
t/bad_check.t [new file with mode: 0644]
t/check.t [new file with mode: 0644]
t2/bad_check.t [deleted file]
t2/check.t [deleted file]

index 1b977f8..e79145a 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -5,5 +5,5 @@ Makefile.PL
 README
 t/load.t
 t/bop.t
-t2/check.t.t
-t2/bad_check.t
+t/check.t
+t/bad_check.t
index 9070e1d..4f86106 100644 (file)
@@ -2,24 +2,75 @@ package Business::OnlinePayment::PaymentsGateway;
 
 use strict;
 use Carp;
-use Business::OnlinePayment
+use Business::OnlinePayment;
 use Net::SSLeay qw(sslcat);
 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $DEBUG);
 
 require Exporter;
 
-@ISA - qw( Exporter AutoLoader Business::OnlinePayment);
+@ISA = qw( Exporter AutoLoader Business::OnlinePayment);
 @EXPORT = qw();
 @EXPORT_OK = qw();
 $VERSION = '0.01';
 
 $DEBUG = 0;
 
+my %pg_response_code = (
+  'A01' => 'Transaction approved/completed',
+  'U01' => 'Merchant not allowed to access customer account',
+  'U02' => 'Customer account is in the ACH Direct "known bad" list',
+  'U03' => 'Merchant daily limit exceeded',
+  'U04' => 'Merchant monthly limit exceeded',
+  'U05' => 'AVS state/zipcode check failed',
+  'U06' => 'AVS state/area code check failed',
+  'U07' => 'AVS anonymous email check failed',
+  'U08' => 'Account has more transactions than the merchant\'s daily velocity'.
+           ' limit allows for',
+  'U09' => 'Account has more transactions than the merchant\'s velocity'.
+           ' window allows for',
+  'U10' => 'Transaction has the same attributes as another transaction'.
+           ' within the time set by the merchant',
+  'U11' => '(RECUR TRANS NOT FOUND) Transaction types 40-42 only',
+  'U12' => 'Original transaction not voidable or capture-able',
+  'U13' => 'Transaction to be voided or captured was not found',
+  'U14' => 'void/capture and original transaction types do not agree (CC/EFT)',
+  'U18' => 'Void or Capture failed',
+  #'U19' => 'Account ABA number if invalid',
+  'U19' => 'Account ABA number is invalid',
+  'U20' => 'Credit card number is invalid',
+  'U21' => 'Date is malformed',
+  'U22' => 'Swipe data is malformed',
+  'U23' => 'Malformed expiration date',
+  'U51' => 'Merchant is not "live"',
+  'U52' => 'Merchant not approved for transaction type (CC or EFT)',
+  'U53' => 'Transaction amount exceeds merchant\'s per transaction limit',
+  'U54' => 'Merchant\'s configuration requires updating ­ call customer'.
+           ' support',
+  'U80' => 'Transaction was declined due to preauthorization (ATM Verify)'.
+           ' result',
+  'U84' => 'Preauthorizer not responding',
+  'U85' => 'Preauthorizer error',
+  'U83' => 'Transaction was declined due to authorizer declination',
+  'U84' => 'Authorizer not responding',
+  'U85' => 'Authorizer error',
+  'U86' => 'Authorizer AVS check failed',
+  'F01' => 'Required field is missing',
+  'F03' => 'Name is not recognized',
+  'F04' => 'Value is not allowed',
+  'F05' => 'Field is repeated in message',
+  'F07' => 'Fields cannot both be present',
+  #'E10' => 'Merchant id or password in incorrect',
+  'E10' => 'Merchant id or password is incorrect',
+  'E20' => 'Transaction message not received (I/O flush required?)',
+  'E90' => 'Originating IP not on merchant\'s approved IP list',
+  'E99' => 'An unspecified error has occurred',
+);
+
 sub set_defaults {
   my $self = shift;
-  $self->server('');
-  $self->port( 5050 + 1000 * $self->test_transaction() );
-  #$self->build_subs();
+  $self->server('paymentsgateway.net');
+  $self->port( 5050 );
+  $self->build_subs(qw(test_transaction));
 }
 
 sub map_fields {
@@ -66,10 +117,10 @@ sub submit {
   my $self = shift;
   $self->map_fields();
 
-  my %content = $self->content();
+  #my %content = $self->content();
 
   $self->revmap_fields( 
-    'pg_merchant_id'                   => 'login',
+    'PG_MERCHANT_ID'                   => 'login',
     'pg_password'                      => 'password',
     'pg_transaction_type'              => \($self->transaction_type()),
     #'pg_merchant_data_1'
@@ -99,6 +150,7 @@ sub submit {
     'ecom_payment_check_account_type'  => \'C', #checking
     #'ecom_payment_check_checkno'       =>
   );
+  my %content = $self->content();
 
   # name (first_name & last_name ) ?
   # fax
@@ -107,49 +159,121 @@ sub submit {
 
   #account_number routing_code bank_name
 
-  my @fields = qw( pg_merchant_id pg_password pg_transaction_type ),
-               ( map { "pg_merchant_$_" } (1..9) ),
-               qw( pg_total_amount pg_sales_tax_amount pg_consumer_id
-                   ecom_consumerorderid ecom_walletid
-                   pg_billto_postal_name_company
-                   ecom_billto_postal_name_first ecom_billto_postal_name_last
-                   ecom_billto_postal_street_line1
-                   ecom_billto_postal_street_line2
-                   ecom_billto_postal_city ecom_billto_postal_stateprov
-                   ecom_billto_postal_postalcode ecom_billto_postal_countrycode
-                   ecom_billto_telecom_phone_number ecom_billto_online_email
-                   pg_billto_ssn pg_billto_dl_number pg_billto_dl_state
-               );
+  my @fields = (
+    qw( PG_MERCHANT_ID pg_password pg_transaction_type ),
+    ( map { "pg_merchant_$_" } ( 1 .. 9 ) ),
+    qw( pg_total_amount pg_sales_tax_amount pg_consumer_id
+        ecom_consumerorderid ecom_walletid
+        pg_billto_postal_name_company
+        ecom_billto_postal_name_first ecom_billto_postal_name_last
+        ecom_billto_postal_street_line1
+        ecom_billto_postal_street_line2
+        ecom_billto_postal_city ecom_billto_postal_stateprov
+        ecom_billto_postal_postalcode ecom_billto_postal_countrycode
+        ecom_billto_telecom_phone_number ecom_billto_online_email
+        pg_billto_ssn pg_billto_dl_number pg_billto_dl_state
+    )
+  );
 
   if ( $content{'type'} =~ /^check$/i ) {
     push @fields, qw( ecom_payment_check_trn
                       ecom_payment_check_account
                       ecom_payment_check_account_type );
   } else {
-    croak $content{$type}. ' not (yet) supported';
+    croak $content{'type'}. ' not (yet) supported';
   }
 
-  my $request = join("\n", map { "$_=$content{$_}" } @fields ). "\n";
+  my $request = join("\n", map { "$_=". $content{$_} }
+                           grep { $content{$_} ne '' }
+                           @fields                     ).
+                "\nendofdata\n";
+
+  warn $request if $DEBUG;
+
+  warn "TEST: ". $self->test_transaction(). "\n" if $DEBUG;
+
+  $self->port( $self->port() + 1000 ) if $self->test_transaction();
+
+  warn "SERVER ". $self->server(). "\n" if $DEBUG;
+  warn "PORT ". $self->port(). "\n" if $DEBUG;
 
   my $reply = sslcat( $self->server(), $self->port(), $request );
+  die "no reply from server" unless $reply;
 
-  my %response = map { /^(\w+)=(.*)$/
+  warn "reply from server: $reply\n" if $DEBUG;
+
+  my %response = map { /^(\w+)=(.*)$/ or /^(endofdata)()$/
                          or warn "can't parse response line: $_";
                        ($1, $2);
                      } split(/\n/, $reply);
 
   if ( $response{'pg_response_type'} eq 'A' ) {
     $self->is_success(1);
-    $self->response_code($response{'pg_response_code'});
+    $self->result_code($response{'pg_response_code'});
     $self->authorization($response{'pg_authorization_code'});
   } else {
     $self->is_success(0);
-    $self->response_code($response{'pg_response_code'});
-    $self->error_message($response{'pg_response_description'});
+    $self->result_code($response{'pg_response_code'});
+    $self->error_message( $pg_response_code{$response{'pg_response_code'}}.
+                          ': '. $response{'pg_response_description'} );
   }
 }
 
 1;
 
-#pod goes here
+__END__
+
+=head1 NAME
+
+Business::OnlinePayment::PaymentsGateway - PaymentsGateway.Net backend for Business::OnlinePayment
+
+=head1 SYNOPSIS
+
+  use Business::OnlinePayment;
+
+  my $tx = new Business::OnlinePayment("PaymentsGateway");
+  $tx->content(
+      type           => 'CHECK',
+      login          => 'test',
+      password       => 'test',
+      action         => 'Normal Authorization',
+      description    => 'Business::OnlinePayment test',
+      amount         => '49.95',
+      invoice_number => '100100',
+      name           => 'Tofu Beast',
+      account_number => '12345',
+      routing_code   => '123456789',
+      bank_name      => 'First National Test Bank',
+  );
+  $tx->submit();
+
+  if($tx->is_success()) {
+      print "Card processed successfully: ".$tx->authorization."\n";
+  } else {
+      print "Card was rejected: ".$tx->error_message."\n";
+  }
+
+=head1 DESCRIPTION
+
+For detailed information see L<Business::OnlinePayment>.
+
+=head1 NOTE
+
+This module only implements 'CHECK' (ACH) transactions at this time.  Credit
+card transactions are not (yet) supported.
+
+=head1 COMPATIBILITY
+
+This module implements the interface documented in the
+"PaymentsGateway.net Integration Guide, Version 2.1, September 2002"
+
+=head1 AUTHOR
+
+Ivan Kohler <ivan-paymentsgateway@420.am>
+
+=head1 SEE ALSO
+
+perl(1). L<Business::OnlinePayment>
+
+=cut
 
diff --git a/README b/README
index a02ad6a..212933f 100644 (file)
--- a/README
+++ b/README
@@ -10,9 +10,6 @@ have a merchant account with PaymentsGateway.net
 This module implements the interface documented in the
 "PaymentsGateway.net Integration Guide, Version 2.1, September 2002"
 
-There are additional tests in t2/ that may be useful to you once you have a
-login and password.
-
 Ivan Kohler <ivan-paymentsgateway@420.am>
 
 Business::OnlinePayment is a generic interface for processing payments through
diff --git a/t/bad_check.t b/t/bad_check.t
new file mode 100644 (file)
index 0000000..5aa127b
--- /dev/null
@@ -0,0 +1,32 @@
+BEGIN { $| = 1; print "1..1\n"; }
+
+use Business::OnlinePayment;
+
+my $ctx = new Business::OnlinePayment("PaymentsGateway");
+$ctx->content(
+    type           => 'CHECK',
+    login          => '2000',
+    password       => 'merchant4demo',
+    action         => 'Normal Authorization',
+    amount         => '49.95',
+    invoice_number => '100100',
+    customer_id    => 'jsk',
+    first_name     => 'Tofu',
+    last_name      => 'Beast',
+    account_number => '12345',
+    #account_number => 'badaccountnumber',
+    routing_code   => '123456789',
+    #routing_code   => 'badroutingcode',
+    bank_name      => 'First National Test Bank',
+);
+$ctx->test_transaction(1); # test, dont really charge
+$ctx->submit();
+
+print $ctx->is_success()."\n";
+
+if($ctx->is_success()) {
+    print "not ok 1\n";
+} else {
+    #warn $ctx->error_message();
+    print "ok 1\n";
+}
diff --git a/t/check.t b/t/check.t
new file mode 100644 (file)
index 0000000..00a9540
--- /dev/null
+++ b/t/check.t
@@ -0,0 +1,30 @@
+BEGIN { $| = 1; print "1..1\n"; }
+
+use Business::OnlinePayment;
+
+my $ctx = new Business::OnlinePayment("PaymentsGateway");
+$ctx->content(
+    type           => 'CHECK',
+    login          => '2000',
+    password       => 'merchant4demo',
+    action         => 'Normal Authorization',
+    amount         => '49.95',
+    invoice_number => '100100',
+    customer_id    => 'jsk',
+    first_name     => 'Tofu',
+    last_name      => 'Beast',
+    account_number => '12345',
+    routing_code   => '321076441',
+    bank_name      => 'First National Test Bank',
+);
+$ctx->test_transaction(1); # test, dont really charge
+$ctx->submit();
+
+print $ctx->is_success()."\n";
+
+if($ctx->is_success()) {
+    print "ok 1\n";
+} else {
+    warn $ctx->result_code. ': '. $ctx->error_message();
+    print "not ok 1 (".$ctx->error_message().")\n";
+}
diff --git a/t2/bad_check.t b/t2/bad_check.t
deleted file mode 100644 (file)
index 3ce505e..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-BEGIN { $| = 1; print "1..1\n"; }
-
-use Business::OnlinePayment;
-
-# checks are broken it seems
-my $ctx = new Business::OnlinePayment("PaymentsGateway");
-$ctx->content(
-    type           => 'CHECK',
-    login          => 'testing',
-    password       => 'testing',
-    action         => 'Normal Authorization',
-    amount         => '49.95',
-    invoice_number => '100100',
-    customer_id    => 'jsk',
-    first_name     => 'Tofu',
-    last_name      => 'Beast',
-    #account_number => '12345',
-    account_number => 'badaccountnumber',
-    #routing_code   => '123456789',
-    routing_code   => 'badroutingcode',
-    bank_name      => 'First National Test Bank',
-);
-$ctx->test_transaction(1); # test, dont really charge
-$ctx->submit();
-
-print $ctx->is_success()."\n";
-
-if($ctx->is_success()) {
-    print "not ok 1\n";
-} else {
-    #warn $ctx->error_message();
-    print "ok 1\n";
-}
diff --git a/t2/check.t b/t2/check.t
deleted file mode 100644 (file)
index e253e24..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-BEGIN { $| = 1; print "1..1\n"; }
-
-use Business::OnlinePayment;
-
-# checks are broken it seems
-my $ctx = new Business::OnlinePayment("PaymentsGateway");
-$ctx->content(
-    type           => 'CHECK',
-    login          => 'testing',
-    password       => 'testing',
-    action         => 'Normal Authorization',
-    amount         => '49.95',
-    invoice_number => '100100',
-    customer_id    => 'jsk',
-    first_name     => 'Tofu',
-    last_name      => 'Beast',
-    account_number => '12345',
-    routing_code   => '123456789',
-    bank_name      => 'First National Test Bank',
-);
-$ctx->test_transaction(1); # test, dont really charge
-$ctx->submit();
-
-print $ctx->is_success()."\n";
-
-if($ctx->is_success()) {
-    print "ok 1\n";
-} else {
-    print "not ok 1 (".$ctx->error_message().")\n";
-}