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
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)
# 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
PREREQ_PM => {
Business::OnlinePayment => '3',
Business::OnlinePayment::HTTPS => '0.05',
+ Tie::IxHash => '0',
},
(
$] >= 5.005
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;
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
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
RoutingNumber => 'routing_code',
AccountNumber => \$account_number,
+ AccountNum => \$account_number,
CheckNumber => \$check_number,
CardHolderName => 'name',
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" ) {
$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);
$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 );
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 {
plan(
( $ENV{"ELINK_ACCOUNT"} && $ENV{"ELINK_PASSWORD"} )
- ? ( tests => 70 )
+ ? ( tests => 56 )
: ( skip_all => $runinfo )
);
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",
tx_check(
$tx,
desc => "refund/credit",
- is_success => 0,
+ is_success => 1,
result_code => "000",
authorization => '',
avs_code => '',
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",
tx_check(
$tx,
desc => "void",
- is_success => 0,
+ is_success => 1,
result_code => "000",
authorization => '',
avs_code => '',
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 )
);
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
);
}
-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",
$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");
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;
--- /dev/null
+#!/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}). ")" : '',
+ )
+ );
+}
--- /dev/null
+#!/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}). ")" : '',
+ )
+ );
+}