summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjeff <jeff>2006-11-21 21:35:42 +0000
committerjeff <jeff>2006-11-21 21:35:42 +0000
commit08916d3727cd4d463c06b2e595b4e38b3dcb358a (patch)
tree2b847f2b75967e0d9af8b6fe481e8cd5beff52bb
Initial importstart
-rw-r--r--MANIFEST5
-rw-r--r--Makefile.PL13
-rw-r--r--README0
-rw-r--r--USAePay.pm213
-rw-r--r--t/USAePay.t863
5 files changed, 1094 insertions, 0 deletions
diff --git a/MANIFEST b/MANIFEST
new file mode 100644
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
index 0000000..6241c05
--- /dev/null
+++ b/Makefile.PL
@@ -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
index 0000000..e69de29
--- /dev/null
+++ b/README
diff --git a/USAePay.pm b/USAePay.pm
new file mode 100644
index 0000000..0ebaf57
--- /dev/null
+++ b/USAePay.pm
@@ -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
index 0000000..7ce6947
--- /dev/null
+++ b/t/USAePay.t
@@ -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}, "");
+
+