From 6d0e232586bb93244951a46844e28a0828ce872a Mon Sep 17 00:00:00 2001 From: jeff Date: Thu, 17 May 2007 23:52:19 +0000 Subject: [PATCH] make ACH work, more tests --- Changes | 7 ++ MANIFEST | 2 + META.yml | 3 +- Makefile.PL | 1 + TransFirsteLink.pm | 55 +++++++++++--- t/credit_card.t | 75 ++++++------------- t/echeck.t | 58 +++++++-------- t/live_card.t | 210 +++++++++++++++++++++++++++++++++++++++++++++++++++++ t/live_check.t | 120 ++++++++++++++++++++++++++++++ 9 files changed, 437 insertions(+), 94 deletions(-) create mode 100644 t/live_card.t create mode 100644 t/live_check.t diff --git a/Changes b/Changes index 9c28ff8..6d07a9e 100644 --- a/Changes +++ b/Changes @@ -1,4 +1,11 @@ Revision history for Perl extension Business::OnlinePayment::TransFirsteLink. +0.02 Wed May 17 19:19:10 EDT 2007 + - more tests + - make echeck conform to behavior rather than documentation + - hush warnings where appropriate + - transfirst indicates query order is significant, so order + hashes with Tie::IxHash (testing seems to indicate order unimportant) + 0.01 Wed Apr 29 07:55:25 EDT 2007 - original version; created by jeff diff --git a/MANIFEST b/MANIFEST index 6ee934e..94180f3 100644 --- a/MANIFEST +++ b/MANIFEST @@ -7,6 +7,8 @@ t/00load.t t/bop.t t/credit_card.t t/echeck.t +t/live_card.t +t/live_check.t t/pod.t t/pod-coverage.t META.yml Module meta-data (added by MakeMaker) diff --git a/META.yml b/META.yml index 91619fc..bd93942 100644 --- a/META.yml +++ b/META.yml @@ -1,12 +1,13 @@ # http://module-build.sourceforge.net/META-spec.html #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# name: Business-OnlinePayment-TransFirsteLink -version: 0.01 +version: 0.02 version_from: TransFirsteLink.pm installdirs: site requires: Business::OnlinePayment: 3 Business::OnlinePayment::HTTPS: 0.05 + Tie::IxHash: 0 distribution_type: module generated_by: ExtUtils::MakeMaker version 6.17 diff --git a/Makefile.PL b/Makefile.PL index 0469740..4ee8933 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -8,6 +8,7 @@ WriteMakefile( PREREQ_PM => { Business::OnlinePayment => '3', Business::OnlinePayment::HTTPS => '0.05', + Tie::IxHash => '0', }, ( $] >= 5.005 diff --git a/TransFirsteLink.pm b/TransFirsteLink.pm index c5dcfe6..80cc4c2 100644 --- a/TransFirsteLink.pm +++ b/TransFirsteLink.pm @@ -3,10 +3,11 @@ package Business::OnlinePayment::TransFirsteLink; use strict; use vars qw($VERSION $DEBUG %error_messages); use Carp qw(carp croak); +use Tie::IxHash; use base qw(Business::OnlinePayment::HTTPS); -$VERSION = '0.01'; +$VERSION = '0.02'; $VERSION = eval $VERSION; $DEBUG = 0; @@ -325,8 +326,8 @@ sub submit { my %content = $self->content; my %required; - $required{CC_20} = [ qw( ePayAccountNum Password OrderNumber - TransactionAmount AccountNumber ExpirationDate + $required{CC_20} = [ qw( ePayAccountNum Password OrderNum + TransactionAmount CardAccountNum ExpirationDate MerchantCustServNum ) ]; $required{CC_30} = [ qw( ePayAccountNum Password TransactionCode OrderNum TransactionAmount CardAccountNum ExpirationDate @@ -336,7 +337,7 @@ sub submit { ReferenceNum ) ]; $required{ECHECK_20} = [ qw( ePayAccountNum Password AccountNumber RoutingNumber DollarAmount OrderNumber - CustomerNumber ) ]; + CustomerNumber CustomerName ) ]; $required{ECHECK_32} = [ qw( ePayAccountNum Password OrderNumber AccountNumber RoutingNumber CheckNumber DollarAmount CustomerName CustomerAddress @@ -406,6 +407,7 @@ sub submit { RoutingNumber => 'routing_code', AccountNumber => \$account_number, + AccountNum => \$account_number, CheckNumber => \$check_number, CardHolderName => 'name', @@ -431,15 +433,21 @@ sub submit { ReferenceNum => 'order_number' ); - my %params = $self->get_fields( @{$required{$type_action}}, - @{$optional{$type_action}}, - ); + tie my %params, 'Tie::IxHash', + $self->get_fields( @{$required{$type_action}}, + @{$optional{$type_action}}, + ); $params{TestTransaction}='Y' if $self->test_transaction; $params{InstallmentNum} = $params{InstallmentOf} = '01' unless ($params{InstallmentNum} && $params{InstallmentOf}); + if ($self->transaction_type() eq 'ECHECK') { + delete $params{InstallmentNum}; + delete $params{InstallmentOf}; + } + if ( $type_action eq "CC_30" || $type_action eq "CC_32" ) { $self->path($self->path."elink/authpd.asp"); } elsif ( $type_action eq "CC_61" ) { @@ -468,13 +476,14 @@ sub submit { $self->required_fields(@{$required{$type_action}}); my $status =''; + my @rarray = (); if ( $type_action eq "CC_30" || $type_action eq "CC_32" ) { my ($format,$account,$tcode,$seq,$moi,$cardnum,$exp,$authamt,$authdate, $authtime,$tstat,$custnum,$ordernum,$refnum,$rcode,$authsrc,$achar, $transid,$vcode,$sic,$country,$avscode,$storenum,$cvv2resp,$cavvcode, $crossrefnum,$etstat,$cavvresponse,$xid,$eci,@junk) - = split '\|', $page; + = split '\|', $page; # AVS and CVS values may be set on success or failure $self->avs_code($avscode); @@ -485,30 +494,52 @@ sub submit { $self->junk( \@junk ); $self->error_message($error_messages{$status}); + } elsif ( $type_action eq "CC_61" ) { - my ($format,$account,$tcode,$voidamt,$seq,$voiddate,$voidtime,$tstat, + $self->avs_code(''); + $self->cvv2_response(''); + my ($format,$account,$tcode,$seq,$voiddate,$voidtime,$tstat, # flaky docs $refnum,$filler1,$filler2,$filler3,$etstat,@junk) = split '\|', $page; $self->result_code( $status = $etstat ); $self->order_number( $refnum ); + $self->authorization(''); $self->junk( \@junk ); $self->error_message($error_messages{$status}); } elsif ( $type_action eq "CC_20" ) { + $self->avs_code(''); + $self->cvv2_response(''); my ($format,$account,$tcode,$seq,$moi,$authamt,$authdate,$authtime, $tstat,$refnum,$crossrefnum,$custnum,$ordernum,$etstat,@junk) = split '\|', $page; $self->result_code( $status = $etstat ); $self->order_number( $refnum ); + $self->authorization(''); $self->junk( \@junk ); $self->error_message($error_messages{$status}); - } elsif ( $type_action eq "ECHECK_32" || $type_action eq "ECHECK_20" ) { + } elsif ( $type_action eq "ECHECK_32" ) { my ($responsecode,$response,$transactionid,$note,$errors,@junk) = split '\|', $page; - # AVS and CVS values may be set on success or failure + $self->avs_code(''); + $self->cvv2_response(''); $self->result_code( $status = $responsecode ); $self->order_number( $transactionid ); + $self->authorization(''); + $errors = $errors ? $errors : ''; + $self->error_message("$response $errors"); + $self->junk( \@junk ); + + } elsif ( $type_action eq "ECHECK_20" ) { + my ($response,$transactionid,$note,$errors,@junk) # very flaky docs + = split '\|', $page; + $self->avs_code(''); + $self->cvv2_response(''); + $self->result_code( $status = $response ); + $self->order_number( $transactionid ); + $self->authorization(''); + $errors = $errors ? $errors : ''; $self->error_message("$response $errors"); $self->junk( \@junk ); @@ -516,7 +547,7 @@ sub submit { croak "can't interpret response for unexpected type and action $type_action"; } - if ( $resp eq "200" && ($status eq "000" || $status eq "011" || $status eq "085" || $status eq "0P0" || $status eq "P00") ) { + if ( $resp eq "200" && ($status eq "000" || $status eq "011" || $status eq "085" || $status eq "0P0" || $status eq "P00" || $status eq 'ACCEPTED') ) { $self->is_success(1); } else { diff --git a/t/credit_card.t b/t/credit_card.t index fe04da2..83e9eb5 100644 --- a/t/credit_card.t +++ b/t/credit_card.t @@ -13,7 +13,7 @@ my $runinfo = plan( ( $ENV{"ELINK_ACCOUNT"} && $ENV{"ELINK_PASSWORD"} ) - ? ( tests => 70 ) + ? ( tests => 56 ) : ( skip_all => $runinfo ) ); @@ -75,97 +75,68 @@ my %content = ( SKIP: { # avs_code() / AVSZIP and AVSADDR tests - skip "AVS tests broken", 28; + skip "AVS tests broken", 21; my $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); - # IF first 3 chars of STREET <= 334 and >= 666 THEN AVSADDR == "N" $tx->content( %content, "address" => "500 Any street" ); tx_check( $tx, desc => "AVSADDR=N,AVSZIP=Y", - is_success => 0, - result_code => 126, - authorization => "010101", - avs_code => "Z", - cvv2_response => "Y", - ); - - # IF first 3 chars of STREET >= 667 THEN AVSADDR == "X" (and AVSZIP="X") - $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); - $tx->content( %content, "address" => "700 Any street" ); - tx_check( - $tx, - desc => "AVSADDR=X,AVSZIP=X", is_success => 1, - result_code => 0, - authorization => "010101", - avs_code => "", - cvv2_response => "Y", + result_code => "000", + authorization => "999999", + avs_code => "Z", + cvv2_response => "M", ); -# # IF ZIP <= 50001 and >= 99999 THEN AVSZIP == "N" $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); $tx->content( %content, "zip" => "99999" ); tx_check( $tx, desc => "AVSADDR=Y,AVSZIP=N", - is_success => 0, - result_code => 126, - authorization => "010101", + is_success => 1, + result_code => "000", + authorization => "999999", avs_code => "A", - cvv2_response => "Y", + cvv2_response => "M", ); - # Both AVSADDR and AVSZIP == "N" $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); $tx->content( %content, "address" => "500 Any street", "zip" => "99999" ); tx_check( $tx, desc => "AVSADDR=N,AVSZIP=N", - is_success => 0, - result_code => 126, - authorization => "010101", + is_success => 1, + result_code => "000", + authorization => "999999", avs_code => "N", - cvv2_response => "Y", + cvv2_response => "M", ); } SKIP: { # cvv2_response() / CVV2MATCH - skip "CVV2 tests broken", 14; + skip "CVV2 tests broken", 7; my $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); - # IF CVV2 >= 301 and <= 600 THEN CVV2MATCH == "N" $tx->content( %content, "cvv2" => "301" ); tx_check( $tx, - desc => "cvv2(301)", - is_success => 0, - result_code => 126, - authorization => "010101", + desc => "wrong cvv2", + is_success => 1, + result_code => "000", + authorization => "999999", avs_code => "Y", cvv2_response => "N", ); - # IF CVV2 >= 601 THEN CVV2MATCH == "X" - $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); - $tx->content( %content, "cvv2" => "601" ); - tx_check( - $tx, - desc => "cvv2(601)", - is_success => 0, - result_code => 126, - authorization => "010101", - avs_code => "Y", - cvv2_response => "X", - ); } SKIP: { # refund test - skip "credit/refund tests broken", 7; + #skip "credit/refund tests broken", 7; my $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); $tx->content( %content, 'action' => "Credit", @@ -174,7 +145,7 @@ SKIP: { # refund test tx_check( $tx, desc => "refund/credit", - is_success => 0, + is_success => 1, result_code => "000", authorization => '', avs_code => '', @@ -184,7 +155,7 @@ SKIP: { # refund test SKIP: { # void test - skip "void tests broken", 7; + #skip "void tests broken", 7; my $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); $tx->content( %content, 'action' => "Void", @@ -193,7 +164,7 @@ SKIP: { # void test tx_check( $tx, desc => "void", - is_success => 0, + is_success => 1, result_code => "000", authorization => '', avs_code => '', diff --git a/t/echeck.t b/t/echeck.t index 2d3de74..386efee 100644 --- a/t/echeck.t +++ b/t/echeck.t @@ -9,10 +9,18 @@ use Business::OnlinePayment; my $runinfo = "to test set environment variables:" - . " (required) ELINK_ACH_ACCOUNT and ELINK_ACH_PASSWORD"; + . " (required) ELINK_ACH_ACCOUNT, ELINK_ACH_PASSWORD" + . " ELINK_ROUTING_CODE, ELINK_BANK_ACCOUNT, ELINK_ACH_NAME" + . " ELINK_ACH_ADDRESS, ELINK_ACH_CITY, ELINK_ACH_STATE" + . " ELINK_ACH_ZIP, ELINK_ACH_PHONE"; plan( - ( $ENV{"ELINK_ACH_ACCOUNT"} && $ENV{"ELINK_ACH_PASSWORD"} ) + ( $ENV{"ELINK_ACH_ACCOUNT"} && $ENV{"ELINK_ACH_PASSWORD"} && + $ENV{"ELINK_ROUTING_CODE"} && $ENV{"ELINK_BANK_ACCOUNT"} && + $ENV{"ELINK_ACH_NAME"} && $ENV{"ELINK_ACH_ADDRESS"} && + $ENV{"ELINK_ACH_CITY"} && $ENV{"ELINK_ACH_STATE"} && + $ENV{"ELINK_ACH_ZIP"} && $ENV{"ELINK_ACH_PHONE"} + ) ? ( tests => 12 ) : ( skip_all => $runinfo ) ); @@ -27,23 +35,19 @@ my %content = ( password => $ENV{"ELINK_ACH_PASSWORD"}, action => "Normal Authorization", type => "CHECK", - description => "Business::OnlinePayment::TransFirsteLink test", - routing_code => "052000113", - account_number => "000000000001", - check_number => "100", - cvv2 => "123", - expiration => "12/" . strftime( "%y", localtime ), - amount => "0.01", - invoice_number => "1999", - account_name => "Tofu Beast", - customer_id => "TB01", - email => 'transfirst@weasellips.com', - address => "123 Anystreet", - city => "Anywhere", - state => "GA", - zip => "30004", - country => "US", - phone => "4045551212", + description => "Business::OnlinePayment::TransFirsteLink live test", + routing_code => $ENV{"ELINK_ROUTING_CODE"}, + account_number => $ENV{"ELINK_BANK_ACCOUNT"}, + check_number => "99", + amount => "1.01", + invoice_number => "LiveTest", + customer_id => "LiveTestCust", + account_name => $ENV{"ELINK_ACH_NAME"}, + address => $ENV{"ELINK_ACH_ADDRESS"}, + city => $ENV{"ELINK_ACH_CITY"}, + state => $ENV{"ELINK_ACH_STATE"}, + zip => $ENV{"ELINK_ACH_ZIP"}, + phone => $ENV{"ELINK_ACH_PHONE"}, ); { # valid account test @@ -57,9 +61,7 @@ my %content = ( ); } -SKIP: { # invalid account test - - skip "invalid account tests broken", 4; +{ # invalid account test my $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); $tx->content( %content, routing_code => "052000113", @@ -70,13 +72,11 @@ SKIP: { # invalid account test $tx, desc => "invalid account", is_success => 0, - result_code => 214, + result_code => 'D10', ); } -SKIP: { # credit/refund test - - skip "credit/refund tests broken", 4; +{ # credit/refund test my $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); $tx->content( %content, action => "Credit"); @@ -84,15 +84,15 @@ SKIP: { # credit/refund test tx_check( $tx, desc => "credit/refund", - is_success => 0, - result_code => "P00", + is_success => 1, + result_code => "ACCEPTED", ); } sub tx_check { my $tx = shift; my %o = @_; - + $tx->test_transaction(1); $tx->submit; diff --git a/t/live_card.t b/t/live_card.t new file mode 100644 index 0000000..3dd5a63 --- /dev/null +++ b/t/live_card.t @@ -0,0 +1,210 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use POSIX qw(strftime); +use Test::More; + +use Business::OnlinePayment; + +my $runinfo = + "to test set environment variables:" + . " (required) ELINK_ACCOUNT, ELINK_PASSWORD, ELINK_CARD," + . " ELINK_CVV2, ELINK_EXP, ELINK_CARD_NAME, ELINK_CARD_ADDRESS," + . " ELINK_CARD_CITY, ELINK_CARD_STATE, ELINK_CARD_ZIP, and ELINK_DO_LIVE "; + +plan( + ( $ENV{"ELINK_ACCOUNT"} && $ENV{"ELINK_PASSWORD"} && + $ENV{"ELINK_CARD"} && $ENV{"ELINK_CVV2"} && + $ENV{"ELINK_EXP"} && $ENV{"ELINK_CARD_NAME"} && + $ENV{"ELINK_CARD_ADDRESS"} && $ENV{"ELINK_CARD_CITY"} && + $ENV{"ELINK_CARD_STATE"} && $ENV{"ELINK_CARD_ZIP"} && + $ENV{"ELINK_DO_LIVE"} + ) + ? ( tests => 56 ) + : ( skip_all => $runinfo ) +); + +my %opts = ( + "debug" => 0, + "merchantcustservnum" => "8005551212", +); + +my %content = ( + login => $ENV{"ELINK_ACCOUNT"}, + password => $ENV{"ELINK_PASSWORD"}, + action => "Normal Authorization", + type => "CC", + description => "Business::OnlinePayment::TransFirsteLink live test", + card_number => $ENV{"ELINK_CARD"}, + cvv2 => $ENV{"ELINK_CVV2"}, + expiration => $ENV{"ELINK_EXP"}, + amount => "0.01", + invoice_number => "LiveTest", + name => $ENV{"ELINK_CARD_NAME"}, + address => $ENV{"ELINK_CARD_ADDRESS"}, + city => $ENV{"ELINK_CARD_CITY"}, + state => $ENV{"ELINK_CARD_STATE"}, + zip => $ENV{"ELINK_CARD_ZIP"}, +); + +my $voidable; +my $credit_amount = 0; + +{ # valid card number test + my $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); + $tx->content(%content); + tx_check( + $tx, + desc => "valid card_number", + is_success => 1, + result_code => "000", + authorization => qr/^\w{6}$/, + avs_code => "Y", # useless + cvv2_response => "M", + ); + $voidable = $tx->order_number if $tx->is_success; +} + +{ # invalid card number test + + my $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); + $tx->content( %content, card_number => "4111111111111112" ); + tx_check( + $tx, + desc => "invalid card_number", + is_success => 0, + result_code => 214, + authorization => qr/^$/, + avs_code => '', + cvv2_response => '', + ); +} + + +{ # avs_code() / AVSZIP and AVSADDR tests + + my $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); + + $tx->content( %content, "address" => "500 Any street" ); + tx_check( + $tx, + desc => "AVSADDR=N,AVSZIP=Y", + is_success => 1, + result_code => "000", + authorization => qr/^\w{6}$/, + avs_code => "Z", + cvv2_response => "M", + ); + $credit_amount += $content{amount} if $tx->is_success; + + $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); + $tx->content( %content, "zip" => "99999" ); + tx_check( + $tx, + desc => "AVSADDR=Y,AVSZIP=N", + is_success => 1, + result_code => "000", + authorization => qr/^\w{6}$/, + avs_code => "A", + cvv2_response => "M", + ); + $credit_amount += $content{amount} if $tx->is_success; + + $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); + $tx->content( %content, "address" => "500 Any street", "zip" => "99999" ); + tx_check( + $tx, + desc => "AVSADDR=N,AVSZIP=N", + is_success => 1, + result_code => "000", + authorization => qr/^\w{6}$/, + avs_code => "N", + cvv2_response => "M", + ); + $credit_amount += $content{amount} if $tx->is_success; +} + +{ # cvv2_response() / CVV2MATCH + + my $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); + + $tx->content( %content, "cvv2" => $content{cvv2}+1 ); + tx_check( + $tx, + desc => "wrong cvv2", + is_success => 1, + result_code => "000", + authorization => qr/^\w{6}$/, + avs_code => "Y", + cvv2_response => "N", + ); + +} + +{ # refund test + + my $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); + $tx->content( %content, 'action' => "Credit", + 'amount' => sprintf("%.2f", $credit_amount), + ); + tx_check( + $tx, + desc => "refund/credit", + is_success => 1, + result_code => "000", + authorization => qr/^$/, + avs_code => '', + cvv2_response => '', + ); +} + +{ # void test + + my $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); + $tx->content( %content, 'action' => "Void", + 'order_number' => $voidable + ); + tx_check( + $tx, + desc => "void", + is_success => 1, + result_code => "000", + authorization => qr/^$/, + avs_code => '', + cvv2_response => '', + ); +} + +sub tx_check { + my $tx = shift; + my %o = @_; + + $tx->submit; + + is( $tx->is_success, $o{is_success}, "$o{desc}: " . tx_info($tx) ); + is( $tx->result_code, $o{result_code}, "result_code(): RESULT" ); + like( $tx->authorization, $o{authorization}, "authorization() / AUTHCODE" ); + is( $tx->avs_code, $o{avs_code}, "avs_code() / AVSADDR and AVSZIP" ); + is( $tx->cvv2_response, $o{cvv2_response}, "cvv2_response() / CVV2MATCH" ); + is( scalar(@{$tx->junk}), 0, "junk() / JUNK " ); + like( $tx->order_number, qr/^(\d{14}|)$/, "order_number() / PNREF" ); +} + +sub tx_info { + my $tx = shift; + + no warnings 'uninitialized'; + + return ( + join( "", + "is_success(", $tx->is_success, ")", + " order_number(", $tx->order_number, ")", + " result_code(", $tx->result_code, ")", + " auth_info(", $tx->authorization, ")", + " avs_code(", $tx->avs_code, ")", + " cvv2_response(", $tx->cvv2_response, ")", + $tx->junk ? " junk(". join('|', @{$tx->junk}). ")" : '', + ) + ); +} diff --git a/t/live_check.t b/t/live_check.t new file mode 100644 index 0000000..7e272cd --- /dev/null +++ b/t/live_check.t @@ -0,0 +1,120 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use POSIX qw(strftime); +use Test::More; + +use Business::OnlinePayment; + +my $runinfo = + "to test set environment variables:" + . " (required) ELINK_ACH_ACCOUNT, ELINK_ACH_PASSWORD" + . " ELINK_ROUTING_CODE, ELINK_BANK_ACCOUNT, ELINK_ACH_NAME" + . " ELINK_ACH_ADDRESS, ELINK_ACH_CITY, ELINK_ACH_STATE" + . " ELINK_ACH_ZIP, ELINK_ACH_PHONE, ELINK_DO_LIVE"; + +plan( + ( $ENV{"ELINK_ACH_ACCOUNT"} && $ENV{"ELINK_ACH_PASSWORD"} && + $ENV{"ELINK_ROUTING_CODE"} && $ENV{"ELINK_BANK_ACCOUNT"} && + $ENV{"ELINK_ACH_NAME"} && $ENV{"ELINK_ACH_ADDRESS"} && + $ENV{"ELINK_ACH_CITY"} && $ENV{"ELINK_ACH_STATE"} && + $ENV{"ELINK_ACH_ZIP"} && $ENV{"ELINK_ACH_PHONE"} && + $ENV{"ELINK_DO_LIVE"} + ) + ? ( tests => 12 ) + : ( skip_all => $runinfo ) +); + +my %opts = ( + "debug" => 0, + "merchantcustservnum" => "8005551212", +); + +my %content = ( + login => $ENV{"ELINK_ACH_ACCOUNT"}, + password => $ENV{"ELINK_ACH_PASSWORD"}, + action => "Normal Authorization", + type => "CHECK", + description => "Business::OnlinePayment::TransFirsteLink live test", + routing_code => $ENV{"ELINK_ROUTING_CODE"}, + account_number => $ENV{"ELINK_BANK_ACCOUNT"}, + check_number => "99", + amount => "1.01", + invoice_number => "LiveTest", + customer_id => "LiveTestCust", + account_name => $ENV{"ELINK_ACH_NAME"}, + address => $ENV{"ELINK_ACH_ADDRESS"}, + city => $ENV{"ELINK_ACH_CITY"}, + state => $ENV{"ELINK_ACH_STATE"}, + zip => $ENV{"ELINK_ACH_ZIP"}, + phone => $ENV{"ELINK_ACH_PHONE"}, +); + +{ # valid account test + my $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); + $tx->content(%content); + tx_check( + $tx, + desc => "valid account", + is_success => 1, + result_code => "P00", + ); +} + +SKIP: { # invalid account test + + skip "invalid account tests broken", 4; + + my $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); + $tx->content( %content, routing_code => "052000113", + account_number => "000000000001", + ); + + tx_check( + $tx, + desc => "invalid account", + is_success => 0, + result_code => 214, + ); +} + +{ # credit/refund test + + my $tx = new Business::OnlinePayment( "TransFirsteLink", %opts ); + $tx->content( %content, action => "Credit"); + + tx_check( + $tx, + desc => "credit/refund", + is_success => 1, + result_code => "ACCEPTED", + ); +} + +sub tx_check { + my $tx = shift; + my %o = @_; + + $tx->submit; + + is( $tx->is_success, $o{is_success}, "$o{desc}: " . tx_info($tx) ); + is( $tx->result_code, $o{result_code}, "result_code(): RESULT" ); + is( scalar(@{$tx->junk}), 0, "junk() / JUNK " ); + like( $tx->order_number, qr/^(\d{9}|)$/, "order_number() / PNREF" ); +} + +sub tx_info { + my $tx = shift; + + no warnings 'uninitialized'; + + return ( + join( "", + "is_success(", $tx->is_success, ")", + " order_number(", $tx->order_number, ")", + " result_code(", $tx->result_code, ")", + $tx->junk ? " junk(". join('|', @{$tx->junk}). ")" : '', + ) + ); +} -- 2.11.0