From 08916d3727cd4d463c06b2e595b4e38b3dcb358a Mon Sep 17 00:00:00 2001 From: jeff Date: Tue, 21 Nov 2006 21:35:42 +0000 Subject: [PATCH] Initial import --- MANIFEST | 5 + Makefile.PL | 13 + README | 0 USAePay.pm | 213 +++++++++++++++ t/USAePay.t | 863 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1094 insertions(+) create mode 100644 MANIFEST create mode 100644 Makefile.PL create mode 100644 README create mode 100644 USAePay.pm create mode 100644 t/USAePay.t 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 ', + '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 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. + +=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 + +=head1 SEE ALSO + +perl(1). L. + +=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}, ""); + + -- 2.11.0