Initial import start
authorjeff <jeff>
Tue, 21 Nov 2006 21:35:42 +0000 (21:35 +0000)
committerjeff <jeff>
Tue, 21 Nov 2006 21:35:42 +0000 (21:35 +0000)
MANIFEST [new file with mode: 0644]
Makefile.PL [new file with mode: 0644]
README [new file with mode: 0644]
USAePay.pm [new file with mode: 0644]
t/USAePay.t [new file with mode: 0644]

diff --git a/MANIFEST b/MANIFEST
new file mode 100644 (file)
index 0000000..6a61271
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,5 @@
+Makefile.PL
+MANIFEST
+README
+USAePay.pm
+t/USAePay.t
diff --git a/Makefile.PL b/Makefile.PL
new file mode 100644 (file)
index 0000000..6241c05
--- /dev/null
@@ -0,0 +1,13 @@
+use ExtUtils::MakeMaker;
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+WriteMakefile(
+    'NAME'         => 'Business::OnlinePayment::USAePay',
+    'VERSION_FROM' => 'USAePay.pm', # finds $VERSION
+    'AUTHOR'       => 'Jeff Finucane <jeff@cmh.net>',
+    'PREREQ_PM'    => { 
+                        'Business::OnlinePayment' => 3,
+                        'Business::OnlinePayment::HTTPS' => 0.04,
+                        'Business::CreditCard' => 0.27,
+                      },
+);
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/USAePay.pm b/USAePay.pm
new file mode 100644 (file)
index 0000000..0ebaf57
--- /dev/null
@@ -0,0 +1,213 @@
+package Business::OnlinePayment::USAePay;
+
+use strict;
+use Carp;
+use Business::OnlinePayment 3;
+use Business::OnlinePayment::HTTPS;
+use Digest::MD5 qw(md5_hex);
+use URI::Escape;
+use vars qw($VERSION @ISA $DEBUG);
+
+@ISA = qw(Business::OnlinePayment::HTTPS);
+$VERSION = '0.01';
+
+$DEBUG = 1;
+
+my $default_path = '/gate.php';
+my $default_cert_path = '/secure/gate.php';
+
+sub set_defaults {
+    my $self = shift;
+    $self->server('www.usaepay.com');
+    $self->port('443');
+    $self->path($default_path);
+
+    $self->build_subs(qw(order_number));
+}
+
+sub map_fields {
+  my($self) = shift;
+
+  my %content = $self->content();
+
+  my %types = ('visa'             => 'CC',
+               'mastercard'       => 'CC',
+               'american express' => 'CC',
+               'discover'         => 'CC',
+               'check'            => 'ECHECK',
+              );
+  $content{'type'} = $types{lc($content{'type'})} || $content{'type'};
+  $self->transaction_type($content{'type'});
+
+  my %actions;
+  my %cc_actions = ('normal authorization' => 'sale',
+                    'authorization only'   => 'authonly',
+                    'post authorization'   => 'postauth',
+                   );
+  my %ec_actions = ('normal authorization' => 'check',
+                    'credit'               => 'checkcredit',
+                   );
+  if ($content{'type'} eq 'CC') {
+    (%actions) = (%cc_actions);
+  }elsif ($content{'type'} eq 'ECHECK') {
+    (%actions) = (%ec_actions);
+  }
+  $content{'action'} = $actions{lc($content{'action'})} || $content{'action'};
+                 
+  $content{'expiration'} =~ s/\D//g;
+
+  $content{'md5hash'} = md5_hex(join(':', map "$content{$_}", qw(action password amount invoice_number md5key))) if defined $content{'password'};
+
+  $self->content(%content);
+}
+
+sub submit {
+    my($self) = @_;
+
+    $self->map_fields();
+
+    $self->remap_fields(
+      login            => 'UMkey',
+      md5key           => 'UMmd5key',
+      md5hash          => 'UMmd5hash',
+      card_number      => 'UMcard',
+      expiration       => 'UMexpir',
+      amount           => 'UMamount',
+      invoice_number   => 'UMinvoice',
+      description      => 'UMdescription',
+      customer_id      => 'UMcustid',
+      cvv2             => 'UMcvv2',
+      email            => 'UMcustemail',
+      name             => 'UMname',
+      address          => 'UMstreet',
+      zip              => 'UMzip',
+      customer_ip      => 'UMip',
+      order_number     => 'UMrefNum',
+      authorization    => 'UMauthCode',
+      routing_code     => 'UMrouting',
+      account_number   => 'UMaccount',
+      customer_ssn     => 'UMssn',
+    );
+    my %content = $self->content;
+    if ( $DEBUG ) {
+      warn "content:$_ => $content{$_}\n" foreach keys %content;
+    }
+
+    my @required_fields = qw(type action login);
+
+    if ($self->transaction_type() eq 'CC' ) {
+      push @required_fields, qw/card_number expiration amount invoice_number name address zip/;
+      if ($self->{_content}->{action} eq 'postauth') {
+        push @required_fields, qw/authorization/;
+      }
+      if (    $self->{_content}->{action} eq 'void'
+           || $self->{_content}->{action} eq 'capture') {
+        push @required_fields, qw/order_number/;
+      }
+    }elsif ($self->transaction_type() eq 'ECHECK' ) {
+      push @required_fields, qw/routing_code account_number amount invoice_number name customer_ssn/;
+    } else {
+      croak("USAePay can't handle transaction type: ".
+            $self->transaction_type());
+    }
+
+    $self->required_fields(@required_fields);
+
+    my %post_data = $self->get_fields( map "$_", qw(
+      UMcommand UMkey UMmd5hash UMmd5key UMauthCode UMrefNum UMcard UMexpir
+      UMrouting UMaccount UMamount Umtax UMnontaxable UMtip UMshipping
+      UMdiscount UMsubtotal UMcustid UMinvoice UMorderid UMponum UMdescription
+      UMcvv2 UMcustemail UMcustreceipt UMname UMStreet UMzip UMssn UMdlnum
+      UMdlstate UMclerk UMterminal UMtable UMip UMsoftware UMredir
+      UMredirApproved UMredirDeclined UMechofields UMtestmode
+    ) );
+    $post_data{'UMtestmode'} = $self->test_transaction() ? 1 : 0;
+    $post_data{'UMsoftware'} = __PACKAGE__. " $VERSION";
+    if ( $DEBUG ) {
+      warn "post_data:$_ => $post_data{$_}\n" foreach keys %post_data;
+    }
+
+    my($page,$server_response) = $self->https_post(%post_data);
+    if ( $DEBUG ) {
+      warn "response page: $page\n";
+    }
+
+    my $response;
+    if ($server_response =~ /200/){
+      $response = {map { split '=', $_, 2 } split '&', $page};
+    }else{
+      $response->{UMstatus} = 'Error';
+      $response->{UMerror} = $server_response;
+    }
+
+    $response->{$_} =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg
+      foreach keys %$response;
+
+    if ( 1 || $DEBUG ) {
+      warn "response:$_ => $response->{$_}\n" foreach keys %$response;
+    }
+
+    if ( $response->{UMstatus} =~ /^Approved/ ) {
+      $self->is_success(1);
+      $self->authorization($response->{UMauthCode});
+    } else {
+      $self->is_success(0);
+    }
+    $self->result_code($response->{UMresult});
+    $self->error_message($response->{UMerror});
+    $self->server_response($response);
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Business::OnlinePayment::USAePay - USA ePay backend for Business::OnlinePayment
+
+=head1 SYNOPSIS
+
+  use Business::OnlinePayment;
+
+  my $tx = new Business::OnlinePayment("USAePay");
+  $tx->content(
+      login          => 'igztOatyqbpd1wsxijl4xnxjodldwdxR', #USA ePay source key
+      action         => 'Normal Authorization',
+      description    => 'Business::OnlinePayment test',
+      amount         => '49.95',
+      invoice_number => '100100',
+      name           => 'Tofu Beast',
+      card_number    => '46464646464646',
+      expiration     => '11/08',
+      address        => '1234 Bean Curd Lane, San Francisco',
+      zip            => '94102',
+  );
+  $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
+
+=head1 COMPATIBILITY
+
+This module implements USAePay's CGI Gateway API v2.9.5.  See
+http://www.usaepay.com/topics/api.html for details.
+
+=head1 AUTHOR
+
+Jeff Finucane <jeff@cmh.net>
+
+=head1 SEE ALSO
+
+perl(1). L<Business::OnlinePayment>.
+
+=cut
+
diff --git a/t/USAePay.t b/t/USAePay.t
new file mode 100644 (file)
index 0000000..7ce6947
--- /dev/null
@@ -0,0 +1,863 @@
+# Before `make install' is performed this script should be runnable with
+# `make test'. After `make install' it should work as `perl eWay.t'
+
+use Test;
+BEGIN { plan tests => 391, todo => [379,380,382] };
+use Business::OnlinePayment::USAePay;
+
+# a test transaction
+my ($tx, $txnum, $res);
+ok($tx = new Business::OnlinePayment("USAePay"));
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4005562233445564',
+        expiration     => '11/08',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($res = $tx->server_response());
+ok($txnum = $res->{UMauthCode});
+ok($res->{UMavsResultCode}, "YYY");
+ok($res->{UMresult}, "A");
+ok($res->{UMcvv2Result}, "Not Processed");
+ok($res->{UMversion}, "2.9");
+ok($res->{UMavsResult}, "Address: Match & 5 Digit Zip: Match");
+ok($res->{UMrefNum}, qr/^\d+/);
+ok($res->{UMbatch}, qr/^\d+/);
+ok($res->{UMerrorcode}, "00000");
+ok($res->{UMvpasResultCode}, "");
+ok($res->{UMcvv2ResultCode}, "P");
+
+#resubmit test
+ok($tx->submit());
+ok(($tx->server_response->{UMauthCode} - $txnum) > 0);
+
+# a test transaction with cvn
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4005562233445564',
+        expiration     => '11/08',
+       cvv2           => '123',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMcvv2Result}, "Not Processed");
+
+# a failing transaction
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        first_name     => 'Tofu',
+        last_name      => 'Beast',
+        email          => 'tofu@example.com',
+        address        => '1234 Bean Curd Lane, Sydney',
+        zip            => '2034',
+        card_number    => '4646464646464646',
+        expiration     => '11/08',
+       cvv2           => '123',
+    )
+);
+ok($tx->test_transaction(0),0);
+ok($tx->submit());
+ok($tx->is_success(),0);
+ok($tx->error_message(), 'Invalid Card Number (3)');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMcvv2Result}, "No CVV2/CVC data available for transaction.");
+
+#various test cards; semi-useful testing
+#Full match avs, zip9 & cvv2
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000100011112224',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "YYY");
+ok($tx->server_response->{UMresult}, "A");
+ok($tx->server_response->{UMcvv2Result}, "Match");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "Address: Match & 5 Digit Zip: Match");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00000");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+
+#Full match avs, zip9 & cvv2
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000100111112223',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "YYX");
+ok($tx->server_response->{UMresult}, "A");
+ok($tx->server_response->{UMcvv2Result}, "Match");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "Address: Match & 9 Digit Zip: Match");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00000");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "M");
+
+#no match avs, match zip5 & cvv2
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000100211112222',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "NYZ");
+ok($tx->server_response->{UMresult}, "A");
+ok($tx->server_response->{UMcvv2Result}, "Match");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "Address: No Match & 5 Digit Zip: Match");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00000");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "M");
+
+# no match address, match zip9 & cvv2
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000100311112221',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "NYW");
+ok($tx->server_response->{UMresult}, "A");
+ok($tx->server_response->{UMcvv2Result}, "Match");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "Address: No Match & 9 Digit Zip: Match");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00000");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "M");
+
+# match address, no match zip5 & match cvv2
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000100411112220',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "YNA");
+ok($tx->server_response->{UMresult}, "A");
+ok($tx->server_response->{UMcvv2Result}, "Match");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "Address: Match & 5 Digit Zip: No Match");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00000");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "M");
+
+# no match address, zip5 & match cvv2
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000100511112229',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "NNN");
+ok($tx->server_response->{UMresult}, "A");
+ok($tx->server_response->{UMcvv2Result}, "Match");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "Address: No Match & 5 Digit Zip: No Match");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00000");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "M");
+
+# card number not on avs file
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000100611112228',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "XXW");
+ok($tx->server_response->{UMresult}, "A");
+ok($tx->server_response->{UMcvv2Result}, "Match");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "Card Number Not On File");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00000");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "M");
+
+# not verified
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000100711112227',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "XXU");
+ok($tx->server_response->{UMresult}, "A");
+ok($tx->server_response->{UMcvv2Result}, "Match");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "Address Information not verified for domestic transaction");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00000");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "M");
+
+# retry avs   
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000100811112226',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "XXR");
+ok($tx->server_response->{UMresult}, "A");
+ok($tx->server_response->{UMcvv2Result}, "Match");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "Retry / System Unavailable");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00000");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "M");
+
+# avs not supported
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000100911112225',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "XXS");
+ok($tx->server_response->{UMresult}, "A");
+ok($tx->server_response->{UMcvv2Result}, "Match");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "Service Not Support");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00000");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "M");
+
+# avs not allowed for card type
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000101011112222',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "XXE");
+ok($tx->server_response->{UMresult}, "A");
+ok($tx->server_response->{UMcvv2Result}, "Match");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "Address Verification Not Allowed For Card Type");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00000");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "M");
+
+# global non-avs participant
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000101111112221',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "XXG");
+ok($tx->server_response->{UMresult}, "A");
+ok($tx->server_response->{UMcvv2Result}, "Match");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "Global Non-AVS participant");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00000");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "M");
+
+# international address match, zip incompat
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000101211112220',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "YYG");
+ok($tx->server_response->{UMresult}, "A");
+ok($tx->server_response->{UMcvv2Result}, "Match");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "International Address: Match & Zip: Not Compatible");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00000");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "M");
+
+# international address match, zip 
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000101311112229',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "GGG");
+ok($tx->server_response->{UMresult}, "A");
+ok($tx->server_response->{UMcvv2Result}, "Match");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "International Address: Match & Zip: Match");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00000");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "M");
+
+# international address Not compat & match, zip 
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000101411112228',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "YGG");
+ok($tx->server_response->{UMresult}, "A");
+ok($tx->server_response->{UMcvv2Result}, "Match");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "International Address: No Compatible & Zip: Match");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00000");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "M");
+
+# full match, avs & match, zip 
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000200011112222',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "YYY");
+ok($tx->server_response->{UMresult}, "A");
+ok($tx->server_response->{UMcvv2Result}, "Match");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "Address: Match & 5 Digit Zip: Match");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00000");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "M");
+
+# match avs & no match cvv2
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000200111112221',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "YYY");
+ok($tx->server_response->{UMresult}, "A");
+ok($tx->server_response->{UMcvv2Result}, "No Match");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "Address: Match & 5 Digit Zip: Match");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00000");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "N");
+
+# match avs & not processed cvv2
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000200211112220',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "YYY");
+ok($tx->server_response->{UMresult}, "A");
+ok($tx->server_response->{UMcvv2Result}, "Not Processed");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "Address: Match & 5 Digit Zip: Match");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00000");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "P");
+
+# match avs & fault in cvv2 database
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000200311112229',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success(),0);
+ok($tx->error_message(), 'Card Declined');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "YYY");
+ok($tx->server_response->{UMresult}, "D");
+ok($tx->server_response->{UMcvv2Result}, "Should be on card but not so indicated");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "Address: Match & 5 Digit Zip: Match");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "10127");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "S");
+
+# match avs & issuer not certified for cvv2
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000200411112228',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "YYY");
+ok($tx->server_response->{UMresult}, "A");
+ok($tx->server_response->{UMcvv2Result}, "Issuer Not Certified");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "Address: Match & 5 Digit Zip: Match");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00000");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "U");
+
+# match avs & no response for cvv2
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000200511112227',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "YYY");
+ok($tx->server_response->{UMresult}, "A");
+ok($tx->server_response->{UMcvv2Result}, "No response from association");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "Address: Match & 5 Digit Zip: Match");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00000");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "X");
+
+# hard decline
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000300011112220',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success(),0);
+ok($tx->error_message(), 'Card Declined');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "YYY");
+ok($tx->server_response->{UMresult}, "D");
+ok($tx->server_response->{UMcvv2Result}, "Not Processed");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "Address: Match & 5 Digit Zip: Match");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "10127");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "P");
+
+# referral
+ok(
+    $tx->content(
+        type           => 'CC',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        card_number    => '4000300111112229',
+        expiration     => '09/09',
+        address        => '1234 Bean Curd Lane, San Francisco',
+        zip            => '94102',
+        cvv2           => '102',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success(),0);
+ok($tx->error_message(), 'Transaction Requires Voice Authentication. Please Call-In.');
+ok($tx->authorization(), '/\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "YYY");
+ok($tx->server_response->{UMresult}, "E");
+ok($tx->server_response->{UMcvv2Result}, "Not Processed");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "Address: Match & 5 Digit Zip: Match");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00043");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "P");
+
+# check
+ok(
+    $tx->content(
+        type           => 'ECHECK',
+        login          => 'yCaWGYQsSVR0S48B6AKMK07RQhaxHvGu', #test platform
+        action         => 'Normal Authorization',
+        description    => 'Business::OnlinePayment test',
+        amount         => '49.95',
+        invoice_number => '100100',
+        name           => 'Tofu Beast',
+        routing_code   => '400020001',
+        account_number => '1112222',
+        customer_ssn   => '999999999',
+        address        => '1234 Bean Curd Lane, San Francisco',
+    )
+);
+ok($tx->submit());
+ok($tx->is_success());
+ok($tx->error_message(), 'Approved');
+ok($tx->authorization(), '/^\d{6}/');
+ok($tx->server_response->{UMavsResultCode}, "YYY");
+ok($tx->server_response->{UMresult}, "E");
+ok($tx->server_response->{UMcvv2Result}, "No CVV2/CVC data available for transaction.");
+ok($tx->server_response->{UMversion}, "2.9");
+ok($tx->server_response->{UMavsResult}, "n/a");
+ok($tx->server_response->{UMrefNum}, qr/^\d+/);
+ok($tx->server_response->{UMerrorcode}, "00011");
+ok($tx->server_response->{UMbatch}, qr/^\d+/);
+ok($tx->server_response->{UMvpasResultCode}, "");
+ok($tx->server_response->{UMcvv2ResultCode}, "");
+
+