summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changes6
-rw-r--r--MANIFEST23
-rw-r--r--Makefile.PL12
-rw-r--r--README18
-rw-r--r--lib/Business/OnlinePayment/PPIPayMover.pm329
-rw-r--r--lib/Business/OnlinePayment/PPIPayMover/AdditionalField.pm102
-rw-r--r--lib/Business/OnlinePayment/PPIPayMover/CountryCodes.pm318
-rw-r--r--lib/Business/OnlinePayment/PPIPayMover/CreditCardRequest.pm3182
-rw-r--r--lib/Business/OnlinePayment/PPIPayMover/CreditCardResponse.pm201
-rw-r--r--lib/Business/OnlinePayment/PPIPayMover/PayerAuthenticationResponse.pm140
-rw-r--r--lib/Business/OnlinePayment/PPIPayMover/SecureHttp.pm155
-rw-r--r--lib/Business/OnlinePayment/PPIPayMover/TransactionClient.pm92
-rw-r--r--lib/Business/OnlinePayment/PPIPayMover/TransactionRequest.pm118
-rw-r--r--lib/Business/OnlinePayment/PPIPayMover/TransactionResponse.pm171
-rw-r--r--lib/Business/OnlinePayment/PPIPayMover/URLEncoder.pm14
-rw-r--r--lib/Business/OnlinePayment/PPIPayMover/constants.pm631
-rw-r--r--t/Business-OnlinePayment-PPIPayMover.t17
-rw-r--r--t/bad_card.t38
-rw-r--r--t/bop.t5
-rw-r--r--t/capture.t62
-rw-r--r--t/credit_card.t39
-rw-r--r--t/load.t12
-rw-r--r--t/void.t65
23 files changed, 5750 insertions, 0 deletions
diff --git a/Changes b/Changes
new file mode 100644
index 0000000..09d70aa
--- /dev/null
+++ b/Changes
@@ -0,0 +1,6 @@
+Revision history for Perl extension Business::OnlinePayment::PPIPayMover.
+
+0.01 Fri Jun 30 04:25:46 2006
+ - original version; created by h2xs 1.23 with options
+ -A -X -b 5.5.0 -v 0.01 -n Business::OnlinePayment::PPIPayMover
+
diff --git a/MANIFEST b/MANIFEST
new file mode 100644
index 0000000..c2f81ba
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,23 @@
+Changes
+Makefile.PL
+MANIFEST
+README
+t/bad_card.t
+t/bop.t
+t/Business-OnlinePayment-PPIPayMover.t
+t/capture.t
+t/credit_card.t
+t/load.t
+t/void.t
+lib/Business/OnlinePayment/PPIPayMover.pm
+lib/Business/OnlinePayment/PPIPayMover/constants.pm
+lib/Business/OnlinePayment/PPIPayMover/AdditionalField.pm
+lib/Business/OnlinePayment/PPIPayMover/CountryCodes.pm
+lib/Business/OnlinePayment/PPIPayMover/CreditCardRequest.pm
+lib/Business/OnlinePayment/PPIPayMover/CreditCardResponse.pm
+lib/Business/OnlinePayment/PPIPayMover/PayerAuthenticationResponse.pm
+lib/Business/OnlinePayment/PPIPayMover/SecureHttp.pm
+lib/Business/OnlinePayment/PPIPayMover/TransactionClient.pm
+lib/Business/OnlinePayment/PPIPayMover/TransactionRequest.pm
+lib/Business/OnlinePayment/PPIPayMover/TransactionResponse.pm
+lib/Business/OnlinePayment/PPIPayMover/URLEncoder.pm
diff --git a/Makefile.PL b/Makefile.PL
new file mode 100644
index 0000000..7e0b989
--- /dev/null
+++ b/Makefile.PL
@@ -0,0 +1,12 @@
+use 5.005;
+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::PPIPayMover',
+ VERSION_FROM => 'lib/Business/OnlinePayment/PPIPayMover.pm', # finds $VERSION
+ PREREQ_PM => {}, # e.g., Module::Name => 1.1
+ ($] >= 5.005 ? ## Add these new keywords supported since 5.005
+ (ABSTRACT_FROM => 'lib/Business/OnlinePayment/PPIPayMover.pm', # retrieve abstract from module
+ AUTHOR => 'Ivan Kohler <ivan@>') : ()),
+);
diff --git a/README b/README
new file mode 100644
index 0000000..0b62930
--- /dev/null
+++ b/README
@@ -0,0 +1,18 @@
+Copyright uncertain at this time; based on code API code provided without
+clear licensing... assuming that can be resolved:
+
+Business::OnlinePayment conversion copyright (c) 2006 Ivan Kohler
+All rights reserved. This program is free software; you can redistribute it
+and/or modify it under the same terms as Perl itself.
+
+This is Business::OnlinePayment::PPIPayMover, an Business::OnlinePayment
+backend module for PPI PayMover. It is only useful if you have a merchant
+account with PPI Paymover: http://www.ppipaymover.com/
+
+Ivan Kohler <ivan-ppipaymover@420.am>
+
+Business::OnlinePayment is a generic interface for processing payments through
+online credit card processors, online check acceptance houses, etc. (If you
+like buzzwords, call it an "multiplatform ecommerce-enabling middleware
+solution").
+
diff --git a/lib/Business/OnlinePayment/PPIPayMover.pm b/lib/Business/OnlinePayment/PPIPayMover.pm
new file mode 100644
index 0000000..8ac9bc8
--- /dev/null
+++ b/lib/Business/OnlinePayment/PPIPayMover.pm
@@ -0,0 +1,329 @@
+package Business::OnlinePayment::PPIPayMover;
+
+use strict;
+use vars qw($VERSION @ISA $DEBUG);
+use Carp;
+use Business::OnlinePayment::PPIPayMover::constants;
+use Business::OnlinePayment::PPIPayMover::TransactionClient;
+use Business::OnlinePayment::PPIPayMover::CreditCardRequest;
+use Business::OnlinePayment::PPIPayMover::CountryCodes;
+use Business::OnlinePayment::PPIPayMover::CreditCardResponse;
+
+$VERSION = '0.01';
+@ISA = qw(Business::OnlinePayment);
+$DEBUG = 0;
+
+my $tranclient = new Business::OnlinePayment::PPIPayMover::TransactionClient;
+#my $ccreq = new Business::OnlinePayment::PPIPayMover::CreditCardRequest;
+
+sub set_defaults {
+ my $self = shift;
+
+ #$self->server('secure.linkpt.net');
+ #$self->port('1129');
+
+ $self->build_subs(qw(order_number avs_code));
+
+}
+
+sub map_fields {
+ my $self = shift;
+
+ my %content = $self->content();
+
+ # ACTION MAP
+ # target types: SALE, ADJUSTMENT, AUTH, CAPTURE, CREDIT, FORCE_AUTH,
+ # FORCE_SALE, QUERY_CREDIT, QUERY_PAYMENT or VOID
+ my %actions = (
+ 'normal authorization' => 'SALE',
+ 'authorization only' => 'AUTH',
+ 'credit' => 'CREDIT',
+ 'post authorization' => 'CAPTURE',
+ 'void' => 'VOID',
+ );
+ $content{'action'} = $actions{lc($content{'action'})} || $content{'action'};
+
+ # TYPE MAP
+ my %types = (
+ 'visa' => 'CC',
+ 'mastercard' => 'CC',
+ 'american express' => 'CC',
+ 'discover' => 'CC',
+ 'cc' => 'CC',
+ #'check'
+ );
+ $content{'type'} = $types{lc($content{'type'})} || $content{'type'};
+ $self->transaction_type($content{'type'});
+
+ # stuff it back into %content
+ $self->content(%content);
+}
+
+sub submit {
+ my $self = shift;
+
+ #type =>
+ #login =>
+ #password =>
+ #authorization =>
+
+ #name
+
+ #order_number
+
+ #currency =>
+
+ #check_type =>
+ #account_name =>
+ #account_number =>
+ #account_type =>
+ #bank_name =>
+ #routing_code =>
+ #customer_org =>
+ #customer_ssn =>
+ #license_num =>
+ #license_state =>
+ #license_dob =>
+ #get from new() args instead# payee =>
+ #check_number =>
+
+ #recurring_billing => 'cnp_recurring',
+
+ $self->map_fields();
+
+ my %content = $self->content;
+
+ my($month, $year);
+ unless ( $content{action} eq 'CAPTURE'
+ || ( $content{'action'} =~ /^(CREDIT|VOID)$/
+ && exists $content{'order_number'} )
+ ) {
+
+ if ( $self->transaction_type() =~
+ /^(cc|visa|mastercard|american express|discover)$/i
+ ) {
+ } else {
+ Carp::croak("PPIPayMover can't handle transaction type: ".
+ $self->transaction_type());
+ }
+
+ $content{'expiration'} =~ /^(\d+)\D+\d*(\d{2})$/
+ or croak "unparsable expiration $content{expiration}";
+
+ ( $month, $year ) = ( $1, "20$2" );
+ $month = '0'. $month if $month =~ /^\d$/;
+ }
+
+ my $ccreq = new Business::OnlinePayment::PPIPayMover::CreditCardRequest;
+
+ $self->revmap_fields( $ccreq,
+
+ 'ChargeTotal' => 'amount',
+ 'ChargeType' => 'action',
+ 'CreditCardNumber' => 'card_number',
+ 'CreditCardVerificationNumber' => 'cvv2',
+ 'ExpireMonth' => \$month,
+ 'ExpireYear' => \$year,
+
+ 'BillAddressOne' => 'address',
+ #'BillAddressTwo' => '',
+ 'BillCity' => 'city',
+ 'BillCompany' => 'company',
+ 'BillCountryCode' => 'country',
+ #'BillCustomerTitle' => '',
+ 'BillEmail', => 'email',
+ 'BillFax' => 'fax',
+ 'BillFirstName' => 'first_name',
+ 'BillLastName' => 'last_name',
+ #'BillMiddleName' => '',
+ 'BillNote' => '',
+ 'BillPhone' => 'phone',
+ 'BillPostalCode' => 'zip',
+ 'BillStateOrProvince' => 'state',
+
+ 'ShipAddressOne' => 'ship_address',
+ #'ShipAddressTwo' => '',
+ 'ShipCity' => 'ship_city',
+ 'ShipCompany' => 'ship_company',
+ 'ShipCountryCode' => 'ship_country',
+ #'ShipCustomerTitle' => '',
+ 'ShipEmail', => 'ship_email',
+ 'ShipFax' => 'ship_fax',
+ 'ShipFirstName' => 'ship_first_name',
+ 'ShipLastName' => 'ship_last_name',
+ #'ShipMiddleName' => '',
+ 'ShipNote' => '',
+ 'ShipPhone' => 'ship_phone',
+ 'ShipPostalCode' => 'ship_zip',
+ 'ShipStateOrProvince' => 'ship_state',
+
+ #'OrderId' => 'order_number',
+ 'OrderId' => (int (rand 999999998) + 1 ), # XXX This can result in duplicate order ids. You should use your own sequence instead.
+ 'BuyerCode' => '83487235',
+ 'CustomerIPAddress' => 'customer_ip',
+ 'OrderCustomerId' => 'customer_id',
+ 'OrderDescription' => 'description',
+ #'OrderUserId' => '',
+ #'PurchaseOrderNumber' => '',
+ 'TransactionConditionCode' => \( TCC_CARDHOLDER_NOT_PRESENT_SECURE_ECOMMERCE ),
+ #'ShippingCharge' => '',
+ #'StateTax' => '',
+ #'TaxAmount' => '',
+ #'TaxExempt' => '',
+
+ 'InvoiceNumber' => 'invoice_number',
+ 'Industry' => \( RETAIL ),
+ #'FolioNumber' => '',
+
+ #'ChargeTotalIncludesRestaurant'
+ #'ChargeTotalIncludesGiftshop'
+ #'ChargeTotalIncludesMinibar'
+ #'ChargeTotalIncludesPhone'
+ #'ChargeTotalIncludesLaundry'
+ #'ChargeTotalIncludesOther'
+
+ #'ServiceRate'
+
+ #'ServiceStartDay'
+ #'ServiceStartMonth'
+ #'ServiceStartYear'
+ #'ServiceEndMonth'
+ #'ServiceEndYear'
+ #'ServiceEndDay'
+
+ #'ServiceNoShow'
+
+ #'ReferenceId' => '', # XXX Use reference ID for follow-on transactions (CAPTURE, VOID)
+ #'CAVV'
+ #'XID'
+ #'Track1'
+ #'Track2'
+
+
+ );
+
+ # Send the transaction! (test token)
+
+ my $token = $content{'login'};
+ $token = "TEST$token" if $self->test_transaction();
+
+ my $ccresponse = $tranclient->doTransaction(
+ "", # transaction key (?)
+ $ccreq, #cc request
+ $token, #token
+ );
+
+ die $tranclient->GetErrorString unless defined $ccresponse;
+
+ $self->result_code($ccresponse->GetResponseCode);
+ $self->avs_code($ccresponse->GetAVSCode);
+ $self->order_number($ccresponse->GetOrderId);
+
+ if ( $self->result_code == 1 ) { # eq '1' ?
+ $self->is_success(1);
+ #$self->authorization($ccresponse->GetBankApprovalCode);
+ $self->authorization($ccresponse->GetReferenceId); #"Identifier for follow-on transactions"
+ } else {
+ $self->is_success(0);
+ $self->error_message($ccresponse->GetResponseCodeText);
+ }
+
+}
+
+## print "ResponseCode : ", $ccresponse->GetResponseCode, "\n";
+## print "ResponseCodeText : ", $ccresponse->GetResponseCodeText, "\n";
+# print "Timestamp : ", $datetime, "\n";
+# print "IsoCode : ", $ccresponse->GetIsoCode, "\n";
+## print "OrderId : ", $ccresponse->GetOrderId, "\n";
+## print "BankApprovalCode : ", $ccresponse->GetBankApprovalCode, "\n";
+# print "State : ", $ccresponse->GetState, "\n";
+# print "AuthorizedAmount : ", $ccresponse->GetAuthorizedAmount, "\n";
+# print "OriginalAuthorizedAmount: ", $ccresponse->GetOriginalAuthorizedAmount,
+#"\n";
+# print "CapturedAmount : ", $ccresponse->GetCapturedAmount, "\n";
+# print "CreditedAmount : ", $ccresponse->GetCreditedAmount, "\n";
+# print "TimeStampCreated : ", $ccresponse->GetTimeStampCreated, "\n";
+## print "ReferenceId : ", $ccresponse->GetReferenceId, "\n";
+# print "BankTransactionId : ", $ccresponse->GetBankTransactionId, "\n";
+# print "BatchId : ", $ccresponse->GetBatchId, "\n";
+# #print "AVS Code : ", $ccresponse->GetAVSCode, "\n";
+
+#this is different from a "normal" B:OP revmap, it sets things in $ccreq
+sub revmap_fields {
+ my($self, $ccreq, %map) = @_;
+ my %content = $self->content();
+ foreach(keys %map) {
+ my $method = "Set$_";
+ my $content = ref($map{$_}) ? ${ $map{$_} } : $content{$map{$_}};
+ $ccreq->$method($content);
+ }
+}
+
+
+1;
+__END__
+
+=head1 NAME
+
+Business::OnlinePayment::PPIPayMover - PPI PayMover backend for Business::OnlinePayment
+
+=head1 SYNOPSIS
+
+ use Business::OnlinePayment;
+
+ my $tx = new Business::OnlinePayment( 'PPIPayMover' );
+
+ $tx->content(
+ login => '195325FCC230184964CAB3A8D93EEB31888C42C714E39CBBB2E541884485D04B', #token
+ type => 'VISA',
+ action => 'Normal Authorization',
+ description => 'Business::OnlinePayment test',
+ amount => '49.95',
+ invoice_number => '100100',
+ customer_id => 'jsk',
+ name => 'Grub Tetris',
+ address => '123 Anystreet',
+ city => 'Anywhere',
+ state => 'UT',
+ zip => '84058',
+ email => 'ivan-ppipaymover@420.am',
+ card_number => '4007000000027',
+ expiration => '09/12',
+ );
+ $tx->submit();
+
+ if($tx->is_success()) {
+ print "Card processed successfully: ".$tx->authorization."\n";
+ } else {
+ print "Card was rejected: ".$tx->error_message."\n";
+ }
+
+=head1 SUPPORTED TRANSACTION TYPES
+
+=head2 Visa, MasterCard, American Express, JCB, Discover/Novus, Carte blanche/Di
+ners Club
+
+=head1 DESCRIPTION
+
+For detailed information see L<Business::OnlinePayment>.
+
+=head1 BUGS
+
+=head1 AUTHOR
+
+Ivan Kohler <ivan-ppipaymover@420.am>
+
+=head1 COPYRIGHT AND LICENSE
+
+Based on API components from PPI PayMover provided without clear licensing, so,
+probably not freely licensable at the moment... assuming that can be resolved:
+
+Business::OnlinePayment conversion copyright (c) 2006 Ivan Kohler
+All rights reserved. This program is free software; you can redistribute it
+and/or modify it under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+perl(1), L<Business::OnlinePayment>.
+
+=cut
diff --git a/lib/Business/OnlinePayment/PPIPayMover/AdditionalField.pm b/lib/Business/OnlinePayment/PPIPayMover/AdditionalField.pm
new file mode 100644
index 0000000..bd2d91e
--- /dev/null
+++ b/lib/Business/OnlinePayment/PPIPayMover/AdditionalField.pm
@@ -0,0 +1,102 @@
+
+# * AdditionalFields are used to hold fields that do not have separate
+# * specifications. Each AdditionalField consists of a name and a value,
+# * which are set in the constructor and are retrieved using the get methods.
+# * <P>
+# * TransactionRequests (including CreditCardRequests) hold
+# * a Vector of AdditionalField objects to permit them to be
+# * interoperable with future releases.
+# * <P>
+# * @see TransactionRequest#setAdditionalField
+# * @see TransactionRequest#setAdditionalFields
+# */
+
+
+#*
+# * Make an AdditionalField object with the given name and value.
+# * <P>
+# * @param name Must not be NULL or "". May not contain ' ', '=', or '+'.
+# */
+
+use strict;
+#use overload;
+package Business::OnlinePayment::PPIPayMover::AdditionalField;
+use overload
+'== ' => \&equals;
+my $paramSeparator = "&";
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ my ($name, $value) = @_; # name and value as two arguements
+ $self->{strError} = "";
+ if (!$name || $name eq "" ) {
+ $self->{strError} .= "AdditionalField constructor: must provide a name";
+ }
+ if (!$value || $value eq "") {
+ $self->{strError} .= "AdditionalField constructor: must provide a value";
+ }
+ if (index($name, " ") != -1 || index($name, "=") != -1) {
+ $self->{strError} .= "AdditionalField constructor: name may not contain space or =";
+ }
+ if (index($value, " ") != -1 || index($value, "=") != -1) {
+ $self->{strError} .= "AdditionalField constructor: value may not contain space or =";
+ }
+ if (index($value, "+") != -1) {
+ $self->{strError} .= "AdditionalField constructor: value may not contain +";
+ }
+ if (defined $name) { $self->{name} = $name }
+ if (defined $value) { $self->{value} = $value }
+
+ bless $self, $class;
+}
+
+#**
+# * Get the name associated with this AdditionalField object.
+# * <P>
+# * @return The name of the additional field.
+#
+sub getName {
+ my $self = shift;
+ $self->{name};
+}
+
+#**
+# * Get the value associated with this AdditionalField object.
+# * <P>
+# * @return The value of the additional field.
+#
+sub getValue {
+ my $self = shift;
+ $self->{value};
+}
+
+sub getError {
+ my $self = shift;
+ $self->{strError};
+}
+
+#**
+# * This method only checks the name field. This is ok because
+# * a TransactionRequest is not allowed to have two AdditionalField
+# * objects with the same name.
+#
+sub equals {
+ my $self = shift;
+ my $other = shift;
+ if($self->{name} eq $other->getName) { return 1 }
+ else { return 0 };
+}
+
+
+sub write {
+ my $self = shift;
+ my $outString = shift;
+ $self->{value} =~ tr/ /+/;
+ $$outString .= $self->{name};
+ $$outString .= "=";
+ $$outString .= $self->{value};
+ $$outString .= $paramSeparator;
+}
+
+1;
diff --git a/lib/Business/OnlinePayment/PPIPayMover/CountryCodes.pm b/lib/Business/OnlinePayment/PPIPayMover/CountryCodes.pm
new file mode 100644
index 0000000..049635c
--- /dev/null
+++ b/lib/Business/OnlinePayment/PPIPayMover/CountryCodes.pm
@@ -0,0 +1,318 @@
+package Business::OnlinePayment::PPIPayMover::CountryCodes;
+
+use strict;
+use vars qw(@ISA @EXPORT %countryHash);
+use Exporter;
+
+@ISA = qw(Exporter);
+@EXPORT = qw(getCountry
+ getNumericCountryCode
+ isValidCountryCode
+getCCodeFromCName);
+
+# Two Character Country Codes */
+%countryHash = ("DZ" => "ALGERIA:012",
+ "BJ" => "BENIN:204",
+ "BW" => "BOTSWANA:072",
+ "BF" => "BURKINA FASO:854",
+ "BI" => "BURUNDI:108",
+ "CM" => "CAMEROON:120",
+ "CV" => "CAPE VERDE:132",
+ "CF" => "CENTRAL AFRICAN REPUBLIC:140",
+ "TD" => "CHAD:148",
+ "KM" => "COMOROS:174",
+ "CG" => "CONGO:178",
+ "CI" => "COTE DIVOIRE:384",
+ "DJ" => "DJIBOUTI:262",
+ "EG" => "EGYPT:818",
+ "GQ" => "EQUATORIAL GUINEA:226",
+ "ER" => "ERITREA:232",
+ "ET" => "ETHIOPIA:231",
+ "GA" => "GABON:266",
+ "GM" => "GAMBIA:270",
+ "GH" => "GHANA:288",
+ "GN" => "GUINEA:324",
+ "GW" => "GUINEA BISSAU:624",
+ "KE" => "KENYA:404",
+ "LS" => "LESOTHO:426",
+ "LR" => "LIBERIA:430",
+ "MG" => "MADAGASCAR:450",
+ "MW" => "MALAWI:454",
+ "ML" => "MALI:466",
+ "MR" => "MAURITANIA:478",
+ "YT" => "MAYOTTE:175",
+ "MA" => "MOROCCO:504",
+ "MZ" => "MOZAMBIQUE:508",
+ "NA" => "NAMIBIA:516",
+ "NE" => "NIGER:562",
+ "NG" => "NIGERIA:566",
+ "RE" => "REUNION:638",
+ "ST" => "SAO TOME AND PRINCIPE:678",
+ "SN" => "SENEGAL:686",
+ "SL" => "SIERRA LEONE:694",
+ "SO" => "SOMALIA:706",
+ "ZA" => "SOUTH AFRICA:710",
+ "SH" => "ST HELENA:654",
+ "SD" => "SUDAN:736",
+ "SZ" => "SWAZILAND:748",
+ "TZ" => "TANZANIA:834",
+ "TG" => "TOGO:768",
+ "TN" => "TUNISIA:788",
+ "UG" => "UGANDA:800",
+ "EH" => "WESTERN SAHARA:732",
+ "ZR" => "ZAIRE:180",
+ "ZM" => "ZAMBIA:894",
+ "ZW" => "ZIMBABWE:716",
+
+# Antartica
+ "AQ" => "ANTARCTICA:010",
+
+# Asia
+ "AF" => "AFGHANISTAN:004",
+ "BD" => "BANGLADESH:050",
+ "BT" => "BHUTAN:064",
+ "BN" => "BRUNEI:096",
+ "KH" => "CAMBODIA:116",
+ "CN" => "CHINA:156",
+ "HK" => "HONG KONG:344",
+ "IN" => "INDIA:356",
+ "ID" => "INDONESIA:360",
+ "JP" => "JAPAN:392",
+ "KZ" => "KAZAKHSTAN:398",
+ "KG" => "KYRGYZSTAN:417",
+ "LA" => "LAOS:418",
+ "MO" => "MACAU:446",
+ "MY" => "MALAYSIA:458",
+ "MV" => "MALDIVES:462",
+ "MN" => "MONGOLIA:496",
+ "NP" => "NEPAL:524",
+ "PK" => "PAKISTAN:586",
+ "PH" => "PHILIPPINES:608",
+ "KR" => "REPUBLIC OF KOREA:410",
+ "RU" => "RUSSIA:643",
+ "SC" => "SEYCHELLES:690",
+ "SG" => "SINGAPORE:702",
+ "LK" => "SRI LANKA:144",
+ "TW" => "TAIWAN:158",
+ "TJ" => "TAJIKISTAN:762",
+ "TH" => "THAILAND:764",
+ "TM" => "TURKMENISTAN:795",
+ "UZ" => "UZBEKISTAN:860",
+ "VN" => "VIETNAM:704",
+
+# Australia
+ "AS" => "AMERICAN SAMOA:016",
+ "AU" => "AUSTRALIA:036",
+ "FM" => "FEDERATED STATES OF MICRONESIA:583",
+ "FJ" => "FIJI:242",
+ "PF" => "FRENCH POLYNESIA:258",
+ "GU" => "GUAM:316",
+ "KI" => "KIRIBATI:296",
+ "MH" => "MARSHALL ISLANDS:584",
+ "NR" => "NAURU:520",
+ "NC" => "NEW CALEDONIA:540",
+ "NZ" => "NEW ZEALAND:554",
+ "MP" => "NORTHERN MARIANA ISLANDS:580",
+ "PW" => "PALAU:585",
+ "PG" => "PAPUA NEW GUINEA:598",
+ "PN" => "PITCAIRN:612",
+ "SB" => "SOLOMON ISLANDS:090",
+ "TO" => "TONGA:776",
+ "TV" => "TUVALU:798",
+ "VU" => "VANUATU:548",
+
+# Caribbean
+ "AI" => "ANGUILLA:660",
+ "AG" => "ANTIGUA AND BARBUDA:028",
+ "AW" => "ARUBA:533",
+ "BS" => "BAHAMAS:044",
+ "BB" => "BARBADOS:052",
+ "BM" => "BERMUDA:060",
+ "KY" => "CAYMAN ISLANDS:136",
+ "DM" => "DOMINICA:212",
+ "DO" => "DOMINICAN REPUBLIC:214",
+ "GD" => "GRENADA:308",
+ "GP" => "GUADELOUPE:312",
+ "HT" => "HAITI:332",
+ "JM" => "JAMAICA:388",
+ "MQ" => "MARTINIQUE:474",
+ "AN" => "NETHERLANDS ANTILLES:530",
+ "PR" => "PUERTO RICO:630",
+ "KN" => "ST KITTS AND NEVIS:659",
+ "LC" => "ST LUCIA:662",
+ "VC" => "ST VINCENT AND THE GRENADINES:670",
+ "TT" => "TRINIDAD AND TOBAGO:780",
+ "TC" => "TURKS AND CAICOS ISLANDS:796",
+ "VG" => "VIRGIN ISLANDS BRITISH:092",
+ "VI" => "VIRGIN ISLANDS USA:850",
+
+# Central America
+ "BZ" => "BELIZE:084",
+ "CR" => "COSTA RICA:188",
+ "SV" => "EL SALVADOR:222",
+ "GT" => "GUATEMALA:320",
+ "HN" => "HONDURAS:340",
+ "NI" => "NICARAGUA:558",
+ "PA" => "PANAMA:591",
+
+# Europe
+ "AL" => "ALBANIA:008",
+ "AD" => "ANDORRA:020",
+ "AM" => "ARMENIA:051",
+ "AT" => "AUSTRIA:040",
+ "AZ" => "AZERBAIJAN:031",
+ "BY" => "BELARUS:112",
+ "BE" => "BELGIUM:056",
+ "BG" => "BULGARIA:100",
+ "HR" => "CROATIA:191",
+ "CY" => "CYPRUS:196",
+ "CZ" => "CZECH REPUBLIC:203",
+ "DK" => "DENMARK:208",
+ "EE" => "ESTONIA:233",
+ "FO" => "FAROE ISLANDS:234",
+ "FI" => "FINLAND:246",
+ "FR" => "FRANCE:250",
+ "GE" => "GEORGIA:268",
+ "DE" => "GERMANY:276",
+ "GI" => "GIBRALTAR:292",
+ "GR" => "GREECE:300",
+ "GL" => "GREENLAND:304",
+ "HU" => "HUNGARY:348",
+ "IS" => "ICELAND:352",
+ "IE" => "IRELAND:372",
+ "IT" => "ITALY:380",
+ "LV" => "LATVIA:428",
+ "LI" => "LIECHTENSTEIN:438",
+ "LT" => "LITHUANIA:440",
+ "LU" => "LUXEMBOURG:442",
+ "MT" => "MALTA:470",
+ "FX" => "METROPOLITAN FRANCE:249",
+ "MD" => "MOLDOVA:498",
+ "NL" => "NETHERLANDS:528",
+ "NO" => "NORWAY:578",
+ "PL" => "POLAND:616",
+ "PT" => "PORTUGAL:620",
+ "RO" => "ROMANIA:642",
+ "SK" => "SLOVAKIA:703",
+ "SI" => "SLOVENIA:705",
+ "ES" => "SPAIN:724",
+ "SJ" => "SVALBARD AND JAN MAYEN ISLANDS:744",
+ "SE" => "SWEDEN:752",
+ "CH" => "SWITZERLAND:756",
+ "MK" => "REPUBLIC OF MACEDONIA:807",
+ "TR" => "TURKEY:792",
+ "UA" => "UKRAINE:804",
+ "GB" => "UNITED KINGDOM:826",
+ "VA" => "VATICAN CITY:336",
+ "YU" => "YUGOSLAVIA:891",
+
+# Middle East
+ "IL" => "ISRAEL:376",
+ "JO" => "JORDAN:400",
+ "KW" => "KUWAIT:414",
+ "LB" => "LEBANON:422",
+ "OM" => "OMAN:512",
+ "QA" => "QATAR:634",
+ "SA" => "SAUDI ARABIA:682",
+ "SY" => "SYRIA:760",
+ "AE" => "UNITED ARAB EMIRATES:784",
+ "YE" => "YEMEN:887",
+
+# North America
+ "CA" => "CANADA:124",
+ "MX" => "MEXICO:484",
+ "US" => "UNITED STATES:840",
+
+# South America
+ "AR" => "ARGENTINA:032",
+ "BO" => "BOLIVIA:068",
+ "BR" => "BRAZIL:076",
+ "CL" => "CHILE:152",
+ "CO" => "COLOMBIA:170",
+ "EC" => "EQUADOR:218",
+ "FK" => "FALKLAND ISLANDS:238",
+ "GF" => "FRENCH GUIANA:254",
+ "GY" => "GUYANA:328",
+ "PY" => "PARAGUAY:600",
+ "PE" => "PERU:604",
+ "SR" => "SURINAME:740",
+ "UY" => "URUGUAY:858",
+ "VE" => "VENEZUELA:862",
+
+# Others
+ "BH" => "BAHRAIN:048",
+ "BV" => "BOUVET ISLANDS:074",
+ "IO" => "BRITISH INDIAN OCEAN TERRITORY:086",
+ "CX" => "CHRISTMAS ISLANDS:162",
+ "CC" => "COCOS KEELING ISLANDS:166",
+ "CK" => "COOK ISLAND:184",
+ "TP" => "EAST TIMOR:626",
+ "TF" => "FRENCH SOUTHERN TERRITORIES:260",
+ "HM" => "HEARD AND MCDONALD ISLANDS:334",
+ "MU" => "MAURITIUS:480",
+ "MC" => "MONACO:492",
+ "MS" => "MONTSERRAT:500",
+ "MM" => "MYANMAR:104",
+ "NU" => "NIUE:570",
+ "NF" => "NORFOLK ISLAND:574",
+ "WS" => "SAMOA:882",
+ "SM" => "SAN MARINO:674",
+ "PM" => "ST PIERRE AND MIQUELON:666",
+ "TK" => "TOKELAU:772",
+ "UM" => "UNITED STATES MINOR OUTLYING ISLANDS:581",
+ "WF" => "WALLIS AND FUTUNA ISLANDS:876",
+
+ "AO" => "ANGOLA:024",
+ "BA" => "BOSNIA AND HERZEGOWINA:070",
+ "CU" => "CUBA:192",
+ "IR" => "ISLAMIC REPUBLIC OF IRAN:364",
+ "IQ" => "IRAQ:368",
+ "KP" => "DEMOCRATIC PEOPLES REPUBLIC OF KOREA:408",
+ "LY" => "LIBYAN ARAB JAMAHIRIYA:434",
+ "RW" => "RWANDA:646",
+ "GS" => "SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS:39",
+ "CD" => "DEMOCRATIC REPUBLIC OF THE CONGO:180",
+ "PS" => "OCCUPIED PALESTINIAN TERRITORY:275"
+);
+
+
+sub getCountry {
+ my $countryCode = shift; # give country code as an arguement to get country name
+ if(exists $CountryCodes::countryHash{$countryCode}){
+ my $countryName;
+ my $countryNumber;
+ ($countryName, $countryNumber) = split(/:/, $CountryCodes::countryHash{$countryCode});
+ return $countryName;
+ }
+ else { return undef }
+}
+
+sub getNumericCountryCode {
+ my $countryCode = shift; # give country code as an arguement to get numeric country code
+ if(exists $CountryCodes::countryHash{$countryCode}) {
+ my $countryName;
+ my $countryNumber;
+ ($countryName, $countryNumber) = split(/:/, $CountryCodes::countryHash{$countryCode});
+ return $countryNumber;
+ }
+ else {return undef}
+}
+
+
+sub isValidCountryCode {
+ my $countryCode = shift;
+ return (exists $CountryCodes::countryHash{$countryCode});
+}
+
+sub getCCodeFromCName {
+ my $country = shift; # give country name as an arguement to get country code
+ $country = uc($country);
+ my $key;
+ my $countryName;
+ my $countryNumber;
+ foreach $key (keys(%CountryCodes::countryHash)){
+ ($countryName, $countryNumber) = split(/:/, $CountryCodes::countryHash{$key});
+ if ($country eq $countryName) { return $key}
+ }
+ return undef;
+}
diff --git a/lib/Business/OnlinePayment/PPIPayMover/CreditCardRequest.pm b/lib/Business/OnlinePayment/PPIPayMover/CreditCardRequest.pm
new file mode 100644
index 0000000..8529489
--- /dev/null
+++ b/lib/Business/OnlinePayment/PPIPayMover/CreditCardRequest.pm
@@ -0,0 +1,3182 @@
+package Business::OnlinePayment::PPIPayMover::CreditCardRequest;
+
+use strict;
+use vars qw(@ISA);
+use Business::OnlinePayment::PPIPayMover::TransactionRequest;
+use Business::OnlinePayment::PPIPayMover::CreditCardResponse;
+use Business::OnlinePayment::PPIPayMover::AdditionalField;
+use Business::OnlinePayment::PPIPayMover::constants;
+use Business::OnlinePayment::PPIPayMover::CountryCodes;
+use Business::OnlinePayment::PPIPayMover::URLEncoder;
+
+@ISA = qw(Business::OnlinePayment::PPIPayMover::TransactionRequest);
+1;
+
+#default constructor
+sub new {
+ my $class = shift;
+ my $self = $class->SUPER::new();
+
+# Misc identification fields
+ $self->{strCartridgeType} = ""; # v1.5
+ $self->{strEcommerceIndicator} = ""; # v1.5
+
+# credit card fields.
+
+ $self->{strCreditCardNumber} = "";
+ $self->{strCreditCardVerificationNumber} = ""; # v1.5
+ $self->{strAVSCode} = ""; # v1.5
+ $self->{strExpireMonth} = "";
+ $self->{strExpireYear} = "";
+ $self->{strChargeType} = "";
+ $self->{strChargeTotal} = "";
+ $self->{dChargeTotal} = -1.0;
+ $self->{strCardBrand} = "";
+ $self->{strCurrency} = "";
+ $self->{strOrderId} = "";
+ $self->{strBankApprovalCode} = ""; # Required if chargetype is FORCE_AUTH or FORCE_SALE
+ $self->{strDuplicateCheck} = ""; #v1.7.1
+ $self->{strReferenceId} = ""; # Required if chargetype is CAPTURE, QUERY_CREDIT, QUERY_PAYMENT or ADJUSTMENT
+ $self->{strOrderDescription} = "";
+ $self->{strOrderUserId} = "";
+ $self->{strTaxAmount} = "";
+ $self->{dTaxAmount} = -1.0;
+ $self->{strShippingCharge} = "";
+ $self->{dShippingCharge} = -1.0;
+
+# Billing info fields ...
+
+ $self->{strBillFirstName} = "";
+ $self->{strBillLastName} = "";
+ $self->{strBillMiddleName} = "";
+ $self->{strBillCustomerTitle} = "";
+ $self->{strBillCompany} = "";
+ $self->{strBillAddressOne} = "";
+ $self->{strBillAddressTwo} = "";
+ $self->{strBillCity} = "";
+ $self->{strBillStateOrProvince} = "";
+ $self->{strBillPostalCode} = "";
+ $self->{strBillCountryCode} = "";
+ $self->{strBillEmail} = "";
+ $self->{strBillPhone} = "";
+ $self->{strBillFax} = "";
+ $self->{strBillNote} = "";
+
+# Shipping info fields default values.
+
+ $self->{strShipFirstName} = "";
+ $self->{strShipLastName} = "";
+ $self->{strShipMiddleName} = "";
+ $self->{strShipCustomerTitle} = "";
+ $self->{strShipCompany} = "";
+ $self->{strShipAddressOne} = "";
+ $self->{strShipAddressTwo} = "";
+ $self->{strShipCity} = "";
+ $self->{strShipStateOrProvince} = "";
+ $self->{strShipPostalCode} = "";
+ $self->{strShipCountryCode} = "";
+ $self->{strShipEmail} = "";
+ $self->{strShipPhone} = "";
+ $self->{strShipFax} = "";
+ $self->{strShipNote} = "";
+
+# Authentication fields
+ $self->{strAuthenticationTransactionId} = "";
+ $self->{strAuthenticationPayload} = "";
+ $self->{boolSuccessOnAuthenticationInconclusive} = "";
+
+
+# Others
+ $self->{strBuyerCode} = "";
+ $self->{strCAVV} = "";
+ $self->{strCustomerIPAddress} = "";
+ $self->{strPurchaseOrderNumber} = "";
+ $self->{dStateTax} = -1.0;
+ $self->{strTrack1} = "";
+ $self->{strTrack2} = "";
+ $self->{strXID} = "";
+ $self->{boolTaxExempt} = "";
+ $self->{strInvoiceNumber} = "";
+
+# Industry Fields
+ $self->{strIndustry} = "";
+ $self->{strFolioNumber} = "";
+
+ $self->{boolChargeTotalIncludesRestaurant} = "";
+ $self->{boolChargeTotalIncludesGiftshop} = "";
+ $self->{boolChargeTotalIncludesMinibar} = "";
+ $self->{boolChargeTotalIncludesPhone} = "";
+ $self->{boolChargeTotalIncludesLaundry} = "";
+ $self->{boolChargeTotalIncludesOther} = "";
+
+ $self->{dServiceRate} = -1.0;
+ $self->{strServiceRate} = "";
+ $self->{intServiceEndDay} = "";
+ $self->{intServiceEndMonth} = "";
+ $self->{intServiceEndYear} = "";
+ $self->{intServiceStartDay} = "";
+ $self->{intServiceStartMonth} = "";
+ $self->{intServiceStartYear} = "";
+ $self->{boolServiceNoShow} = "";
+
+ return $self;
+}
+
+
+
+#**
+# * Set the value of the cartridge type.
+# * <p>
+# */
+sub SetCartridgeType {
+ my $self = shift;
+ my $cartType = shift; # take one string arguement to get cartridgeType
+ if (!defined($cartType)) {
+ $self->{strError} = "Cartridge type is undefined.";
+ return CCR_ERROR;
+ }
+ if ($cartType eq ""){
+ $self->{strError} = "Invalid cartridge type.";
+ return CCR_ERROR;
+ }
+ $self->{strCartridgeType} = $cartType;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the value of the Ecommerce Indicator number.
+# * <p>
+# */
+sub SetEcommerceIndicator {
+ my $self = shift;
+ my $ecommerceIndicator = shift; # take one string arguement to get EcommerceIndicator
+ if (!defined($ecommerceIndicator)) {
+ $self->{strError} = "Ecommerce indicator is undefined.";
+ return CCR_ERROR;
+ }
+ if ($ecommerceIndicator eq ""){
+ $self->{strError} = "Invalid ecommerce indicator.";
+ return CCR_ERROR;
+ }
+ $self->{strEcommerceIndicator} = $ecommerceIndicator;
+ return CCR_NO_ERROR;
+}
+
+
+
+
+#**
+# * Set the value of the credit card number.
+# * <p>
+# * @param creditCardNumber must be numeric characters
+# * @exception TransactionProtocolException thrown if creditCardNumber is non-numeric or the empty String.
+# */
+sub SetCreditCardNumber {
+ my $self = shift;
+ my $ccNo = shift; # take one string arguement to get creditcard number
+ if (!defined($ccNo)) {
+ $self->{strError} = "Credit card number is undefined.";
+ return CCR_ERROR;
+ }
+ if ($ccNo eq ""){
+ $self->{strError} = "Invalid credit card number.";
+ return CCR_ERROR;
+ }
+ if ($ccNo =~ /\D/) {
+ $self->{strError} = "Non-numeric credit card number.";
+ return CCR_ERROR;
+ }
+ if ( ( length $ccNo < 13 ) || ( length $ccNo > 19 ) ) {
+ $self->{strError} = "Invalid credit card number length.";
+ return CCR_ERROR;
+ }
+ $self->{strCreditCardNumber} = $ccNo;
+ return CCR_NO_ERROR;
+}
+
+#**
+# * Set the value of the credit card verification number.
+# * <p>
+# * @param creditCardVerificationNumber must be numeric characters
+# */
+sub SetCreditCardVerificationNumber {
+ my $self = shift;
+ my $ccVerNo = shift; # take one string arguement to get creditCardVerification number
+ if (!defined($ccVerNo)) {
+ $self->{strError} = "Credit card verification number is undefined.";
+ return CCR_ERROR;
+ }
+ if ($ccVerNo eq ""){
+ $self->{strError} = "Invalid credit card verification number.";
+ return CCR_ERROR;
+ }
+ if ($ccVerNo =~ /\D/) {
+ $self->{strError} = "Non-numeric credit card verification number.";
+ return CCR_ERROR;
+ }
+ $self->{strCreditCardVerificationNumber} = $ccVerNo;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the value of the credit card expiration month.
+# * <p>
+# * @param expireMonth Must be an integer in ASCII characters in the range "1" to "12, inclusive.
+# * @exception TransactionProtocolException thrown if expireMonth is not >= 1 and <= 12.
+# */
+sub SetExpireMonth
+{
+ my $self = shift;
+ my $expireMonth = shift; #take one string arguement
+ if (!defined($expireMonth)) {
+ $self->{strError} = "Expire month is undefined.";
+ return CCR_ERROR;
+ }
+ if ($expireMonth eq ""){
+ $self->{strError} = "Invalid expire month.";
+ return CCR_ERROR;
+ }
+
+ if ($expireMonth =~ /\D/) {
+ $self->{strError} = "Invalid credit expire month (non-digit).";
+ return CCR_ERROR;
+ }
+
+ my $iExpireMonth = 1 * $expireMonth;
+ if ($iExpireMonth < 1 || $iExpireMonth > 12) {
+ $self->{strError} .= "Invalid expire month (not 1 through 12).";
+ return CCR_ERROR;
+ }
+ $self->{strExpireMonth} = $expireMonth;
+
+ return 1;
+}
+
+
+#**
+# * Set the value of the credit card expiration year.
+# * <p>
+# * @param expireYear Must be a four-digit integer in ASCII characters. E.g. "2001".
+# * @exception TransactionProtocolException thrown if expireYear is not a four digit year.
+#
+sub SetExpireYear
+{
+ my $self = shift;
+ my $expireYear = shift; # take a string arguement
+ if (!defined($expireYear)) {
+ $self->{strError} = "Expire year is undefined.";
+ return CCR_ERROR;
+ }
+ if (length($expireYear) != 4) {
+ $self->{strError} = "Invalid expire year, must be 4 numeric characters.";
+ return CCR_ERROR;
+ }
+ if($expireYear =~ /\D/){
+ $self->{strError} = "Invalid credit expire year (non-numeric).";
+ return CCR_ERROR;
+ }
+
+ $self->{strExpireYear} = $expireYear;
+ return CCR_NO_ERROR;
+}
+#**
+# * Set the charge type.
+# * <p>
+# * @param chargeType Must be one of the following constants: SALE, AUTH, CAPTURE, FORCE_AUTH,
+# * FORCE_SALE, VOID, QUERY_CREDIT, QUERY_PAYMENT, ADJUSTMENT or CREDIT.
+# * @exception TransactionProtocolException thrown if chargeType is not a valid charge type
+# * defined by this class.
+# */
+sub SetChargeType
+{
+ my $self = shift;
+ my $chargeType = shift; # take one string arguement
+
+ if (!defined($chargeType)) {
+ $self->{strError} = "Charge type is undefined.";
+ return CCR_ERROR;
+ }
+ if ($chargeType eq "") {
+ $self->{strError} = "Invalid charge type";
+ return CCR_ERROR;
+ }
+
+ if (!($chargeType eq SALE || $chargeType eq AUTH ||
+ $chargeType eq CAPTURE || $chargeType eq VOID ||
+ $chargeType eq FORCE_AUTH || $chargeType eq FORCE_SALE ||
+ $chargeType eq QUERY_PAYMENT || $chargeType eq QUERY_CREDIT ||
+ $chargeType eq CLOSE_ORDER || $chargeType eq CANCEL_ORDER ||
+ $chargeType eq VOID_AUTH || $chargeType eq VOID_CAPTURE ||
+ $chargeType eq VOID_CREDIT || $chargeType eq CREATE_ORDER ||
+ $chargeType eq CREDIT || $chargeType eq ADJUSTMENT)) {
+ $self->{strError} = "Invalid charge type.";
+ return CCR_ERROR;
+ }
+ $self->{strChargeType} = $chargeType;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the transaction amount using a floating point value. Other amounts, such
+# * as tax amount or shipping charges, do not affect the charge total
+# * <p>
+# * @param chargeTotal Must be a positive floating-point number.
+# * E.g. Use <i>12.34</i> to represent $12.34.
+# * @exception TransactionProtocolException thrown if chargeTotal less than zero
+# */
+sub SetChargeTotal
+{
+ my $self = shift;
+ my $chargeTotal = shift; # take either one string or float arguement
+
+ if (!defined($chargeTotal)) {
+ $self->{strError} = "Charge total is undefined.";
+ return CCR_ERROR;
+ }
+
+ if ( $chargeTotal !~ /^(\d+\.?\d*|\.\d+)$/ ) {
+ $self->{strError} = "Non-numeric charge.";
+ return CCR_ERROR;
+ }
+
+ my $dChargeTotal = $chargeTotal * 1.0;
+ if ($dChargeTotal < 0){
+ $self->{strError} = "Charge total cannot be negative.";
+ return CCR_ERROR;
+ }
+
+ $self->{dChargeTotal} = $dChargeTotal;
+ $self->{strChargeTotal} = "".$chargeTotal;
+
+ return CCR_NO_ERROR;
+}
+
+
+
+
+#**
+# * Set the transaction credit card brand.
+# * <p>
+# * @param cardBrand Must be one of the following constants:
+# * VISA, MASTERCARD, AMERICAN_EXPRESS, DISCOVER, NOVA, AMEX, DINERS, EUROCARD,
+# * CARD_BRAND_1, CARD_BRAND_2, CARD_BRAND_3, CARD_BRAND_4, CARD_BRAND_5, or CARD_BRAND_6.
+# * @exception TransactionProtocolException thrown if cardBrand not one of the card brand constants
+# * defined by this class.
+# */
+sub SetCardBrand
+{
+ my $self = shift;
+ my $CardBrand = shift; # take a string arguement
+
+ if (!defined($CardBrand) || $CardBrand eq ""){
+ $self->{strError} = "Blank or undefined card type.";
+ return CCR_ERROR;
+ }
+
+ if ($CardBrand ne VISA &&
+ $CardBrand ne MASTERCARD &&
+ $CardBrand ne AMERICAN_EXPRESS &&
+ $CardBrand ne DISCOVER &&
+ $CardBrand ne NOVA &&
+ $CardBrand ne AMEX &&
+ $CardBrand ne DINERS &&
+ $CardBrand ne EUROCARD &&
+ $CardBrand ne CARD_BRAND_1 &&
+ $CardBrand ne CARD_BRAND_2 &&
+ $CardBrand ne CARD_BRAND_3 &&
+ $CardBrand ne CARD_BRAND_4 &&
+ $CardBrand ne CARD_BRAND_5 &&
+ $CardBrand ne CARD_BRAND_6) {
+ $self->{strError} = "Invalid card brand:$CardBrand.";
+ return CCR_ERROR;
+ }
+ $self->{strCardBrand} = $CardBrand;
+ return CCR_NO_ERROR;
+}
+
+#**
+# * Set the order ID.
+# */
+sub SetOrderId
+{
+ my $self = shift;
+ my $OrderId = shift; # take a string arguement
+ if (!defined($OrderId)) {
+ $self->{strError} = "Order id is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strOrderId} = $OrderId;
+ return CCR_NO_ERROR;
+}
+
+#**
+# * Set the capture reference ID (used in tracking captures / deposits).
+# * This field is required if chargeType is CAPTURE.
+# */
+sub SetCaptureReferenceId
+{
+ my $self = shift;
+ my $CaptureReferenceId = shift; #take a string arguement
+ if (!defined($CaptureReferenceId)){
+ $self->{strError} = "Capture reference id is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strReferenceId} = $CaptureReferenceId;
+ return CCR_NO_ERROR;
+}
+
+#
+# Set Reference Id
+# This should be used instead of SetCaptureReferenceId
+# Added in v1.6
+#
+sub SetReferenceId
+{
+ my $self = shift;
+ my $ReferenceId = shift; #take a string arguement
+ if (!defined($ReferenceId)){
+ $self->{strError} = "Reference id is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strReferenceId} = $ReferenceId;
+ return CCR_NO_ERROR;
+}
+
+#**
+# * Set a comment describing the order.
+# */
+sub SetOrderDescription
+{
+ my $self = shift;
+ my $OrderDescription = shift; #take a string arguement
+ if (!defined($OrderDescription)) {
+ $self->{strError} = "Order description is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strOrderDescription} = $OrderDescription;
+ return CCR_NO_ERROR;
+}
+
+
+#/**
+# * Set the order's user id. The order user id is an identifier
+# * for a merchant's customer. It is not required, but may provide
+# * increased searching functionality in the merchant support center.
+# */
+sub SetOrderUserId
+{
+ my $self = shift;
+ my $OrderUserId = shift; # take a string arguement
+ if (!defined($OrderUserId)) {
+ $self->{strError} = "Order user ID is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strOrderUserId} = $OrderUserId;
+ return CCR_NO_ERROR;
+}
+
+#**
+# * Set the bank approval code (used in force sale and force auth).
+# * This field is required if chargeType is FORCE_AUTH or FORCE_SALE.
+# */
+sub SetBankApprovalCode
+{
+ my $self = shift;
+ my $BankApprovalCode = shift; #take a string arguement
+ if (!defined($BankApprovalCode)){
+ $self->{strError} = "Bank Approval Code is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strBankApprovalCode} = $BankApprovalCode;
+ return CCR_NO_ERROR;
+}
+
+#**
+# * Set the duplicate check.
+# * Possible values are CHECK, OVERRIDE, NO_CHECK
+# */
+sub SetDuplicateCheck
+{
+ my $self = shift;
+ my $DuplicateCheck = shift; #take a string arguement
+ if (!defined($DuplicateCheck)){
+ $self->{strError} = "Duplicate Check is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strDuplicateCheck} = $DuplicateCheck;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the tax amount using a floating point value.
+# * The tax amount is the amount of the chargeTotal that is tax.
+# * <p>
+# * @param taxAmount Must be a positive floating-point number.
+# * E.g. Use <i>11.55</i> to represent $11.55.
+# * @exception TransactionProtocolException thrown if taxAmount less than zero
+# */
+sub SetTaxAmount
+{
+ my $self = shift;
+ my $TaxAmount = shift; # take a string or an integer arguement
+
+ if (!defined($TaxAmount)) {
+ $self->{strError} = "Tax amount is undefined.";
+ return CCR_ERROR;
+ }
+ if ( $TaxAmount !~ /^(\d+\.?\d*|\.\d+)$/ ) {
+ $self->{strError} = "Non-numeric tax amount.";
+ return CCR_ERROR;
+ }
+
+ my $dTaxAmount = $TaxAmount * 1.0;
+ if ($dTaxAmount < 0) {
+ $self->{strError} = "Tax amount cannot be negative.";
+ return CCR_ERROR;
+ }
+
+ $self->{dTaxAmount} = $dTaxAmount;
+ $self->{strTaxAmount} = "".$TaxAmount;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the shipping charge using a floating point value.
+# * The shipping charge is the amount of the chargeTotal that is shipping charges.
+# * <p>
+# * @param shippingCharge Must be a positive floating-point number.
+# * E.g. Use <i>11.55</i> to represent $11.55.
+# * @exception TransactionProtocolException thrown if shippingCharge less than zero
+# */
+sub SetShippingCharge
+{
+ my $self = shift;
+ my $ShippingCharge = shift; # take a string or an integer arguement
+
+ if (!defined($ShippingCharge)) {
+ $self->{strError} = "Shipping charge is undefined.";
+ return CCR_ERROR;
+ }
+ if ( $ShippingCharge !~ /^(\d+\.?\d*|\.\d+)$/ ) {
+ $self->{strError} = "Non-numeric shipping charge.";
+ return CCR_ERROR;
+ }
+
+ my $dShippingCharge = $ShippingCharge * 1.0;
+ if ($dShippingCharge < 0.00) {
+ $self->{strError} = "Shipping charge cannot be negative.";
+ return CCR_ERROR;
+ }
+
+ $self->{dShippingCharge} = $dShippingCharge;
+ $self->{strShippingCharge} = "".$ShippingCharge;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the first name of the customer being billed.
+# */
+sub SetBillFirstName
+{
+ my $self = shift;
+ my $BillFirstName = shift; # take a string arguement
+ if (!defined($BillFirstName)) {
+ $self->{strError} = "Bill first name is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strBillFirstName} = $BillFirstName;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the last name of the customer being billed.
+# */
+sub SetBillLastName
+{
+ my $self = shift;
+ my $BillLastName = shift; # take a string arguement
+ if (!defined($BillLastName)) {
+ $self->{strError} = "Bill last name is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strBillLastName} = $BillLastName;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the middle name of the customer being billed.
+#
+sub SetBillMiddleName
+{
+ my $self = shift;
+ my $BillMiddleName = shift; # take a string arguement
+ if (!defined($BillMiddleName)) {
+ $self->{strError} = "Bill middle name is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strBillMiddleName} = $BillMiddleName;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the title of the customer being billed, such as "Mr." or "Sales Manager".
+#/
+sub SetBillCustomerTitle
+{
+ my $self = shift;
+ my $BillCustomerTitle = shift; # take a string arguement
+ if (!defined($BillCustomerTitle)) {
+ $self->{strError} = "Bill customer title is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strBillCustomerTitle} = $BillCustomerTitle;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the name of the company of the customer being billed.
+# */
+sub SetBillCompany
+{
+ my $self = shift;
+ my $BillCompany = shift; # take a string arguement
+ if (!defined($BillCompany)) {
+ $self->{strError} = "Bill company is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strBillCompany} = $BillCompany;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the first part of the address of the customer being billed,
+# * such as "1455 Cedar Springs Drive".
+# */
+sub SetBillAddressOne
+{
+ my $self = shift;
+ my $BillAddressOne = shift; # take a string arguement
+ if (!defined($BillAddressOne)) {
+ $self->{strError} = "Bill address one is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strBillAddressOne} = $BillAddressOne;
+ return CCR_NO_ERROR;
+}
+
+
+#*
+# * Set the second part of the address of the customer being billed,
+# * such as "Suite 100".
+# */
+sub SetBillAddressTwo
+{
+ my $self = shift;
+ my $BillAddressTwo = shift; # take a string arguement
+ if (!defined($BillAddressTwo)) {
+ $self->{strError} = "Bill address two is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strBillAddressTwo} = $BillAddressTwo;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the city of the customer being billed.
+# */
+sub SetBillCity
+{
+ my $self = shift;
+ my $BillCity = shift; # take a string arguement
+ if (!defined($BillCity)) {
+ $self->{strError} = "Bill city is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strBillCity} = $BillCity;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the state or province of the customer being billed.
+# */
+sub SetBillStateOrProvince
+{
+ my $self = shift;
+ my $BillStateOrProvince = shift; # take a string arguement
+ if (!defined($BillStateOrProvince)) {
+ $self->{strError} = "Bill state or province is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strBillStateOrProvince} = $BillStateOrProvince;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the postal code (or zip code) of the customer being billed.
+# */
+sub SetBillPostalCode
+{
+ my $self = shift;
+ my $BillPostalCode = shift; # take a string arguement
+ if (!defined($BillPostalCode)) {
+ $self->{strError} = "Bill postal code is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strBillPostalCode} = $BillPostalCode;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * @param billCountryCode The alphabetic country code of the billing address.
+# * Must be a valid country code from ISO-3166. E.g. "CA" or "US".
+# * <p>
+# * @see com.paygateway.CountryCodes
+# * @exception TransactionProtocolException thrown if an invalid country code is passed in
+# */
+sub SetBillCountryCode
+{
+ my $self = shift;
+ my $BillCountryCode = shift; # take a string arguement (either country code or country name)
+
+ if (!defined($BillCountryCode)) {
+ $self->{strError} = "Country code is undefined.";
+ return CCR_ERROR;
+ }
+ my $CountryCode = getCCodeFromCName($BillCountryCode);
+ if (isValidCountryCode($BillCountryCode)) {
+ $self->{strBillCountryCode} = $BillCountryCode;
+ return CCR_NO_ERROR;
+ }
+ elsif (defined($CountryCode)) {
+ $self->{strBillCountryCode} = $CountryCode;
+ return CCR_NO_ERROR;
+ }
+ else {
+ $self->{strError} = "Invalid country code for billing address.";
+ return CCR_ERROR;
+ }
+}
+
+
+#**
+# * Set the email address of the customer being billed.
+# */
+sub SetBillEmail
+{
+ my $self = shift;
+ my $BillEmail = shift;
+ if (!defined($BillEmail)) {
+ $self->{strError} = "Bill email is undefined.";
+ return CCR_ERROR;
+ }
+ if ($BillEmail !~ /.+@.+\..+/ ) {
+ $self->{strError} = "Invalid bill email format.";
+ return CCR_ERROR;
+ }
+ $self->{strBillEmail} = $BillEmail;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+#* Set the phone number
+#*/
+sub SetBillPhone
+{
+ my $self = shift;
+ my $BillPhone = shift; # take a string arguement
+ if (!defined($BillPhone)) {
+ $self->{strError} = "Bill phone is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strBillPhone} = $BillPhone;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the facsimile number of the customer being billed.
+# */
+sub SetBillFax
+{
+ my $self = shift;
+ my $BillFax = shift;
+ if (!defined($BillFax)) {
+ $self->{strError} = "Bill fax is undefined";
+ return CCR_ERROR;
+ }
+ $self->{strBillFax} = $BillFax;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the billing note. This a comment about the billing information.
+# */
+sub SetBillNote
+{
+ my $self = shift;
+ my $BillNote = shift; #take a string arguement
+ if (!defined($BillNote)) {
+ $self->{strError} = "Bill note is undefined";
+ return CCR_ERROR;
+ }
+ $self->{strBillNote} = $BillNote;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the first name for the shipping information.
+# */
+sub SetShipFirstName
+{
+ my $self = shift;
+ my $ShipFirstName = shift; # take a string arguement
+ if (!defined($ShipFirstName)) {
+ $self->{strError} = "Ship first name is undefined";
+ return CCR_ERROR;
+ }
+ $self->{strShipFirstName} = $ShipFirstName;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the last name for the shipping information.
+# */
+sub SetShipLastName
+{
+ my $self = shift;
+ my $ShipLastName = shift; # take a string arguement
+ if (!defined($ShipLastName)) {
+ $self->{strError} = "Ship last is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strShipLastName} = $ShipLastName;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the middle name for the shipping information.
+# */
+sub SetShipMiddleName
+{
+ my $self = shift;
+ my $ShipMiddleName = shift; # take a string arguement
+
+ if (!defined($ShipMiddleName)) {
+ $self->{strError} = "Ship middle name is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strShipMiddleName} = $ShipMiddleName;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the customer title of the customer being jstrShipped to.
+# */
+sub SetShipCustomerTitle
+{
+ my $self = shift;
+ my $ShipCustomerTitle = shift; # take a string arguement
+ if (!defined($ShipCustomerTitle)) {
+ $self->{strError} = "Ship customer title is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strShipCustomerTitle} = $ShipCustomerTitle;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the company for the shipping information.
+# */
+sub SetShipCompany
+{
+ my $self = shift;
+ my $ShipCompany = shift; # take a string arguement
+ if (!defined($ShipCompany)) {
+ $self->{strError} = "Ship company is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strShipCompany} = $ShipCompany;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the first part of the shipping address, such as
+# * "485 Bridestone Way".
+# */
+sub SetShipAddressOne
+{
+ my $self = shift;
+ my $ShipAddressOne = shift; # take a string arguement
+ if (!defined($ShipAddressOne)) {
+ $self->{strError} = "Ship address is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strShipAddressOne} = $ShipAddressOne;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the second part of the shipping address, such as
+# * "Suite 234".
+
+sub SetShipAddressTwo
+{
+ my $self = shift;
+ my $ShipAddressTwo = shift; # take a string arguement
+ if (!defined($ShipAddressTwo)) {
+ $self->{strError} = "Ship address two is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strShipAddressTwo} = $ShipAddressTwo;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the city for the shipping address.
+# */
+sub SetShipCity
+{
+ my $self = shift;
+ my $ShipCity = shift; # take a string arguement
+ if (!defined($ShipCity)) {
+ $self->{strError} = "Ship city is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strShipCity} = $ShipCity;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the state or provicnce for the shipping address.
+# */
+sub SetShipStateOrProvince
+{
+ my $self = shift;
+ my $ShipStateOrProvince = shift; # take a string arguement
+ if (!defined($ShipStateOrProvince)) {
+ $self->{strError} = "Ship state or province is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strShipStateOrProvince} = $ShipStateOrProvince;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the postal code (or zip code) for the shipping address.
+# */
+sub SetShipPostalCode
+{
+ my $self = shift;
+ my $ShipPostalCode = shift; # take a string arguement
+ if (!defined($ShipPostalCode)) {
+ $self->{strError} = "Ship postal code is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strShipPostalCode} = $ShipPostalCode;
+ return CCR_NO_ERROR;
+}
+
+#**
+# * Set the shipping country code.
+# * @param shipCountryCode The alphabetic country code of the billing address.
+# * Must be a valid country code from ISO-3166. E.g. "CA" or "US".
+# * <p>
+# * @see com.paygateway.CountryCodes
+# * @exception TransactionProtocolException thrown if an invalid country code is passed in
+# */
+sub SetShipCountryCode
+{
+ my $self = shift;
+ my $ShipCountryCode = shift; # take a string arguement (either country code or country name)
+
+ if (!defined($ShipCountryCode)) {
+ $self->{strError} = "Ship country code is undefined.";
+ return CCR_ERROR;
+ }
+ my $CountryCode = getCCodeFromCName($ShipCountryCode) ;
+ if (isValidCountryCode($ShipCountryCode)) {
+ $self->{strShipCountryCode} = $ShipCountryCode;
+ return CCR_NO_ERROR;
+ }
+ elsif (defined($CountryCode)) {
+ $self->{strShipCountryCode} = $CountryCode;
+ return CCR_NO_ERROR;
+ }
+ else {
+ $self->{strError} = "Invalid country code for shipping address";
+ return CCR_ERROR;
+ }
+}
+
+
+#**
+# * Set the email address of the customer being shipped to.
+# */
+sub SetShipEmail
+{
+ my $self = shift;
+ my $ShipEmail = shift; # take a string arguement
+ if (!defined($ShipEmail)) {
+ $self->{strError} = "Ship email is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strShipEmail} = $ShipEmail;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the phone number of the customer being shipped to.
+# */
+sub SetShipPhone
+{
+ my $self = shift;
+ my $ShipPhone = shift; # take a string arguement
+ if (!defined($ShipPhone)) {
+ $self->{strError} = "Ship phone is undefined";
+ return CCR_ERROR;
+ }
+ $self->{strShipPhone} = $ShipPhone;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the facsimile number of the customer being shipped to.
+# */
+sub SetShipFax
+{
+ my $self = shift;
+ my $ShipFax = shift; # take a string arguement
+ if (!defined($ShipFax)) {
+ $self->{strError} = "Ship fax is undefined";
+ return CCR_ERROR;
+ }
+ $self->{strShipFax} = $ShipFax;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set a note (comment) for the shipping information.
+# */
+sub SetShipNote
+{
+ my $self = shift;
+ my $ShipNote = shift;
+ if (!defined($ShipNote)) {
+ $self->{strError} = "Ship note is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strShipNote} = $ShipNote;
+ return CCR_NO_ERROR;
+}
+
+
+#/**
+# * Sets the currency
+# */
+sub SetCurrency
+{
+ my $self = shift;
+ my $Currency = shift; # take a string arguement
+ if (!defined($Currency)) {
+ $self->{strError} = "Currency is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strCurrency} = $Currency;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets the buyer code
+# */
+sub SetBuyerCode
+{
+ my $self = shift;
+ my $buyerCode = shift; # take a string arguement
+ if (!defined($buyerCode)) {
+ $self->{strError} = "Buyer code is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strBuyerCode} = $buyerCode;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets the CAVV (for VBV transactions)
+# */
+sub SetCAVV
+{
+ my $self = shift;
+ my $cavv = shift; # take a string arguement
+ if (!defined($cavv)) {
+ $self->{strError} = "CAVV is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strCAVV} = $cavv;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets the Customer IP Address
+# */
+sub SetCustomerIPAddress
+{
+ my $self = shift;
+ my $ip = shift; # take a string arguement
+ if (!defined($ip)) {
+ $self->{strError} = "Customer IP address is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strCustomerIPAddress} = $ip;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets the Order Customer ID
+# */
+sub SetOrderCustomerId
+{
+ my $self = shift;
+ my $orderCustomerID = shift; # take a string arguement
+ if (!defined($orderCustomerID)) {
+ $self->{strError} = "Order customer ID is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strOrderCustomerID} = $orderCustomerID;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets the purchase order number
+# */
+sub SetPurchaseOrderNumber
+{
+ my $self = shift;
+ my $purchaseOrderNumber = shift; # take a string arguement
+ if (!defined($purchaseOrderNumber)) {
+ $self->{strError} = "Purchase order number is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strPurchaseOrderNumber} = $purchaseOrderNumber;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets the state tax
+# */
+sub SetStateTax
+{
+ my $self = shift;
+ my $stateTax = shift; # take a string arguement
+ if (!defined($stateTax)) {
+ $self->{strError} = "State tax is undefined.";
+ return CCR_ERROR;
+ }
+
+ if ( $stateTax !~ /^(\d+\.?\d*|\.\d+)$/ ) {
+ $self->{strError} = "Non-numeric state tax amount.";
+ return CCR_ERROR;
+ }
+
+ $stateTax = $stateTax * 1.0;
+ if ($stateTax < 0) {
+ $self->{strError} = "State tax cannot be negative.";
+ return CCR_ERROR;
+ }
+
+ $self->{dStateTax} = $stateTax;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets the track 1 data
+# */
+sub SetTrack1
+{
+ my $self = shift;
+ my $track1 = shift; # take a string arguement
+ if (!defined($track1)) {
+ $self->{strError} = "Track 1 is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strTrack1} = $track1;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets the track 2 data
+# */
+sub SetTrack2
+{
+ my $self = shift;
+ my $track2 = shift; # take a string arguement
+ if (!defined($track2)) {
+ $self->{strError} = "Track 2 is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strTrack2} = $track2;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets the transaction condition code
+# */
+sub SetTransactionConditionCode
+{
+ my $self = shift;
+ my $tcc = shift; # take a string arguement
+ if (!defined($tcc)) {
+ $self->{strError} = "Transaction condition code is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strTransactionConditionCode} = $tcc;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets the xid
+# */
+sub SetXID
+{
+ my $self = shift;
+ my $xid = shift; # take a string arguement
+ if (!defined($xid)) {
+ $self->{strError} = "XID is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strXID} = $xid;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets tax exempt flag
+# */
+sub SetTaxExempt
+{
+ my $self = shift;
+ my $taxExempt = shift; # take a string arguement
+ if (!defined($taxExempt)) {
+ $self->{strError} = "Tax exempt flag is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{boolTaxExempt} = $taxExempt;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets invoice number
+# */
+sub SetInvoiceNumber
+{
+ my $self = shift;
+ my $invoiceNumber = shift; # take a string arguement
+ if (!defined($invoiceNumber)) {
+ $self->{strError} = "Invoice number is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strInvoiceNumber} = $invoiceNumber;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets the Authentication Transaction ID
+# *
+# * Used in Payer Authentication transaction type
+# */
+sub SetAuthenticationTransactionId
+{
+ my $self = shift;
+ my $authenticationTransactionId = shift; # take a string arguement
+ if (!defined($authenticationTransactionId)) {
+ $self->{strError} = "Authentication Transaction ID is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strAuthenticationTransactionId} = $authenticationTransactionId;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets the Authentication Payload
+# *
+# * Used in Payer Authentication transaction type
+# */
+sub SetAuthenticationPayload
+{
+ my $self = shift;
+ my $authenticationPayload = shift; # take a string arguement
+ if (!defined($authenticationPayload)) {
+ $self->{strError} = "Authentication Payload is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strAuthenticationPayload} = $authenticationPayload;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets the Success On Authentication Inconclusive
+# *
+# * Used in Payer Authentication transaction type
+# */
+sub SetDoTransactionOnAuthenticationInconclusive
+{
+ my $self = shift;
+ my $successOnAuthenticationInconclusive = shift; # take a string arguement
+ if (!defined($successOnAuthenticationInconclusive)) {
+ $self->{strError} = "Success on authentication inconclusive is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{boolSuccessOnAuthenticationInconclusive} = $successOnAuthenticationInconclusive;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the Industry type.
+# * <p>
+# * @param industry Must be one of the following constants: DIRECT_MARKETING, RETAIL, LODGING, RESTAURANT.
+# * @exception TransactionProtocolException thrown if industry is not a valid charge type
+# * defined by this class.
+# */
+sub SetIndustry
+{
+ my $self = shift;
+ my $industry = shift; # take one string arguement
+
+ if (!defined($industry)) {
+ $self->{strError} = "Industry is undefined.";
+ return CCR_ERROR;
+ }
+ if ($industry eq "") {
+ $self->{strError} = "Invalid industry";
+ return CCR_ERROR;
+ }
+
+ if (!($industry eq DIRECT_MARKETING ||
+ $industry eq RETAIL ||
+ $industry eq LODGING ||
+ $industry eq RESTAURANT )) {
+ $self->{strError} = "Invalid industry.";
+ return CCR_ERROR;
+ }
+ $self->{strIndustry} = $industry;
+ return CCR_NO_ERROR;
+}
+
+
+#/**
+# * Sets folio number
+# */
+sub SetFolioNumber
+{
+ my $self = shift;
+ my $folioNumber = shift; # take a string arguement
+ if (!defined($folioNumber)) {
+ $self->{strError} = "Folio number is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{strFolioNumber} = $folioNumber;
+ return CCR_NO_ERROR;
+}
+
+
+
+#**
+# * Set the service rate using a floating point value.
+# * <p>
+# * @param ServiceRate Must be a positive floating-point number.
+# * E.g. Use <i>11.55</i> to represent $11.55.
+# * @exception TransactionProtocolException thrown if ServiceRate less than zero
+# */
+sub SetServiceRate
+{
+ my $self = shift;
+ my $ServiceRate = shift; # take a string or an integer arguement
+
+ if (!defined($ServiceRate)) {
+ $self->{strError} = "Service rate is undefined.";
+ return CCR_ERROR;
+ }
+ if ( $ServiceRate !~ /^(\d+\.?\d*|\.\d+)$/ ) {
+ $self->{strError} = "Non-numeric Service Rate.";
+ return CCR_ERROR;
+ }
+
+ my $dServiceRate = $ServiceRate * 1.0;
+ if ($dServiceRate < 0) {
+ $self->{strError} = "Service rate cannot be negative.";
+ return CCR_ERROR;
+ }
+
+ $self->{dServiceRate} = $dServiceRate;
+ $self->{strServiceRate} = "".$ServiceRate;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * Set the service end day
+# */
+sub SetServiceEndDay
+{
+ my $self = shift;
+ my $serviceEndDay = shift; #take one string arguement
+ if (!defined($serviceEndDay)) {
+ $self->{strError} = "Service end day is undefined.";
+ return CCR_ERROR;
+ }
+ if ($serviceEndDay eq ""){
+ $self->{strError} = "Invalid service end day.";
+ return CCR_ERROR;
+ }
+
+ if ($serviceEndDay =~ /\D/) {
+ $self->{strError} = "Invalid service end day (non-digit).";
+ return CCR_ERROR;
+ }
+
+ $serviceEndDay = 1 * $serviceEndDay;
+ if ($serviceEndDay < 1 || $serviceEndDay > 31) {
+ $self->{strError} .= "Invalid service end day (not 1 through 31).";
+ return CCR_ERROR;
+ }
+ $self->{intServiceEndDay} = $serviceEndDay;
+
+ return 1;
+}
+
+
+#**
+# * Set the service end month
+# */
+sub SetServiceEndMonth
+{
+ my $self = shift;
+ my $serviceEndMonth = shift; #take one string arguement
+ if (!defined($serviceEndMonth)) {
+ $self->{strError} = "Service end month is undefined.";
+ return CCR_ERROR;
+ }
+ if ($serviceEndMonth eq ""){
+ $self->{strError} = "Invalid service end month.";
+ return CCR_ERROR;
+ }
+
+ if ($serviceEndMonth =~ /\D/) {
+ $self->{strError} = "Invalid service end month (non-digit).";
+ return CCR_ERROR;
+ }
+
+ $serviceEndMonth = 1 * $serviceEndMonth;
+ if ($serviceEndMonth < 1 || $serviceEndMonth > 12) {
+ $self->{strError} .= "Invalid service end month (not 1 through 12).";
+ return CCR_ERROR;
+ }
+ $self->{intServiceEndMonth} = $serviceEndMonth;
+
+ return 1;
+}
+
+#**
+# * Set the service end year
+# */
+sub SetServiceEndYear
+{
+ my $self = shift;
+ my $serviceEndYear = shift; #take one string arguement
+ if (!defined($serviceEndYear)) {
+ $self->{strError} = "Service end year is undefined.";
+ return CCR_ERROR;
+ }
+ if ($serviceEndYear eq ""){
+ $self->{strError} = "Invalid service end year.";
+ return CCR_ERROR;
+ }
+
+ if ($serviceEndYear =~ /\D/) {
+ $self->{strError} = "Invalid service end year (non-digit).";
+ return CCR_ERROR;
+ }
+
+ $serviceEndYear = 1 * $serviceEndYear;
+ if ($serviceEndYear < 2005 || $serviceEndYear > 9999) {
+ $self->{strError} .= "Invalid service end year.";
+ return CCR_ERROR;
+ }
+ $self->{intServiceEndYear} = $serviceEndYear;
+
+ return 1;
+}
+
+
+#**
+# * Set the service start day
+# */
+sub SetServiceStartDay
+{
+ my $self = shift;
+ my $serviceStartDay = shift; #take one string arguement
+ if (!defined($serviceStartDay)) {
+ $self->{strError} = "Service start day is undefined.";
+ return CCR_ERROR;
+ }
+ if ($serviceStartDay eq ""){
+ $self->{strError} = "Invalid service start day.";
+ return CCR_ERROR;
+ }
+
+ if ($serviceStartDay =~ /\D/) {
+ $self->{strError} = "Invalid service start day (non-digit).";
+ return CCR_ERROR;
+ }
+
+ $serviceStartDay = 1 * $serviceStartDay;
+ if ($serviceStartDay < 1 || $serviceStartDay > 31) {
+ $self->{strError} .= "Invalid service start day (not 1 through 31).";
+ return CCR_ERROR;
+ }
+ $self->{intServiceStartDay} = $serviceStartDay;
+
+ return 1;
+}
+
+
+#**
+# * Set the service start month
+# */
+sub SetServiceStartMonth
+{
+ my $self = shift;
+ my $serviceStartMonth = shift; #take one string arguement
+ if (!defined($serviceStartMonth)) {
+ $self->{strError} = "Service start month is undefined.";
+ return CCR_ERROR;
+ }
+ if ($serviceStartMonth eq ""){
+ $self->{strError} = "Invalid service start month.";
+ return CCR_ERROR;
+ }
+
+ if ($serviceStartMonth =~ /\D/) {
+ $self->{strError} = "Invalid service start month (non-digit).";
+ return CCR_ERROR;
+ }
+
+ $serviceStartMonth = 1 * $serviceStartMonth;
+ if ($serviceStartMonth < 1 || $serviceStartMonth > 12) {
+ $self->{strError} .= "Invalid service start month (not 1 through 12).";
+ return CCR_ERROR;
+ }
+ $self->{intServiceStartMonth} = $serviceStartMonth;
+
+ return 1;
+}
+
+#**
+# * Set the service start year
+# */
+sub SetServiceStartYear
+{
+ my $self = shift;
+ my $serviceStartYear = shift; #take one string arguement
+ if (!defined($serviceStartYear)) {
+ $self->{strError} = "Service start year is undefined.";
+ return CCR_ERROR;
+ }
+ if ($serviceStartYear eq ""){
+ $self->{strError} = "Invalid service start year.";
+ return CCR_ERROR;
+ }
+
+ if ($serviceStartYear =~ /\D/) {
+ $self->{strError} = "Invalid service start year (non-digit).";
+ return CCR_ERROR;
+ }
+
+ $serviceStartYear = 1 * $serviceStartYear;
+ if ($serviceStartYear < 2005 || $serviceStartYear > 9999) {
+ $self->{strError} .= "Invalid service start year.";
+ return CCR_ERROR;
+ }
+ $self->{intServiceStartYear} = $serviceStartYear;
+
+ return 1;
+}
+
+
+
+#/**
+# * Sets the Charge Total Includes Restaurant flag
+# *
+# */
+sub SetChargeTotalIncludesRestaurant
+{
+ my $self = shift;
+ my $isChargeTotalIncludesRestaurant = shift; # take a string arguement
+ if (!defined($isChargeTotalIncludesRestaurant)) {
+ $self->{strError} = "Charge Total Includes Restaurant is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{boolChargeTotalIncludesRestaurant} = $isChargeTotalIncludesRestaurant;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets the Charge Total Includes Giftshop flag
+# *
+# */
+sub SetChargeTotalIncludesGiftshop
+{
+ my $self = shift;
+ my $isChargeTotalIncludesGiftshop = shift; # take a string arguement
+ if (!defined($isChargeTotalIncludesGiftshop)) {
+ $self->{strError} = "Charge Total Includes Giftshop is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{boolChargeTotalIncludesGiftshop} = $isChargeTotalIncludesGiftshop;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets the Charge Total Includes Minibar flag
+# *
+# */
+sub SetChargeTotalIncludesMinibar
+{
+ my $self = shift;
+ my $isChargeTotalIncludesMinibar = shift; # take a string arguement
+ if (!defined($isChargeTotalIncludesMinibar)) {
+ $self->{strError} = "Charge Total Includes Minibar is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{boolChargeTotalIncludesMinibar} = $isChargeTotalIncludesMinibar;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets the Charge Total Includes Phone flag
+# *
+# */
+sub SetChargeTotalIncludesPhone
+{
+ my $self = shift;
+ my $isChargeTotalIncludesPhone = shift; # take a string arguement
+ if (!defined($isChargeTotalIncludesPhone)) {
+ $self->{strError} = "Charge Total Includes Phone is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{boolChargeTotalIncludesPhone} = $isChargeTotalIncludesPhone;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets the Charge Total Includes Laundry flag
+# *
+# */
+sub SetChargeTotalIncludesLaundry
+{
+ my $self = shift;
+ my $isChargeTotalIncludesLaundry = shift; # take a string arguement
+ if (!defined($isChargeTotalIncludesLaundry)) {
+ $self->{strError} = "Charge Total Includes Laundry is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{boolChargeTotalIncludesLaundry} = $isChargeTotalIncludesLaundry;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets the Charge Total Includes Other flag
+# *
+# */
+sub SetChargeTotalIncludesOther
+{
+ my $self = shift;
+ my $isChargeTotalIncludesOther = shift; # take a string arguement
+ if (!defined($isChargeTotalIncludesOther)) {
+ $self->{strError} = "Charge Total Includes Other is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{boolChargeTotalIncludesOther} = $isChargeTotalIncludesOther;
+ return CCR_NO_ERROR;
+}
+
+#/**
+# * Sets the Service No Show flag
+# *
+# */
+sub SetServiceNoShow
+{
+ my $self = shift;
+ my $isServiceNoShow = shift; # take a string arguement
+ if (!defined($isServiceNoShow)) {
+ $self->{strError} = "Service No Show is undefined.";
+ return CCR_ERROR;
+ }
+ $self->{boolServiceNoShow} = $isServiceNoShow;
+ return CCR_NO_ERROR;
+}
+
+
+
+#/////////////////////////////////////////////////////////////////////////////////////////////////////
+#// Get Methods.
+#
+
+#/**
+# * Get the cartridge type.
+# * @returns the type of cartridge being used
+# */
+sub GetCartridgeType
+{
+ my $self = shift;
+ $self->{strCartridgeType};
+}
+
+#/**
+# * Get the Ecommerce Indicator
+# * @returns the Ecommerce Indicator
+# */
+sub GetEcommerceIndicator
+{
+ my $self = shift;
+ $self->{strEcommerceIndicator};
+}
+
+#/**
+# * Get the value of the credit card number.
+# * @see #setCreditCardNumber(JString)
+# * @return the value of the credit card number or an empty String if the credit card number was not set
+# */
+sub GetCreditCardNumber
+{
+ my $self = shift;
+ $self->{strCreditCardNumber};
+}
+
+#/**
+# * Get the value of the credit card number.
+# * @return the value of the credit card verification number or an empty String if the credit card number was not set
+# */
+sub GetCreditCardVerificationNumber
+{
+ my $self = shift;
+ $self->{strCreditCardVerificationNumber};
+}
+
+#**
+# * Get the value of the credit card's expire year.
+# * @see #setExpireYear(JString)
+# * @return the String passed to setExpireYear or an empty String if the expire year was not set
+# */
+sub GetExpireYear
+{
+ my $self = shift;
+ $self->{strExpireYear};
+}
+
+
+#**
+# * Get the value of the credit card's expire month.
+# * @see #setExpireMonth(String)
+# * @return the String passed to setExpireMonth or an empty String if the expire month was not set
+# */
+sub GetExpireMonth
+{
+ my $self = shift;
+ $self->{strExpireMonth};
+}
+
+
+#**
+# * Get the value of the charge type. The possible values are defined
+# * by the constants of this class documented in setChargeType(String)
+# * The chage type indicates what action to take with this credit card
+# * transaction.
+# * @see #setChargeType(String)
+# * @return the String passed to setChargeType or an empty String if the charge type was not set
+#
+sub GetChargeType()
+{
+ my $self = shift;
+ $self->{strChargeType};
+}
+
+
+#**
+# * Get the value of the charge total. The charge total is the amount that
+# * will be used for this credit card transaction.
+# * @see #setChargeTotal(double)
+# * @see #setChargeTotal(String)
+# * @return the value of the charge total or -1 if the charge total was not set
+#
+sub GetChargeTotal
+{
+ my $self = shift;
+ $self->{dChargeTotal};
+}
+
+sub GetChargeTotalStr
+{
+ my $self = shift;
+ $self->{strChargeTotal};
+}
+
+#**
+# * Get the value of the card brand. The card brand identifies the type
+# * of card being used. The card brand must be one of the constants defined
+# * by this class and documented in setCardBrand(JString)
+# * @see #setCardBrand(JString)
+# * @return the value of the card brand or an empty String if the card brand was not set
+#/
+sub GetCardBrand
+{
+ my $self = shift;
+ $self->{strCardBrand};
+}
+
+#**
+# * Get the value of the order id. The order id must be a unique identifier
+# * for a paticular order.
+# * @see #setOrderId(JString)
+# * @return the value of the order id or an empty String if the order id was not set
+# */
+sub GetOrderId
+{
+ my $self = shift;
+ $self->{strOrderId};
+}
+
+
+
+#**
+# * Get the value of the capture reference id. The capture reference id is the
+# * value returned from an "AUTH" credit card transaction that must be presented
+# * when to the "CAPTURE" for that order.
+# * @see #setCaptureReferenceId(JString)
+# * @return the value of the capture reference id or an empty String if the capture reference id was not set
+#
+sub GetCaptureReferenceId
+{
+ my $self = shift;
+ $self->{strReferenceId};
+}
+
+#
+# Get Reference Id
+# This should be used instead of GetCaptureReferenceId
+# Added in v1.6
+#
+sub GetReferenceId
+{
+ my $self = shift;
+ $self->{strReferenceId};
+}
+
+#/**
+# * Get the value of the order description. The order description is a comment
+# * that describes the order.
+# * @see #setOrderDescription(JString)
+# * @return the value of the order description or an empty String if the order description was not set
+#/
+sub GetOrderDescription
+{
+ my $self = shift;
+ $self->{strOrderDescription};
+}
+
+#**
+# * Get the value of the order user id. The order user id is a unique identifier
+# * for a merchant's customer.
+# * @see #setOrderUserId(String)
+# * @return the value of the order user id of an empty String if order user id was not set
+#
+sub GetOrderUserId
+{
+ my $self = shift;
+ $self->{strOrderUserId};
+}
+
+#**
+# * Get the value of the duplicate check.
+# * Possible values are: CHECK; OVERRIDE; NO_CHECK.
+# * @see #setDuplicateCheck(String)
+# * @return the value of the duplicate check or an empty String if the dc was not set
+#
+sub GetDuplicateCheck
+{
+ my $self = shift;
+ $self->{strDuplicateCheck};
+}
+
+
+#**
+# * Get the value of the bank approval code. The bank approval code is the
+# * value required for a "FORCE_AUTH" or "FORCE_SALE" credit card transaction.
+# * It is obtained offline via a phone call to the merchant's bank 'voice auth'
+# * phone number. The card holder is not present in this type of transaction.
+# * @see #setBankApprovalCode(String)
+# * @return the value of the bank approval code or an empty String if the bac was not set
+#
+sub GetBankApprovalCode
+{
+ my $self = shift;
+ $self->{strBankApprovalCode};
+}
+
+
+#**
+# * The tax amount is the amount of the the charge total that is tax.
+# * @see #setTaxAmount
+# * @see #setChargeTotal
+# * @return value of the tax amount of -1 if the tax amount has not been set.
+#
+sub GetTaxAmount
+{
+ my $self = shift;
+ $self->{dTaxAmount};
+}
+
+sub GetTaxAmountStr
+{
+ my $self = shift;
+ $self->{strTaxAmount};
+}
+
+
+#**
+# * The shipping charge is the amount of the charge total that is shipping charges.
+# * @see #setShippingCharge
+# * @see #setChargeTotal
+# * @return value of the shipping charge or -1 if the shipping charge has not been set
+# */
+sub GetShippingCharge
+{
+ my $self = shift;
+ $self->{dShippingCharge};
+}
+
+sub GetShippingChargeStr
+{
+ my $self = shift;
+ $self->{strShippingCharge};
+}
+
+
+#/**
+# * Get the value of the first name of the customer being billed.
+# * @see #setBillFirstName(JString)
+# * @return the billing first name or an empty String if the billing first name was not set
+# */
+sub GetBillFirstName
+{
+ my $self = shift;
+ $self->{strBillFirstName};
+}
+
+
+#**
+# * Get the value of the last name of the customer being billed.
+# * @see #setBillLastName(String)
+# * return the billing last name or an empty String if the billing last name was not set
+# */
+sub GetBillLastName
+{
+ my $self = shift;
+ $self->{strBillLastName};
+}
+
+
+#**
+# * Get the value of the middle name of the customer being billed.
+# * @see #setBillMiddleName(JString)
+# * @return the billing middle name or an empty String if the billing middle name was not set
+# */
+sub GetBillMiddleName
+{
+ my $self = shift;
+ $self->{strBillMiddleName};
+}
+
+
+#**
+# * Get the value of the title of the customer being billed.
+# * @see #setBillCustomerTitle(JString)
+# * @return the billing customer title or an empty String if billing customer title was not set
+# */
+sub GetBillCustomerTitle
+{
+ my $self = shift;
+ $self->{strBillCustomerTitle};
+}
+
+#**
+# * Get the value of the company name of the customer being billed.
+# * @see #setBillCompany(JString)
+# * @return the billing company name or an empty String if the billing company name was not set
+#
+sub GetBillCompany
+{
+ my $self = shift;
+ $self->{strBillCompany};
+}
+
+
+#**
+# * Get the value of the first part of the billing address.
+# * @see #setBillAddressOne(JString)
+# * @return the first part of the billing address or an empty String if the billing address part one was not set
+# */
+sub GetBillAddressOne
+{
+ my $self = shift;
+ $self->{strBillAddressOne};
+}
+
+
+#**
+# * Get the value of the second part of the billing address.
+# * @see #setBillAddressTwo(JString)
+# * @return the second part of the billing address or an empty String if the billing address part two was not set
+# */
+sub GetBillAddressTwo
+{
+ my $self = shift;
+ $self->{strBillAddressTwo};
+}
+
+
+#**
+# * Get the value of the city for the billing address.
+# * @see #setBillCity(JString)
+# * @return the billing address city or an empty String if the billing city was not set
+# */
+sub GetBillCity
+{
+ my $self = shift;
+ $self->{strBillCity};
+}
+
+
+#**
+# * Get the value of the state or province for the billing address.
+# * @see #setBillStateOrProvince(String)
+# * @return the billing address state or province or an empty String if billing state or province was not set
+# */
+sub GetBillStateOrProvince
+{
+ my $self = shift;
+ $self->{strBillStateOrProvince};
+}
+
+
+#**
+# * Get the value of the postal code for the billing address.
+# * @see #setBillPostalCode(String)
+# * @return the billing address postal code or an empty String if billing postal code was not set
+#*/
+sub GetBillPostalCode
+{
+ my $self = shift;
+ $self->{strBillPostalCode};
+}
+
+
+#**
+# * Get the value of the country for the billing address.
+# * @see #setBillCountryCode(JString)
+# * @return the billing country or an empty String if the billing country was not set
+#
+sub GetBillCountryCode
+{
+ my $self = shift;
+ $self->{strBillCountryCode};
+}
+
+
+#**
+# * Get the value of the email address of the customer being billed.
+# * @see #setBillEmail(JString)
+# * @return the billing email address or an empty String if the billing email was not set
+#
+sub GetBillEmail
+{
+ my $self = shift;
+ $self->{strBillEmail};
+}
+
+
+#**
+# * Get the value of the phone number of the customer being billed.
+# * @see #setBillPhone(JString)
+# * @return the billing phone number or an empty String if the billing phone number was not set
+# */
+sub GetBillPhone
+{
+ my $self = shift;
+ $self->{strBillPhone};
+}
+
+
+#**
+# * Get the value of the fax number of the customer being billed.
+# * @see #setBillFax(JString)
+# * @return the billing fax number or an empty String if the billing fax number was not set
+# */
+sub GetBillFax
+{
+ my $self = shift;
+ $self->{strBillFax};
+}
+
+
+#**
+# * Get the value of the billing note. The billing note is an extra
+# * comment to the billing information.
+# * @see #setBillNote(JString)
+# * @return the billing note or an empty String if the billing not was not set
+#
+sub GetBillNote
+{
+ my $self = shift;
+ $self->{strBillNote};
+}
+
+#**
+# * Get the value of the first name of the customer being shipped to.
+# * @see #setShipFirstName(JString)
+# * @return the shipping first name or an empty String if the shipping first name was not set
+#
+sub GetShipFirstName
+{
+ my $self = shift;
+ $self->{strShipFirstName};
+}
+
+
+#**
+# * Get the value of the last name of the customer being shipped to.
+# * @see #setShipLastName(JString)
+# * @return the shipping last name or an empty String if the shipping last name was not set
+# */
+sub GetShipLastName
+{
+ my $self = shift;
+ $self->{strShipLastName};
+}
+
+
+#**
+# * Get the value of the middle name of the customer being shipped to.
+# * @see #setShipMiddleName(JString)
+# * @return the shipping middle name or an empty String if the shipping middle name was not set
+# */
+sub GetShipMiddleName
+{
+ my $self = shift;
+ $self->{strShipMiddleName};
+}
+
+
+#**
+# * Get the value of the title of the customer being shipped to.
+# * @see #setShipCustomerTitle(String)
+# * @return the shipping customer title or an empty String if the shipping customer title was not set
+#
+sub GetShipCustomerTitle
+{
+ my $self = shift;
+ $self->{strShipCustomerTitle};
+}
+
+
+#**
+# * Get the value of the company name of the customer being shipped to.
+# * @see #setShipCompany(JString)
+# * @return the shipping company name or an empty String if the shipping company name was not set
+# */
+sub GetShipCompany
+{
+ my $self = shift;
+ $self->{strShipCompany};
+}
+
+
+#**
+# * Get the value of the first part of the shipping address.
+# * @see #setShipAddressOne(JString)
+# * @return the first part of the shipping address or an empty String if the shipping address part one was not set
+# */
+sub GetShipAddressOne
+{
+ my $self = shift;
+ $self->{strShipAddressOne};
+}
+
+
+#**
+# * Get the value of the second part of the shipping address.
+# * @see #setShipAddressTwo(JString)
+# * @return the second part of the shipping address or an empty String if the shipping address part two was not set
+#
+sub GetShipAddressTwo
+{
+ my $self = shift;
+ $self->{strShipAddressTwo};
+}
+
+
+#**
+# * Get the value of the city for the shipping address.
+# * @see #setShipCity(JString)
+# * @return the shipping address city or an empty String if the shipping city was not set
+#
+sub GetShipCity
+{
+ my $self = shift;
+ $self->{strShipCity};
+}
+
+#**
+# * Get the value of the state or province for the shipping address.
+# * @see #setShipStateOrProvince(JString)
+# * @return the shipping address state or province or an empty String if the shipping state or provice was not set
+# */
+sub GetShipStateOrProvince
+{
+ my $self = shift;
+ $self->{strShipStateOrProvince};
+}
+
+
+#*
+# * Get the value of the postal code for the shipping address.
+# * @see #setShipPostalCode(JString)
+# * @return the shipping address postal code or an empty String if the shipping postal code was not set
+# */
+sub GetShipPostalCode
+{
+ my $self = shift;
+ $self->{strShipPostalCode};
+}
+
+
+#**
+# * Get the value of the country for the shipping address.
+# * @see #setShipCountryCode(JString)
+# * @return the shipping country or an empty String if the shipping country was not set
+# */
+sub GetShipCountryCode
+{
+ my $self = shift;
+ $self->{strShipCountryCode};
+}
+
+
+#**
+# * Get the value of the email address of the customer being shipped to.
+# * @see #setShipEmail(JString)
+# * @return the shipping email address or an empty String if the shipping customer email address was not set
+# */
+sub GetShipEmail
+{
+ my $self = shift;
+ $self->{strShipEmail};
+}
+
+
+#**
+# * Get the value of the phone number of the customer being shipped to.
+# * @see #setShipPhone(JString)
+# * @return the shipping phone number or an empty String if the shipping customer phone number was not set
+# */
+sub GetShipPhone
+{
+ my $self = shift;
+ $self->{strShipPhone};
+}
+
+
+#**
+# * Get the value of the fax number of the customer being shipped to.
+# * @see #setShipFax(JString)
+# * @return the shipping fax number or an empty JString if the shipping customer fax number was not set
+# */
+sub GetShipFax
+{
+ my $self = shift;
+ $self->{strShipFax};
+}
+
+
+#**
+# * Get the value of the shipping note. The shipping note is an extra
+# * comment to the shipping information.
+# * @see #setShipNote(JString)
+# * @return the shipping note or an empty String if the shipping note was not set
+# */
+sub GetShipNote
+{
+ my $self = shift;
+ $self->{strShipNote};
+}
+
+
+#**
+# * Method to get a CreditCardResponse object.
+# */
+sub GetTransResponseObject
+{
+ my $self = shift;
+ my $InString = shift;
+ return new Business::OnlinePayment::PPIPayMover::CreditCardResponse($InString);
+}
+
+
+#/**
+# * Get the value of the currency. The currency that
+# * will be used for this transaction. If the merchant
+# * does not have an account configured to process this currency, the
+# * Transaction Server will return an error.
+# * @see #setCurrency(String)
+# * @return the currency or "" if the currency was not set
+# */
+sub GetCurrency
+{
+ my $self = shift;
+ $self->{strCurrency};
+}
+
+
+#/**
+# * Gets the buyer code
+# */
+sub GetBuyerCode
+{
+ my $self = shift;
+ $self->{strBuyerCode};
+}
+
+#/**
+# * Gets the CAVV (for VBV transactions)
+# */
+sub GetCAVV
+{
+ my $self = shift;
+ $self->{strCAVV};
+}
+
+#/**
+# * Gets the Customer IP Address
+# */
+sub GetCustomerIPAddress
+{
+ my $self = shift;
+ $self->{strCustomerIPAddress};
+}
+
+#/**
+# * Gets the Order Customer ID
+# */
+sub GetOrderCustomerId
+{
+ my $self = shift;
+ $self->{strOrderCustomerID};
+}
+
+#/**
+# * Gets the purchase order number
+# */
+sub GetPurchaseOrderNumber
+{
+ my $self = shift;
+ $self->{strPurchaseOrderNumber};
+}
+
+#/**
+# * Gets the state tax
+# */
+sub GetStateTax
+{
+ my $self = shift;
+ $self->{dStateTax};
+}
+
+#/**
+# * Gets the track 1 data
+# */
+sub GetTrack1
+{
+ my $self = shift;
+ $self->{strTrack1};
+}
+
+#/**
+# * Gets the track 2 data
+# */
+sub GetTrack2
+{
+ my $self = shift;
+ $self->{strTrack2};
+}
+
+#/**
+# * Gets the transaction condition code
+# */
+sub GetTransactionConditionCode
+{
+ my $self = shift;
+ $self->{strTransactionConditionCode};
+}
+
+#/**
+# * Gets the xid
+# */
+sub GetXID
+{
+ my $self = shift;
+ $self->{strXID};
+}
+
+#/**
+# * Gets tax exempt flag
+# */
+sub GetTaxExempt
+{
+ my $self = shift;
+ $self->{boolTaxExempt};
+}
+
+#/**
+# * Gets invoice number
+# */
+sub GetInvoiceNumber
+{
+ my $self = shift;
+ $self->{strInvoiceNumber};
+}
+
+#/**
+# * Gets the Authentication Transaction ID
+# *
+# * Used in Payer Authentication transaction type
+# */
+sub GetAuthenticationTransactionId
+{
+ my $self = shift;
+ $self->{strAuthenticationTransactionId};
+}
+
+#/**
+# * Gets the Authentication Payload
+# *
+# * Used in Payer Authentication transaction type
+# */
+sub GetAuthenticationPayload
+{
+ my $self = shift;
+ $self->{strAuthenticationPayload};
+}
+
+#/**
+# * Gets the Success On Authentication Inconclusive
+# *
+# * Used in Payer Authentication transaction type
+# */
+sub GetDoTransactionOnAuthenticationInconclusive
+{
+ my $self = shift;
+ $self->{boolSuccessOnAuthenticationInconclusive};
+}
+
+
+#/**
+# * Gets the industry
+# */
+sub GetIndustry
+{
+ my $self = shift;
+ $self->{strIndustry};
+}
+
+#/**
+# * Gets the folio number
+# */
+sub GetFolioNumber
+{
+ my $self = shift;
+ $self->{strFolioNumber};
+}
+
+#/**
+# * Gets the service rate
+# */
+sub GetServiceRate
+{
+ my $self = shift;
+ $self->{dServiceRate};
+}
+
+#/**
+# * Gets the service rate as a String
+# */
+sub GetServiceRateStr
+{
+ my $self = shift;
+ $self->{strServiceRate};
+}
+
+#/**
+# * Gets the service start year
+# */
+sub GetServiceStartYear
+{
+ my $self = shift;
+ $self->{intServiceStartYear};
+}
+
+#/**
+# * Gets the service start month
+# */
+sub GetServiceStartMonth
+{
+ my $self = shift;
+ $self->{intServiceStartMonth};
+}
+
+#/**
+# * Gets the service start day
+# */
+sub GetServiceStartDay
+{
+ my $self = shift;
+ $self->{intServiceStartDay};
+}
+
+#/**
+# * Gets the service end year
+# */
+sub GetServiceEndYear
+{
+ my $self = shift;
+ $self->{intServiceEndYear};
+}
+
+#/**
+# * Gets the service end month
+# */
+sub GetServiceEndMonth
+{
+ my $self = shift;
+ $self->{intServiceEndMonth};
+}
+
+#/**
+# * Gets the service end day
+# */
+sub GetServiceEndDay
+{
+ my $self = shift;
+ $self->{intServiceEndDay};
+}
+
+#/**
+# * Gets the Charge Total Includes Restaurant flag
+# */
+sub GetChargeTotalIncludesRestaurant
+{
+ my $self = shift;
+ $self->{boolChargeTotalIncludesRestaurant};
+}
+
+#/**
+# * Gets the Charge Total Includes Giftshop flag
+# */
+sub GetChargeTotalIncludesGiftshop
+{
+ my $self = shift;
+ $self->{boolChargeTotalIncludesGiftshop};
+}
+
+#/**
+# * Gets the Charge Total Includes Minibar flag
+# */
+sub GetChargeTotalIncludesMinibar
+{
+ my $self = shift;
+ $self->{boolChargeTotalIncludesMinibar};
+}
+
+#/**
+# * Gets the Charge Total Includes Laundry flag
+# */
+sub GetChargeTotalIncludesLaundry
+{
+ my $self = shift;
+ $self->{boolChargeTotalIncludesLaundry};
+}
+
+#/**
+# * Gets the Charge Total Includes Phone flag
+# */
+sub GetChargeTotalIncludesPhone
+{
+ my $self = shift;
+ $self->{boolChargeTotalIncludesPhone};
+}
+
+#/**
+# * Gets the Charge Total Includes Other flag
+# */
+sub GetChargeTotalIncludesOther
+{
+ my $self = shift;
+ $self->{boolChargeTotalIncludesOther};
+}
+
+#/**
+# * Gets the Service No Show flag
+# */
+sub GetServiceNoShow
+{
+ my $self = shift;
+ $self->{boolServiceNoShow};
+}
+
+
+
+#**
+# * Method to create the post string.
+# */
+sub WriteRequest
+{
+ my $self = shift;
+ my $class =ref($self);
+ my $PostString = shift; # a pointer to string as arguement
+ my $temp = "";
+ $self->SUPER::WriteRequest($PostString);
+
+# Cartridge Type
+ $temp = Encode( $self->{strCartridgeType} );
+ $$PostString .= "cartridge_type=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Ecommerce Indicator
+ $temp = Encode( $self->{strEcommerceIndicator} );
+ $$PostString .= "ecommerce_indicator=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# fixed value for transaction_type
+ $$PostString .= "transaction_type=CREDIT_CARD";
+ $$PostString .= $self->{strParamSeparator};
+
+# creditCardNumber
+ $temp = Encode( $self->{strCreditCardNumber} );
+ $$PostString .= "credit_card_number=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# creditCardVerificationNumber
+ $temp = Encode( $self->{strCreditCardVerificationNumber} );
+ $$PostString .= "credit_card_verification_number=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# expireMonth
+ $temp = Encode( $self->{strExpireMonth} );
+ $$PostString .= "expire_month=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# expireYear
+ $temp = Encode( $self->{strExpireYear} );
+ $$PostString .= "expire_year=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# chargeType
+ $temp = Encode( $self->{strChargeType} );
+ $$PostString .= "charge_type=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# chargeTotal
+ $$PostString .= "charge_total=";
+ $$PostString .= Encode( $self->{dChargeTotal} );
+ $$PostString .= $self->{strParamSeparator};
+
+# cardBrand
+# $$PostString .= "card_brand=";
+# $$PostString .= Encode( $self->{strCardBrand} );
+# $$PostString .= $self->{strParamSeparator};
+
+# orderId
+ $temp = Encode( $self->{strOrderId} );
+ $$PostString .= "order_id=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# captureReferenceId
+ $temp = Encode( $self->{strReferenceId} );
+ $$PostString .= "reference_id=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# orderDescription
+ $temp = Encode( $self->{strOrderDescription} );
+ $$PostString .= "order_description=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# orderUserId
+ $temp = Encode( $self->{strOrderUserId} );
+ $$PostString .= "order_user_id=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# BankApprovalCode
+ $temp = Encode( $self->{strBankApprovalCode} );
+ $$PostString .= "bank_approval_code=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# DuplicateCheck
+ $temp = Encode( $self->{strDuplicateCheck} );
+ $$PostString .= "duplicate_check=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# taxAmount
+ $$PostString .= "tax_amount=";
+ $$PostString .= Encode( $self->{dTaxAmount} );
+ $$PostString .= $self->{strParamSeparator};
+
+# shippingCharge
+ $$PostString .= "shipping_charge=";
+ $$PostString .= Encode( $self->{dShippingCharge} );
+ $$PostString .= $self->{strParamSeparator};
+
+# billFirstName
+ $temp = Encode( $self->{strBillFirstName} );
+ $$PostString .= "bill_first_name=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# billMiddleName
+ $temp = Encode( $self->{strBillMiddleName} );
+ $$PostString .= "bill_middle_name=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# billLastName
+ $temp = Encode( $self->{strBillLastName} );
+ $$PostString .= "bill_last_name=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# billCustomerTitle
+ $temp = Encode( $self->{strBillCustomerTitle} );
+ $$PostString .= "bill_customer_title=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# billCompany
+ $temp = Encode( $self->{strBillCompany} );
+ $$PostString .= "bill_company=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# billAddressOne
+ $temp = Encode( $self->{strBillAddressOne} );
+ $$PostString .= "bill_address_one=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# billAddressTwo
+ $temp = Encode( $self->{strBillAddressTwo} );
+ $$PostString .= "bill_address_two=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# billCity
+ $temp = Encode( $self->{strBillCity} );
+ $$PostString .= "bill_city=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# billStateOrProvince
+ $temp = Encode( $self->{strBillStateOrProvince} );
+ $$PostString .= "bill_state_or_province=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# billPostalCode
+ $temp = Encode( $self->{strBillPostalCode} );
+ $$PostString .= "bill_postal_code=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# billCountryCode
+ $temp = Encode( $self->{strBillCountryCode} );
+ $$PostString .= "bill_country_code=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# billEmail
+ $temp = Encode( $self->{strBillEmail} );
+ $$PostString .= "bill_email=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# billPhone
+ $temp = Encode( $self->{strBillPhone} );
+ $$PostString .= "bill_phone=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# billFax
+ $temp = Encode( $self->{strBillFax} );
+ $$PostString .= "bill_fax=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# billNote
+ $temp = Encode( $self->{strBillNote} );
+ $$PostString .= "bill_note=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# shipFirstName
+ $temp = Encode( $self->{strShipFirstName} );
+ $$PostString .= "ship_first_name=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# shipMiddleName
+ $temp = Encode( $self->{strShipMiddleName} );
+ $$PostString .= "ship_middle_name=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# shipLastName
+ $temp = Encode( $self->{strShipLastName} );
+ $$PostString .= "ship_last_name=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# shipCustomerTitle
+ $temp = Encode( $self->{strShipCustomerTitle} );
+ $$PostString .= "ship_customer_title=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# shipCompany
+ $temp = Encode( $self->{strShipCompany} );
+ $$PostString .= "ship_company=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# shipAddressOne
+ $temp = Encode( $self->{strShipAddressOne} );
+ $$PostString .= "ship_address_one=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# shipAddressTwo
+ $temp = Encode( $self->{strShipAddressTwo} );
+ $$PostString .= "ship_address_two=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# shipCity
+ $temp = Encode( $self->{strShipCity} );
+ $$PostString .= "ship_city=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# shipStateOrProvince
+ $temp = Encode( $self->{strShipStateOrProvince} );
+ $$PostString .= "ship_state_or_province=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# shipPostalCode
+ $temp = Encode( $self->{strShipPostalCode} );
+ $$PostString .= "ship_postal_code=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# shipCountryCode
+ $temp = Encode( $self->{strShipCountryCode} );
+ $$PostString .= "ship_country_code=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# shipEmail
+ $temp = Encode( $self->{strShipEmail} );
+ $$PostString .= "ship_email=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# shipPhone
+ $temp = Encode( $self->{strShipPhone} );
+ $$PostString .= "ship_phone=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# shipFax
+ $temp = Encode( $self->{strShipFax} );
+ $$PostString .= "ship_fax=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# shipNote
+ $temp = Encode( $self->{strShipNote} );
+ $$PostString .= "ship_note=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Currency
+# $temp = Encode( $self->{strCurrency} );
+# $$PostString .= "currency=$temp";
+# $$PostString .= $self->{strParamSeparator};
+
+# Buyer Code
+ $temp = Encode( $self->{strBuyerCode} );
+ $$PostString .= "buyer_code=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# CAVV
+ $temp = Encode( $self->{strCAVV} );
+ $$PostString .= "cavv=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Customer IP Address
+ $temp = Encode( $self->{strCustomerIPAddress} );
+ $$PostString .= "customer_ip_address=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Order Customer ID
+ $temp = Encode( $self->{strOrderCustomerID} );
+ $$PostString .= "order_customer_id=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Purchase Order Number
+ $temp = Encode( $self->{strPurchaseOrderNumber} );
+ $$PostString .= "purchase_order_number=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# State Tax
+ $temp = Encode( $self->{dStateTax} );
+ if( $temp == -1 ) {
+ $temp = "";
+ }
+ $$PostString .= "state_tax=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Track 1
+ $temp = Encode( $self->{strTrack1} );
+ $$PostString .= "track1=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Track 2
+ $temp = Encode( $self->{strTrack2} );
+ $$PostString .= "track2=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Transaction condition code
+ $temp = Encode( $self->{strTransactionConditionCode} );
+ $$PostString .= "transaction_condition_code=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# XID
+ $temp = Encode( $self->{strXID} );
+ $$PostString .= "x_id=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Invoice number
+ $temp = Encode( $self->{strInvoiceNumber} );
+ $$PostString .= "invoice_number=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Tax Exempt
+ $temp = $self->{boolTaxExempt};
+ if ( $temp eq "" ) {
+ #not set. leave it.
+ } elsif ( $temp ) {
+ $temp = "true";
+ } elsif(! $temp) {
+ $temp = "false";
+ } else {
+ $temp = "";
+ }
+ $$PostString .= "tax_exempt=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Authentication Transaction ID
+ $temp = Encode( $self->{strAuthenticationTransactionId} );
+ $$PostString .= "authentication_transaction_id=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Authentication Payload
+ $temp = Encode( $self->{strAuthenticationPayload} );
+ $$PostString .= "authentication_payload=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Success On Authentication Inconclusive
+ $temp = $self->{boolSuccessOnAuthenticationInconclusive};
+ if ( $temp eq "" ) {
+ #not set. leave it.
+ } elsif ( $temp ) {
+ $temp = "true";
+ } elsif(!$temp) {
+ $temp = "false";
+ } else {
+ $temp = "";
+ }
+ $$PostString .= "success_on_authentication_inconclusive=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Industry
+ $temp = Encode( $self->{strIndustry} );
+ $$PostString .= "industry=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Folio number
+ $temp = Encode( $self->{strFolioNumber} );
+ $$PostString .= "folio_number=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Service Rate
+ $temp = Encode( $self->{dServiceRate} );
+ if( $temp == -1 ) {
+ $temp = "";
+ }
+ $$PostString .= "service_rate=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Service Start Day
+ $temp = Encode( $self->{intServiceStartDay} );
+ $$PostString .= "service_start_day=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Service Start Month
+ $temp = Encode( $self->{intServiceStartMonth} );
+ $$PostString .= "service_start_month=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Service Start Year
+ $temp = Encode( $self->{intServiceStartYear} );
+ $$PostString .= "service_start_year=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Service End Day
+ $temp = Encode( $self->{intServiceEndDay} );
+ $$PostString .= "service_end_day=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Service End Month
+ $temp = Encode( $self->{intServiceEndMonth} );
+ $$PostString .= "service_end_month=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Service End Year
+ $temp = Encode( $self->{intServiceEndYear} );
+ $$PostString .= "service_end_year=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Charge Total Includes Restaurant
+ $temp = Encode( $self->{boolChargeTotalIncludesRestaurant} );
+ if ( $temp eq "" ) {
+ #not set. leave it.
+ } elsif ( $temp ) {
+ $temp = "true";
+ } elsif(!$temp) {
+ $temp = "false";
+ } else {
+ $temp = "";
+ }
+ $$PostString .= "charge_total_incl_restaurant=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Charge Total Includes Giftshop
+ $temp = Encode( $self->{boolChargeTotalIncludesGiftshop} );
+ if ( $temp eq "" ) {
+ #not set. leave it.
+ } elsif ( $temp ) {
+ $temp = "true";
+ } elsif(!$temp) {
+ $temp = "false";
+ } else {
+ $temp = "";
+ }
+ $$PostString .= "charge_total_incl_giftshop=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Charge Total Includes Minibar
+ $temp = Encode( $self->{boolChargeTotalIncludesMinibar} );
+ if ( $temp eq "" ) {
+ #not set. leave it.
+ } elsif ( $temp ) {
+ $temp = "true";
+ } elsif(!$temp) {
+ $temp = "false";
+ } else {
+ $temp = "";
+ }
+ $$PostString .= "charge_total_incl_minibar=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Charge Total Includes Phone
+ $temp = Encode( $self->{boolChargeTotalIncludesPhone} );
+ if ( $temp eq "" ) {
+ #not set. leave it.
+ } elsif ( $temp ) {
+ $temp = "true";
+ } elsif(!$temp) {
+ $temp = "false";
+ } else {
+ $temp = "";
+ }
+ $$PostString .= "charge_total_incl_phone=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Charge Total Includes Laundry
+ $temp = Encode( $self->{boolChargeTotalIncludesLaundry} );
+ if ( $temp eq "" ) {
+ #not set. leave it.
+ } elsif ( $temp ) {
+ $temp = "true";
+ } elsif(!$temp) {
+ $temp = "false";
+ } else {
+ $temp = "";
+ }
+ $$PostString .= "charge_total_incl_laundry=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Charge Total Includes Other
+ $temp = Encode( $self->{boolChargeTotalIncludesOther} );
+ if ( $temp eq "" ) {
+ #not set. leave it.
+ } elsif ( $temp ) {
+ $temp = "true";
+ } elsif(!$temp) {
+ $temp = "false";
+ } else {
+ $temp = "";
+ }
+ $$PostString .= "charge_total_incl_other=$temp";
+ $$PostString .= $self->{strParamSeparator};
+
+# Service No Show
+ $temp = Encode( $self->{boolServiceNoShow} );
+ if ( $temp eq "" ) {
+ #not set. leave it.
+ } elsif ( $temp ) {
+ $temp = "true";
+ } elsif(!$temp) {
+ $temp = "false";
+ } else {
+ $temp = "";
+ }
+ $$PostString .= "service_no_show=$temp";
+
+# No parameter separator on last line.
+
+}
+
+sub GetErrorString
+{
+ my $self = shift;
+ return $self->{strError};
+}
+
+
diff --git a/lib/Business/OnlinePayment/PPIPayMover/CreditCardResponse.pm b/lib/Business/OnlinePayment/PPIPayMover/CreditCardResponse.pm
new file mode 100644
index 0000000..3cf5ae3
--- /dev/null
+++ b/lib/Business/OnlinePayment/PPIPayMover/CreditCardResponse.pm
@@ -0,0 +1,201 @@
+package Business::OnlinePayment::PPIPayMover::CreditCardResponse;
+
+use strict;
+use vars qw(@ISA);
+use Business::OnlinePayment::PPIPayMover::TransactionResponse;
+use Business::OnlinePayment::PPIPayMover::PayerAuthenticationResponse;
+use Business::OnlinePayment::PPIPayMover::constants;
+
+@ISA = qw(Business::OnlinePayment::PPIPayMover::TransactionResponse);
+
+sub new {
+ my $class = shift;
+ my $InString = shift;
+ my $self = $class->SUPER::new($InString);
+
+ $self->{oPayerAuthenticationResponse} = undef;
+ $self->{strReferenceId} = undef;
+ $self->{strBatchId} = undef;
+ $self->{strBankTransactionId} = undef;
+ $self->{strBankApprovalCode} = undef;
+ $self->{strState} = undef;
+ $self->{strAuthorizedAmount} = undef;
+ $self->{strOriginalAuthorizedAmount} = undef;
+ $self->{strCapturedAmount} = undef;
+ $self->{strCreditedAmount} = undef;
+ $self->{strTimeStampCreated} = undef;
+ $self->{strOrderId} = undef;
+ $self->{strIsoCode} = undef;
+ $self->{strAVSCode} = "None"; # v1.5
+ $self->{strCreditCardVerificationResponse} = undef;
+
+ if ($self->{iResponseCode} == TRANSACTION_SERVER_ERROR || $self->{iResponseCode} == INVALID_VERSION) {
+ return $self;
+ }
+ if (!($$InString) && !($self->{iResponseCode} == SUCCESSFUL_TRANSACTION)) {
+ return $self;
+ }
+
+ my @temp = split(/\n/, $$InString);
+ my $size = @temp;
+ if ($size < 10) {
+ $self->{strError} .= "input string is in wrong format";
+ $self->{iRetVal} = 0;
+ return $self;
+ }
+
+ # Looking to see if there is a nested Payer Authentication Response
+ my $payerAuthResponse = new Business::OnlinePayment::PPIPayMover::TransactionResponse($InString,AUTHENTICATION_PREFIX);
+
+ if (defined($payerAuthResponse->GetResponseCode)){
+ $self->{oPayerAuthenticationResponse} = new Business::OnlinePayment::PPIPayMover::PayerAuthenticationResponse($InString,AUTHENTICATION_PREFIX);
+ }
+
+ my $name;
+ my $value;
+ foreach (@temp) {
+
+ ($name, $value) = split(/=/, $_, 2);
+
+ if ($name eq "capture_reference_id") {
+ $self->{strReferenceId} = $value;
+ }
+ elsif ($name eq "order_id") {
+ $self->{strOrderId} = $value;
+ }
+ elsif ($name eq "iso_code") {
+ $self->{strIsoCode} = $value;
+ }
+ elsif ($name eq "bank_approval_code") {
+ $self->{strBankApprovalCode} = $value;
+ }
+ elsif ($name eq "state") {
+ $self->{strState} = $value;
+ }
+ elsif ($name eq "authorized_amount") {
+ $self->{strAuthorizedAmount} = $value;
+ }
+ elsif ($name eq "original_authorized_amount") {
+ $self->{strOriginalAuthorizedAmount} = $value;
+ }
+ elsif ($name eq "captured_amount") {
+ $self->{strCapturedAmount} = $value;
+ }
+ elsif ($name eq "credited_amount") {
+ $self->{strCreditedAmount} = $value;
+ }
+ elsif ($name eq "time_stamp_created") {
+ $self->{strTimeStampCreated} = $value;
+ }
+ elsif ($name eq "bank_transaction_id") {
+ $self->{strBankTransactionId} = $value;
+ }
+ elsif ($name eq "batch_id") {
+ $self->{strBatchId } = $value;
+ }
+ elsif ($name eq "avs_code") {
+ $self->{strAVSCode} = $value;
+ }
+ elsif ($name eq "credit_card_verification_response") {
+ $self->{strCreditCardVerificationResponse} = $value;
+ }
+ else {
+ $self->{strError} .= "Invalid data name: ";
+ }
+ }
+ return $self;
+}
+
+
+sub GetBatchId
+{
+ my $self = shift;
+ $self->{strBatchId};
+}
+
+sub GetBankTransactionId
+{
+ my $self = shift;
+ $self->{strBankTransactionId};
+}
+
+sub GetBankApprovalCode
+{
+ my $self = shift;
+ $self->{strBankApprovalCode};
+}
+
+sub GetState
+{
+ my $self = shift;
+ $self->{strState};
+}
+
+sub GetAuthorizedAmount
+{
+ my $self = shift;
+ $self->{strAuthorizedAmount};
+}
+
+sub GetOriginalAuthorizedAmount
+{
+ my $self = shift;
+ $self->{strOriginalAuthorizedAmount};
+}
+
+sub GetCapturedAmount
+{
+ my $self = shift;
+ $self->{strCapturedAmount};
+}
+
+sub GetCreditedAmount
+{
+ my $self = shift;
+ $self->{strCreditedAmount};
+}
+
+sub GetTimeStampCreated
+{
+ my $self = shift;
+ $self->{strTimeStampCreated};
+}
+
+sub GetOrderId
+{
+ my $self = shift;
+ $self->{strOrderId};
+}
+
+sub GetIsoCode
+{
+ my $self = shift;
+ $self->{strIsoCode};
+}
+
+sub GetCaptureReferenceId
+{
+ my $self = shift;
+ $self->{strReferenceId};
+}
+
+sub GetReferenceId
+{
+ my $self = shift;
+ $self->{strReferenceId};
+}
+
+sub GetAVSCode {
+ my $self = shift;
+ $self->{strAVSCode};
+}
+
+sub GetCreditCardVerificationResponse {
+ my $self = shift;
+ $self->{strCreditCardVerificationResponse};
+}
+
+sub GetPayerAuthenticationResponse {
+ my $self = shift;
+ $self->{oPayerAuthenticationResponse};
+}
diff --git a/lib/Business/OnlinePayment/PPIPayMover/PayerAuthenticationResponse.pm b/lib/Business/OnlinePayment/PPIPayMover/PayerAuthenticationResponse.pm
new file mode 100644
index 0000000..e679865
--- /dev/null
+++ b/lib/Business/OnlinePayment/PPIPayMover/PayerAuthenticationResponse.pm
@@ -0,0 +1,140 @@
+package Business::OnlinePayment::PPIPayMover::PayerAuthenticationResponse;
+
+use strict;
+use vars qw(@ISA);
+use Business::OnlinePayment::PPIPayMover::TransactionResponse;
+use Business::OnlinePayment::PPIPayMover::constants;
+
+@ISA = qw(Business::OnlinePayment::PPIPayMover::TransactionResponse);
+
+sub new {
+ my $class = shift;
+ my @param = @_;
+ my $paramNo = @param;
+
+ my $InString = shift;
+ my $prefix = "";
+
+ if( $paramNo == 2){
+ $prefix = shift;
+ }
+ my $self = $class->SUPER::new($InString,$prefix);
+
+ $self->{strAuthenticationTransactionId} = "";
+ $self->{strLookupPayload} = "";
+ $self->{strHiddenFields} = "";
+ $self->{strOrderId} = "";
+ $self->{strAuthenticationURL} = "";
+ $self->{strCavv} = "";
+ $self->{strXID} = "";
+ $self->{strStatus} = "";
+ $self->{strTransactionConditionCode} = "";
+ if ($self->{iResponseCode} == TRANSACTION_SERVER_ERROR || $self->{iResponseCode} == INVALID_VERSION) {
+ return $self;
+ }
+ if (!($$InString) && !($self->{iResponseCode} == SUCCESSFUL_TRANSACTION)) {
+ return $self;
+ }
+
+ my @temp = split(/\n/, $$InString);
+ my $size = @temp;
+ if ($size < 10) {
+ $self->{strError} .= "input string is in wrong format";
+ $self->{iRetVal} = 0;
+ return $self;
+ }
+ #splice(@temp, 0, 4);
+ my $name;
+ my $value;
+ foreach (@temp) {
+
+ # Anything after the first = is part
+ # of the value (including other ='s)
+ ($name, $value) = split(/=/, $_, 2);
+
+ if ($name eq $prefix."authentication_transaction_id") {
+ $self->{strAuthenticationTransactionId} = $value;
+ }
+ elsif ($name eq $prefix."lookup_payload") {
+ $self->{strLookupPayload} = $value;
+ }
+ elsif ($name eq $prefix."hidden_fields") {
+ $self->{strHiddenFields} = $value;
+ }
+ elsif ($name eq $prefix."order_id") {
+ $self->{strOrderId} = $value;
+ }
+ elsif ($name eq $prefix."authentication_url") {
+ $self->{strAuthenticationURL} = $value;
+ }
+ elsif ($name eq $prefix."cavv") {
+ $self->{strCavv } = $value;
+ }
+ elsif ($name eq $prefix."x_id") {
+ $self->{strXID} = $value;
+ }
+ elsif ($name eq $prefix."status") {
+ $self->{strStatus} = $value;
+ }
+ elsif ($name eq $prefix."transaction_condition_code") {
+ $self->{strTransactionConditionCode} = $value;
+ }
+ else {
+ $self->{strError} .= "Invalid data name: ";
+ }
+ }
+ return $self;
+}
+
+
+sub GetAuthenticationTransactionId
+{
+ my $self = shift;
+ $self->{strAuthenticationTransactionId};
+}
+
+sub GetLookupPayload
+{
+ my $self = shift;
+ $self->{strLookupPayload};
+}
+
+sub GetHiddenFields
+{
+ my $self = shift;
+ $self->{strHiddenFields};
+}
+
+sub GetOrderId
+{
+ my $self = shift;
+ $self->{strOrderId};
+}
+
+sub GetAuthenticationURL
+{
+ my $self = shift;
+ $self->{strAuthenticationURL};
+}
+
+sub GetCavv
+{
+ my $self = shift;
+ $self->{strCavv};
+}
+
+sub GetXID
+{
+ my $self = shift;
+ $self->{strXID};
+}
+
+sub GetStatus {
+ my $self = shift;
+ $self->{strStatus};
+}
+
+sub GetTransactionConditionCode {
+ my $self = shift;
+ $self->{strTransactionConditionCode};
+}
diff --git a/lib/Business/OnlinePayment/PPIPayMover/SecureHttp.pm b/lib/Business/OnlinePayment/PPIPayMover/SecureHttp.pm
new file mode 100644
index 0000000..bd03acd
--- /dev/null
+++ b/lib/Business/OnlinePayment/PPIPayMover/SecureHttp.pm
@@ -0,0 +1,155 @@
+use strict;
+package Business::OnlinePayment::PPIPayMover::SecureHttp;
+use Socket;
+use Net::SSLeay qw(die_now die_if_ssl_error) ;
+1;
+
+# constuctor
+sub new
+{
+ my $class = shift;
+ my $self = {};
+ bless $self, $class;
+ $self->{ctx} = undef;
+ $self->{ssl} = undef;
+ $self->{strError} = "";
+ return $self;
+}
+
+sub Init
+{
+ my $self = shift;
+
+ Net::SSLeay::load_error_strings();
+ Net::SSLeay::ERR_load_crypto_strings();
+ Net::SSLeay::SSLeay_add_ssl_algorithms();
+ Net::SSLeay::randomize();
+
+ $self->{ctx} = Net::SSLeay::CTX_new();
+ if(!$self->{ctx}) {
+ $self->{strError} .= "Failed to create SSL_CTX. \n" .
+ "SSLeay error: " . Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error);
+ return 0;
+ }
+
+ if(!Net::SSLeay::CTX_set_options($self->{ctx}, &Net::SSLeay::OP_ALL)) {
+ # For some reason the if statement above always returns false,
+ # but SSLeay reports no error. Ignore this error, since
+ # everything still works fine.
+ #
+ #$self->{strError} .= "Failed to set SSL_CTX options. \n" .
+ # "SSLeay error: " . Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error) . "\n";
+ }
+
+ $self->{ssl} = Net::SSLeay::new($self->{ctx});
+ if(!$self->{ssl}) {
+ $self->{strError} .= "Failed to create an SSL. \n" .
+ "SSLeay error: " . Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error);
+ return 0;
+ }
+
+ return 1;
+}
+
+sub Connect
+{
+ my $self = shift;
+ my ($destServer, $port) = @_;
+ $port = getservbyname($port, 'tcp') unless $port =~ /^\d+$/;
+
+ my $destIp = gethostbyname ($destServer);
+ if(!defined($destIp)) {
+ $self->{strError} .= "Couldn't resolve host name (gethostbyname) using host: $destServer\n";
+ return 0;
+ }
+
+ my $destServerSockAddr = sockaddr_in($port, $destIp);
+
+ if(!socket (S, AF_INET, SOCK_STREAM, 0)) {
+ $self->{strError} .= "Failed to create a socket. $!";
+ return 0;
+ }
+
+ if(!connect (S, $destServerSockAddr)) {
+ $self->{strError} .= "Failed to connect. $!";
+ return 0;
+ }
+
+ select (S); $| = 1; select (STDOUT); # Eliminate STDIO buffering
+ Net::SSLeay::set_fd($self->{ssl}, fileno(S)); # Must use fileno
+ if (! Net::SSLeay::connect($self->{ssl})) {
+ $self->{strError} .= "Failed to make an ssl connect. \n" .
+ "SSLeay error: " . Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error);
+ return 0;
+ }
+
+ return 1;
+}
+
+sub DoSecurePost
+{
+ my $self = shift;
+ my ($strPath, $strContent, $Response) = @_;
+ my $PostString = "POST ";
+ $PostString .= $strPath;
+ $PostString .= " HTTP/1.0\r\nContent-Type: application/x-www-form-urlencoded\r\n";
+ $PostString .= "Content-Length: ";
+ $PostString .= length($strContent);
+ $PostString .= " \r\n\r\n";
+ $PostString .= $strContent;
+
+ if(!Net::SSLeay::ssl_write_all($self->{ssl}, $PostString)) {
+ $self->{strError} .= "Failed to write. " .
+ "SSLeay error: " . Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error);
+ return 0;
+ }
+
+ shutdown S, 1; # Half close --> No more output, sends EOF to server
+
+ if( $^O eq "MSWin32" ) {
+ # Windows doesn't implement ALRM signal,
+ # so don't use a timeout.
+ # May hang client system.
+ $$Response = Net::SSLeay::ssl_read_all($self->{ssl});
+ } else {
+ # This block uses the alarm signal
+ # to see if the server times out responding.
+ eval {
+ local $SIG{ ALRM } = sub {
+ $self->{strError} .= "Server timed out.";
+ close S;
+ };
+ alarm 270; # Alarm on 4.5 min timeout
+ # Read in response from server
+ $$Response = Net::SSLeay::ssl_read_all($self->{ssl});
+ };
+ alarm 0; # Alarm off
+
+ }
+
+ if ( !defined( $$Response ) ) {
+ $self->{strError} .= "Failed to read from socket. " .
+ "SSLeay error: " . Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error);
+ return 0;
+ }
+ return 1;
+}
+
+sub DisconnectFromServer
+{
+ my $self = shift;
+ Net::SSLeay::free ($self->{ssl}); # Tear down connection
+ Net::SSLeay::CTX_free ($self->{ctx});
+ close S;
+}
+
+sub CleanUp
+{
+ return 1;
+}
+
+sub GetErrorString
+{
+ my $self = shift;
+ return $self->{strError};
+}
diff --git a/lib/Business/OnlinePayment/PPIPayMover/TransactionClient.pm b/lib/Business/OnlinePayment/PPIPayMover/TransactionClient.pm
new file mode 100644
index 0000000..cef6a99
--- /dev/null
+++ b/lib/Business/OnlinePayment/PPIPayMover/TransactionClient.pm
@@ -0,0 +1,92 @@
+use strict;
+package Business::OnlinePayment::PPIPayMover::TransactionClient;
+use Business::OnlinePayment::PPIPayMover::TransactionResponse;
+use Business::OnlinePayment::PPIPayMover::TransactionRequest;
+use Business::OnlinePayment::PPIPayMover::CreditCardRequest;
+use Business::OnlinePayment::PPIPayMover::CreditCardResponse;
+use Business::OnlinePayment::PPIPayMover::SecureHttp;
+use Business::OnlinePayment::PPIPayMover::constants;
+1;
+
+# default constructor
+sub new {
+ my $class = shift;
+ my $self = {};
+ $self->{strError} = "";
+ $self->{strResponse} = "";
+ bless $self, $class;
+ return $self;
+}
+
+sub doTransaction # take three arguements
+{
+ my $self = shift;
+ my $TransactionKey = shift; # the first arguement(string)
+ my $transReq = shift; # the second arguement(class object)
+ my $AccountToken = shift; # the third arguement(string)
+
+ my $PostString = "";
+ my $ResponseString = "";
+
+ # write out account_token ...
+ $PostString .= "account_token=$AccountToken";
+ $PostString .= "&";
+
+ # write out transaction_key ...
+ #$PostString .= "transaction_key=$TransactionKey";
+ #$PostString .= "&";
+
+ # write out version_id ...
+ my $temp = VERSION;
+ $temp =~ tr/ /+/;
+ $PostString .= "version_id=$temp";
+ $PostString .= "&";
+
+ $transReq->WriteRequest(\$PostString); # get post information
+
+ my $ResponseContent;
+ my $secureHttp = new Business::OnlinePayment::PPIPayMover::SecureHttp;
+ my $strServer = PAY_HOST;
+ my $strPath = PAY_HOST_PATH;
+ my $iPort = PAY_HOST_PORT;
+
+
+ if(!$secureHttp->Init) {
+ $self->{strError} = $secureHttp->GetErrorString;
+ return undef;
+ }
+
+ if(!$secureHttp->Connect($strServer, $iPort)) {
+ $self->{strError} = $secureHttp->GetErrorString;
+ return undef;
+ }
+ if(!$secureHttp->DoSecurePost($strPath, $PostString, \$self->{strResponse})) {
+ $self->{strError} .= $secureHttp->GetErrorString;
+ return undef;
+ }
+
+ $secureHttp->DisconnectFromServer;
+ $secureHttp->CleanUp;
+
+ my $i = index($self->{strResponse}, "response_code");
+ if($i>=0) {
+ $ResponseContent = substr($self->{strResponse}, $i);
+ return $transReq->GetTransResponseObject(\$ResponseContent);
+ }
+ else {
+ return undef;
+ }
+}
+
+
+
+sub GetErrorString
+{
+ my $self = shift;
+ return $self->{strError};
+}
+
+#JString TransactionClient::GetResponseString()
+#{
+# return m_jstrResponse;
+#}
diff --git a/lib/Business/OnlinePayment/PPIPayMover/TransactionRequest.pm b/lib/Business/OnlinePayment/PPIPayMover/TransactionRequest.pm
new file mode 100644
index 0000000..c932225
--- /dev/null
+++ b/lib/Business/OnlinePayment/PPIPayMover/TransactionRequest.pm
@@ -0,0 +1,118 @@
+use strict;
+package Business::OnlinePayment::PPIPayMover::TransactionRequest;
+use Business::OnlinePayment::PPIPayMover::constants;
+use Business::OnlinePayment::PPIPayMover::AdditionalField;
+use Business::OnlinePayment::PPIPayMover::TransactionResponse;
+1;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ $self->{AdditionalFields} = [];
+ $self->{strError} = "";
+ $self->{strParamSeparator} = "&";
+
+ bless $self, $class;
+ return $self;
+}
+
+
+# *
+# * A method to add a single additional field to the TransactionRequest or TransactionRequest subclass
+# * (such as CreditCardRequest).
+# * <P>
+# * @param additionalField An AdditionalField object containing a name and a value. The name must be
+# * unique. That is, one TransactionRequest object can contain only one additional field with a given name.
+# * <P>
+# * @see AdditionalField
+# */
+sub SetAdditionalField {
+ my $self = shift;
+ my $additionalField = shift; # take only one AdditionalField object arguement
+ foreach (@{$self->{AdditionalFields}}) {
+ if ($additionalField->equals($_)) {
+ $self->{strError} .= "TransactionRequest.setAddtionalField: name already used";
+ return CCR_ERROR;
+ }
+ }
+ ${$self->{AdditionalFields}}[$#{$self->{AdditionalFields}} + 1] = $additionalField;
+ return CCR_NO_ERROR;
+}
+
+
+#**
+# * A method to add multiple additional fields to the TransactionRequest or TransactionRequest subclass
+# * (such as CreditCardRequest).
+# * <P>
+# * @param additionalFields An Vector of AdditionalField objects, each containing a name and a value.
+# * The parameter cannot be NULL and the Vector must be non-empty.
+# * <P>
+# * @see AdditionalField
+# */
+sub SetAdditionalFields {
+ my $self = shift;
+ my $additionalFields = shift; # take one AdditionalField array arguement
+ my $size = @$additionalFields;
+ if ($size == 0) {
+ $self->{strError} .= "TransactionRequest.setAdditionalFields passed empty vector";
+ return CCR_ERROR;
+ }
+
+ foreach (@$additionalFields) {
+ if (defined($_)) {$self->SetAdditionalField($_)}
+ }
+
+ return CCR_NO_ERROR;
+}
+
+#**
+# * A method to retrieve an additional field
+# * @return Returns an AdditionalField object or NULL if name is unkown
+# */
+sub GetAdditionalField {
+ my $self = shift;
+ my $name = shift; # use name as arguement to get additional field arguememt
+ foreach (@{$self->{AdditionalFields}}) {
+ if ($name = $_->getName) { return $_ }
+ }
+ return undef;
+}
+
+
+#**
+# * A method to retrieve a Vector of AdditionalField objects
+# * @return Returns a Vector of AdditionalField objects or NULL
+# */
+sub GetAdditionalFields{
+ my $self = shift;
+ return @{$self->{AdditionalFields}};
+}
+
+
+#**
+# * A method for Transaction Server developers that is not used by merchant developers.
+# * <P>
+# * This method should be overwritten by subclasses, but the subclasses
+# * version of this method MUST CALL super.writeRequest(out).
+# */
+sub WriteRequest {
+ my $self = shift;
+ my $PostString = shift; #arguement as a pointer to string
+ my $size = @{$self->{AdditionalFields}};
+ if ($size == 0) {
+ return CCR_ERROR;
+ }
+
+ foreach (@{$self->{AdditionalFields}}) {
+ if (defined($_)) {
+ $_->write($PostString);
+ }
+ }
+ return CCR_NO_ERROR;
+}
+
+sub GetTransResponseObject {
+ my $self = shift;
+ my $InString = shift; # use one string arguement
+ return new Business::OnlinePayment::PPIPayMover::TransactionResponse($InString);
+}
diff --git a/lib/Business/OnlinePayment/PPIPayMover/TransactionResponse.pm b/lib/Business/OnlinePayment/PPIPayMover/TransactionResponse.pm
new file mode 100644
index 0000000..4056864
--- /dev/null
+++ b/lib/Business/OnlinePayment/PPIPayMover/TransactionResponse.pm
@@ -0,0 +1,171 @@
+use strict;
+package Business::OnlinePayment::PPIPayMover::TransactionResponse;
+use Business::OnlinePayment::PPIPayMover::constants;
+1;
+
+sub new {
+ my $class = shift;
+ my @param = @_;
+ my $paramNo = @param;
+ my $self = {};
+ bless $self, $class;
+
+ $self->{strError} = "";
+ $self->{iRetVal} = undef;
+ $self->{iResponseCode} = undef;
+ $self->{strResponseCode} = undef;
+ $self->{strResponseCodeText} = undef;
+ $self->{strTimeStamp} = undef;
+ $self->{bRetryRecommended} = undef;
+
+
+# constructor for only one or two string arguement
+ if ($paramNo == 1 || $paramNo == 2) {
+ my $InString = shift;
+ my $prefix = "";
+
+ if($paramNo == 2){
+ $prefix = shift;
+ }
+
+ if ($$InString eq "") {
+ $self->{strError} .= "Empty response string";
+ $self->{iRetVal} = 0;
+ return $self;
+ }
+ my @tmp;
+ @tmp = split(/\n/, $$InString);
+
+ my $name;
+ my $value;
+ foreach (@tmp) {
+
+ # Anything after the first = is part
+ # of the value (including other ='s)
+ ($name, $value) = split(/=/, $_, 2);
+
+ if (index($name, "<") == 0) {
+ $self->{strError} .= "Server not available";
+ $self->{iRetVal} = 0;
+
+ $self->{iResponseCode} = TRANSACTION_SERVER_ERROR;
+ $self->{strResponseCode} = "".$self->{iResponseCode};
+ $self->{strResponseCodeText} = "The Transaction Server is currently not available";
+ return $self;
+ }
+
+ if ($name eq $prefix."response_code") {
+
+ if($value."" eq "0" || $value."" eq "") {
+ $self->{strError} .= "Invalid response code";
+ $self->{iRetVal} = 0;
+ return $self;
+ }
+ else {
+ $self->{strResponseCode} = $value;
+ $self->{iResponseCode} = 1 * $value;
+ }
+ }
+ elsif ($name eq $prefix."response_code_text"){
+ $self->{strResponseCodeText} = $value;
+ }
+ elsif ($name eq $prefix."time_stamp") {
+ $self->{strTimeStamp} = $value;
+ }
+ elsif ($name eq $prefix."retry_recommended") {
+ if ($value eq "true") {
+ $self->{bRetryRecommended} = 1;
+ }
+ elsif ($value eq "false") {
+ $self->{bRetryRecommended} = 0;
+ }
+ else {
+ $self->{strError} .= "invalid retry flag";
+ return $self;
+ }
+ }
+ else {
+ $self->{strError} .= "Invalid data name: ";
+ }
+ }
+ }
+
+# constructor for 4 arguements. More arguements are ignored
+# (1) ResponseCode(integer), (2) ResponseCodeText(string), (3) TimeStamp(string),
+# (4) RetryRecommended(bool: 1 or 0 in the form of integer)
+
+ elsif ($paramNo >= 4) {
+ my ($iResponseCode, $strResponseCodeText, $strTimeStamp, $bRetryRecommended) = @param[0..3];
+ if (!defined($iResponseCode) || $iResponseCode < 1 || !defined($strResponseCodeText) ||
+ !defined($strTimeStamp) || !defined($bRetryRecommended)) {
+ $self->{strError} .= "Wrong parameter";
+ return $self;
+ }
+ $self->{iResponseCode} = $iResponseCode;
+ $self->{strResponseCode} = "".$iResponseCode;
+ $self->{strResponseCodeText} = $strResponseCodeText;
+ $self->{strTimeStamp} = $strTimeStamp;
+ $self->{bRetryRecommended} = $bRetryRecommended;
+ }
+ else {
+ $self->{strError} .= "Parameter number is only $paramNo and more are needed";
+ return $self;
+ }
+ return $self;
+}
+
+
+sub GetError {
+ my $self = shift;
+ $self->{strError};
+}
+sub GetResponseCode {
+ my $self = shift;
+ $self->{iResponseCode};
+}
+
+sub GetResponseCodeStrVal {
+ my $self = shift;
+ $self->{strResponseCode};
+}
+
+sub GetResponseCodeText{
+ my $self = shift;
+ $self->{strResponseCodeText};
+}
+
+sub GetTimeStamp {
+ my $self = shift;
+ $self->{strTimeStamp};
+}
+
+sub GetRetryRecommended {
+ my $self = shift;
+ $self->{bRetryRecommended};
+}
+
+
+sub WriteResponse {
+ my $self = shift;
+ my $outString = shift;
+
+ $self->{strResponseCodeText} =~ tr/\n/ /;
+ $self->{strTimeStamp} =~ tr/\n/ /;
+ $$outString .= "response_code=";
+ $$outString .= $self->{strResponseCode};
+ $$outString .= "\n";
+ $$outString .= "response_code_text=";
+ $$outString .= $self->{strResponseCodeText};
+ $$outString .= "\n";
+ $$outString .= "time_stamp=";
+ $$outString .= $self->{strTimeStamp};
+ $$outString .= "\n";
+
+ if ($self->{bRetryRecommended}) {
+ $$outString .= "retry_recommended=true\n";
+ }
+ else {
+ $$outString .= "retry_recommended=false\n";
+ }
+ return CCR_NO_ERROR;
+}
diff --git a/lib/Business/OnlinePayment/PPIPayMover/URLEncoder.pm b/lib/Business/OnlinePayment/PPIPayMover/URLEncoder.pm
new file mode 100644
index 0000000..556b557
--- /dev/null
+++ b/lib/Business/OnlinePayment/PPIPayMover/URLEncoder.pm
@@ -0,0 +1,14 @@
+package Business::OnlinePayment::PPIPayMover::URLEncoder;
+require Exporter;
+@ISA = qw(Exporter);
+@EXPORT = qw(Encode);
+
+1;
+
+sub Encode {
+ #my $self = shift;
+ my $value = shift;
+
+ $value =~ s/([^a-zA-Z0-9_\-.])/uc sprintf("%%%02x",ord($1))/eg;
+ return $value;
+}
diff --git a/lib/Business/OnlinePayment/PPIPayMover/constants.pm b/lib/Business/OnlinePayment/PPIPayMover/constants.pm
new file mode 100644
index 0000000..0015c74
--- /dev/null
+++ b/lib/Business/OnlinePayment/PPIPayMover/constants.pm
@@ -0,0 +1,631 @@
+package Business::OnlinePayment::PPIPayMover::constants;
+
+use strict;
+use vars qw(@ISA @EXPORT);
+use Exporter;
+
+@ISA = qw(Exporter);
+
+@EXPORT = qw(VERSION
+ PAY_HOST
+ PAY_HOST_PATH
+ PAY_HOST_PORT
+ SUCCESSFUL_TRANSACTION
+ MISSING_REQUIRED_REQUEST_FIELD
+ INVALID_REQUEST_FIELD
+ ILLEGAL_TRANSACTION_REQUEST
+ TRANSACTION_SERVER_ERROR
+ TRANSACTION_NOT_POSSIBLE
+ INVALID_VERSION
+ CREDIT_CARD_DECLINED
+ ACQUIRER_GATEWAY_ERROR
+ PAYMENT_ENGINE_ERROR
+ SALE
+ AUTH
+ FORCE_SALE
+ FORCE_AUTH
+ ADJUSTMENT
+ QUERY_PAYMENT
+ QUERY_CREDIT
+ CAPTURE
+ VOID
+ CREDIT
+ CREATE_ORDER
+ CLOSE_ORDER
+ CANCEL_ORDER
+ VOID_AUTH
+ VOID_CAPTURE
+ VOID_CREDIT
+ SETTLE_ACTION
+ PURGE_ACTION
+ TOTALS_ACTION
+ VISA
+ MASTERCARD
+ AMERICAN_EXPRESS
+ DISCOVER
+ NOVA
+ AMEX
+ DINERS
+ EUROCARD
+ CARD_BRAND_1
+ CARD_BRAND_2
+ CARD_BRAND_3
+ CARD_BRAND_4
+ CARD_BRAND_5
+ CARD_BRAND_6
+ TR_ERROR
+ TR_NO_ERROR
+ CCR_ERROR
+ CCR_NO_ERROR
+ BR_ERROR
+ BR_NO_ERROR
+ ISR_ERROR
+ ISR_NO_ERROR
+ ECLIENT_ERROR
+ ECLIENT_NO_ERROR
+ HTTP_POST_RESULT_NOTIFICATION_STRING
+ EMAIL_RESULT_NOTIFICATION_STRING
+ NO_RESULT_NOTIFICATION_STRING
+ EMAIL_RESULT_NOTIFICATION
+ HTTP_POST_RESULT_NOTIFICATION
+ NO_RESULT_NOTIFICATION
+ TCC_DEFAULT
+ TCC_CARDHOLDER_NOT_PRESENT_MAIL_FAX_ORDER
+ TCC_CARDHOLDER_NOT_PRESENT_TELEPHONE_ORDER
+ TCC_CARDHOLDER_NOT_PRESENT_INSTALLMENT
+ TCC_CARDHOLDER_NOT_PRESENT_PAYER_AUTHENTICATION
+ TCC_CARDHOLDER_NOT_PRESENT_SECURE_ECOMMERCE
+ TCC_CARDHOLDER_NOT_PRESENT_RECURRING_BILLING
+ TCC_CARDHOLDER_PRESENT_RETAIL_ORDER
+ TCC_CARDHOLDER_PRESENT_RETAIL_ORDER_WITHOUT_SIGNATURE
+ TCC_CARDHOLDER_PRESENT_RETAIL_ORDER_KEYED
+ TCC_CARDHOLDER_NOT_PRESENT_PAYER_AUTHENTICATION_ATTEMPTED
+ PERIOD_WEEKLY
+ PERIOD_BIWEEKLY
+ PERIOD_SEMIMONTHLY
+ PERIOD_MONTHLY
+ PERIOD_QUARTERLY
+ PERIOD_ANNUAL
+ COMMAND_ADD_CUSTOMER_ACCOUNT_ONLY
+ COMMAND_ADD_RECURRENCE_ONLY
+ COMMAND_ADD_CUSTOMER_ACCOUNT_AND_RECURRENCE
+ ACCOUNT_TYPE_CREDIT_CARD
+ STATUS_ENROLLED
+ STATUS_NOT_ENROLLED
+ STATUS_ENROLLED_BUT_AUTHENTICATION_UNAVAILABLE
+ AUTHENTICATION_PREFIX
+ CHECKING
+ SAVINGS
+ PERSONAL
+ CORPORATE
+ DIRECT_MARKETING
+ RETAIL
+ LODGING
+ RESTAURANT
+ CHECK
+ OVERRIDE
+ NO_CHECK
+);
+
+sub VERSION { "Perl Plug v1.8.0" }
+
+#**
+# * Payment Host Information
+#
+
+sub PAY_HOST { "etrans.paygateway.com" }
+sub PAY_HOST_PATH { "/TransactionManager" }
+sub PAY_HOST_PORT { 443 }
+
+
+#**
+# * Response code indicating the transaction was successfully processed.
+#
+sub SUCCESSFUL_TRANSACTION { 1 }
+
+#**
+# * Response code indicating that a required request field was not provided
+# * with the request. The required field will be identifed in the response
+# * code text returned from getResponseCodeText(). The field identified will
+# * be defined by a subclass of TransactionRequest.
+#
+sub MISSING_REQUIRED_REQUEST_FIELD { 2 }
+
+#*
+# * Response code indicating that the value provided to a subclass of
+# * TrasactionRequest for a transaction field was not valid. The resonse
+# * code text returned from getResponseCodeText() will identify the
+# * problem and the field.
+# *
+sub INVALID_REQUEST_FIELD { 3 }
+
+#*
+# * Response code indicating the transaction request was illegal. This
+# * can happen if a transaction is sent for an account that does not
+# * exist or if the account has not been configured to perform the
+# * requested transaction type.
+#
+sub ILLEGAL_TRANSACTION_REQUEST { 4 }
+
+#*
+# * Response code indicating that an error occured within the transaction
+# * server. The transaction server is where this Java Transaction Client API
+# * connects and sends transaction data for further processing. This type
+# * of error is temporary. If one occurs maintenance staff are immediately
+# * signaled to correct the problem.
+#
+sub TRANSACTION_SERVER_ERROR { 5 }
+
+#**
+# * Response code indicating that the requested transaction is not possible.
+# * This can happen if the transaction request refers to a previous transaction
+# * that does not exist. For example, when using the CreditCardRequest and
+# * CreditCardResponse classes one possible request is to perform a capture of
+# * funds previously authorized from a customers credit card. If a capture
+# * request is sent that refers to an authorization that does not exist then
+# * this response code will be returned.
+#
+sub TRANSACTION_NOT_POSSIBLE { 6 }
+
+#**
+# * Response code indicating that the version of the Java Transaction Client API
+#* being used is no longer valid.
+#
+sub INVALID_VERSION { 7 }
+
+#**
+# * Response code indicating that the credit card transaction was declined.
+# *
+sub CREDIT_CARD_DECLINED { 100 }
+
+#**
+# * Response code indicating that the Acquirer Gateway encountered an
+# * error. This is a software program that handles credit card transactions.
+# * It accepts connections over the internet and communicates with the
+# * private banking network.
+# *
+sub ACQUIRER_GATEWAY_ERROR { 101 }
+
+#**
+# * Response code indicating that the Payment Engine encountered an
+# * error. This is a software program that makes connections to an
+# * Aquirer Gateway.
+#
+sub PAYMENT_ENGINE_ERROR { 102 }
+
+#/////////////////////////////////////////////////////////////////////////////////////////////////////
+#// Constants that are permissible values for chargeBrand.
+#
+
+#**
+# * One of ten permissible values of the parameter of the setChargeType() method.
+# * May also be used as the chargeType parameter in the CreditCardRequest constructor.
+# * Indicates that the type of operation being done is a sale
+# * (both an authorization and a capture).
+# * <p>
+# * Other permissible values for setChargeType() are ADJUSTMENT, AUTH, CAPTURE, CREDIT, FORCE_AUTH, FORCE_SALE, QUERY_CREDIT, QUERY_PAYMENT or VOID.
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getChargeType
+# * @see com.paygateway.CreditCardRequest#setChargeType
+# */
+sub SALE { "SALE" }
+
+#**
+# * Additional Charge Type
+# * <p>
+# * See above for other permissible values for setChargeType().
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getChargeType
+# * @see com.paygateway.CreditCardRequest#setChargeType
+# *
+sub AUTH { "AUTH" }
+
+#**
+# * Additional Charge Type
+# * <p>
+# * See above for other permissible values for setChargeType().
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getChargeType
+# * @see com.paygateway.CreditCardRequest#setChargeType
+# *
+sub CAPTURE { "CAPTURE" }
+
+#**
+# * Additional Charge Type
+# * <p>
+# * See above for other permissible values for setChargeType().
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getChargeType
+# * @see com.paygateway.CreditCardRequest#setChargeType
+# *
+sub VOID { "VOID" }
+
+#**
+# * Additional Charge Type
+# * <p>
+# * See above for other permissible values for setChargeType().
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getChargeType
+# * @see com.paygateway.CreditCardRequest#setChargeType
+# *
+sub CREDIT { "CREDIT" }
+
+#**
+# * Additional Charge Type
+# * <p>
+# * See above for other permissible values for setChargeType().
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getChargeType
+# * @see com.paygateway.CreditCardRequest#setChargeType
+# *
+sub FORCE_AUTH { "FORCE_AUTH" }
+
+#**
+# * Additional Charge Type
+# * <p>
+# * See above for other permissible values for setChargeType().
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getChargeType
+# * @see com.paygateway.CreditCardRequest#setChargeType
+# *
+sub FORCE_SALE { "FORCE_SALE" }
+
+#**
+# * Additional Charge Type
+# * <p>
+# * See above for other permissible values for setChargeType().
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getChargeType
+# * @see com.paygateway.CreditCardRequest#setChargeType
+# *
+sub QUERY_PAYMENT { "QUERY_PAYMENT" }
+
+#**
+# * Additional Charge Type
+# * <p>
+# * See above for other permissible values for setChargeType().
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getChargeType
+# * @see com.paygateway.CreditCardRequest#setChargeType
+# *
+sub QUERY_CREDIT { "QUERY_CREDIT" }
+
+#**
+# * Additional Charge Type
+# * <p>
+# * See above for other permissible values for setChargeType().
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getChargeType
+# * @see com.paygateway.CreditCardRequest#setChargeType
+# *
+sub ADJUSTMENT { "ADJUSTMENT" }
+
+
+
+
+
+# new charge types for BatchRequest
+# added in v1.6
+sub SETTLE_ACTION { "SETTLE" }
+sub PURGE_ACTION { "PURGE" }
+sub TOTALS_ACTION { "TOTALS" }
+
+# new charge types for ibm pm
+# added in v1.6
+sub CLOSE_ORDER { "CLOSE_ORDER" }
+sub CANCEL_ORDER { "CANCEL_ORDER" }
+sub CREATE_ORDER { "CREATE_ORDER" }
+sub VOID_AUTH { "VOID_AUTH" }
+sub VOID_CAPTURE { "VOID_CAPTURE" }
+sub VOID_CREDIT { "VOID_CREDIT" }
+
+#/////////////////////////////////////////////////////////////////////////////////////////////////////
+#// Permissible values for cardBrand.
+
+#
+# * One permissible value for the parameter of the setCardBrand() method.
+# * May also be used as the cardBrand parameter in the CreditCardRequest constructor.
+# <p>
+# Other permissible values are
+# MASTERCARD, AMERICAN_EXPRESS, DISCOVER, NOVA, AMEX, DINERS, or EUROCARD,
+# as well as generic values (to support future card types)
+# CARD_BRAND_1, CARD_BRAND_2, CARD_BRAND_3, CARD_BRAND_4, CARD_BRAND_5, or CARD_BRAND_6.
+# <p>
+# @see com.paygateway.CreditCardRequest#getCardBrand
+# @see com.paygateway.CreditCardRequest#setCardBrand
+#*/
+sub VISA { "VISA" }
+
+#**
+# * One permissible value for the parameter of the setCardBrand() method.
+# * May also be used as the cardBrand parameter in the CreditCardRequest constructor.
+# <p>
+# Other permissible values are
+# VISA, AMERICAN_EXPRESS, DISCOVER, NOVA, AMEX, DINERS, or EUROCARD,
+# as well as generic values (to support future card types)
+# CARD_BRAND_1, CARD_BRAND_2, CARD_BRAND_3, CARD_BRAND_4, CARD_BRAND_5, or CARD_BRAND_6.
+# <p>
+# @see com.paygateway.CreditCardRequest#getCardBrand
+# @see com.paygateway.CreditCardRequest#setCardBrand
+#
+sub MASTERCARD { "MASTERCARD" }
+
+#**
+# * One permissible value for the parameter of the setCardBrand() method.
+# * May also be used as the cardBrand parameter in the CreditCardRequest constructor.
+# * <p>
+# * Other permissible values are
+# * VISA, MASTERCARD, DISCOVER, NOVA, AMEX, DINERS, or EUROCARD,
+# * as well as generic values (to support future card types)
+# * CARD_BRAND_1, CARD_BRAND_2, CARD_BRAND_3, CARD_BRAND_4, CARD_BRAND_5, or CARD_BRAND_6.
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getCardBrand
+# * @see com.paygateway.CreditCardRequest#setCardBrand
+# */
+sub AMERICAN_EXPRESS { "AMERICAN_EXPRESS" }
+
+#/**
+# * One permissible value for the parameter of the setCardBrand() method.
+# * May also be used as the cardBrand parameter in the CreditCardRequest constructor.
+# * <p>
+# * Other permissible values are
+# * VISA, MASTERCARD, AMERICAN_EXPRESS, NOVA, AMEX, DINERS, or EUROCARD,
+# * as well as generic values (to support future card types)
+# * CARD_BRAND_1, CARD_BRAND_2, CARD_BRAND_3, CARD_BRAND_4, CARD_BRAND_5, or CARD_BRAND_6.
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getCardBrand
+# * @see com.paygateway.CreditCardRequest#setCardBrand
+# */
+sub DISCOVER { "DISCOVER" }
+
+#**
+# * One permissible value for the parameter of the setCardBrand() method.
+# * May also be used as the cardBrand parameter in the CreditCardRequest constructor.
+# * <p>
+# * Other permissible values are
+# * VISA, MASTERCARD, AMERICAN_EXPRESS, DISCOVER, AMEX, DINERS, or EUROCARD,
+# * as well as generic values (to support future card types)
+# * CARD_BRAND_1, CARD_BRAND_2, CARD_BRAND_3, CARD_BRAND_4, CARD_BRAND_5, or CARD_BRAND_6.
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getCardBrand
+# * @see com.paygateway.CreditCardRequest#setCardBrand
+# */
+sub NOVA { "NOVA" }
+
+#**
+# * One permissible value for the parameter of the setCardBrand() method.
+# * May also be used as the cardBrand parameter in the CreditCardRequest constructor.
+# * <p>
+# * Other permissible values are
+# * VISA, MASTERCARD, AMERICAN_EXPRESS, DISCOVER, NOVA, DINERS, or EUROCARD,
+# * as well as generic values (to support future card types)
+# * CARD_BRAND_1, CARD_BRAND_2, CARD_BRAND_3, CARD_BRAND_4, CARD_BRAND_5, or CARD_BRAND_6.
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getCardBrand
+# * @see com.paygateway.CreditCardRequest#setCardBrand
+# */
+sub AMEX { "AMEX" }
+
+#*
+# * One permissible value for the parameter of the setCardBrand() method.
+# * May also be used as the cardBrand parameter in the CreditCardRequest constructor.
+# * <p>
+# * Other permissible values are
+# * VISA, MASTERCARD, AMERICAN_EXPRESS, DISCOVER, NOVA, AMEX, or EUROCARD,
+# * as well as generic values (to support future card types)
+# * CARD_BRAND_1, CARD_BRAND_2, CARD_BRAND_3, CARD_BRAND_4, CARD_BRAND_5, or CARD_BRAND_6.
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getCardBrand
+# * @see com.paygateway.CreditCardRequest#setCardBrand
+# */
+sub DINERS { "DINERS" }
+
+#*
+# * One permissible value for the parameter of the setCardBrand() method.
+# * May also be used as the cardBrand parameter in the CreditCardRequest constructor.
+# * <p>
+# * Other permissible values are
+# * VISA, MASTERCARD, AMERICAN_EXPRESS, DISCOVER, NOVA, AMEX, or DINERS,
+# * as well as generic values (to support future card types)
+# * CARD_BRAND_1, CARD_BRAND_2, CARD_BRAND_3, CARD_BRAND_4, CARD_BRAND_5, or CARD_BRAND_6.
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getCardBrand
+# * @see com.paygateway.CreditCardRequest#setCardBrand
+# */
+sub EUROCARD { "EUROCARD" }
+
+#**
+# * One permissible value for the parameter of the setCardBrand() method.
+# * May also be used as the cardBrand parameter in the CreditCardRequest constructor.
+# * <p>
+# * Other permissible values are
+# * VISA, MASTERCARD, AMERICAN_EXPRESS, DISCOVER, NOVA, AMEX, DINERS, or EUROCARD,
+# * as well as generic values (to support future card types)
+# * CARD_BRAND_2, CARD_BRAND_3, CARD_BRAND_4, CARD_BRAND_5, or CARD_BRAND_6.
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getCardBrand
+# * @see com.paygateway.CreditCardRequest#setCardBrand
+# */
+sub CARD_BRAND_1 { "CARD_BRAND_1" }
+
+
+#**
+# * One permissible value for the parameter of the setCardBrand() method.
+# * May also be used as the cardBrand parameter in the CreditCardRequest constructor.
+# * <p>
+# * Other permissible values are
+# * VISA, MASTERCARD, AMERICAN_EXPRESS, DISCOVER, NOVA, AMEX, DINERS, or EUROCARD,
+# * as well as generic values (to support future card types)
+# * CARD_BRAND_1, CARD_BRAND_3, CARD_BRAND_4, CARD_BRAND_5, or CARD_BRAND_6.
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getCardBrand
+# * @see com.paygateway.CreditCardRequest#setCardBrand
+# */
+sub CARD_BRAND_2 { "CARD_BRAND_2" }
+
+#**
+# * One permissible value for the parameter of the setCardBrand() method.
+# * May also be used as the cardBrand parameter in the CreditCardRequest constructor.
+# * <p>
+# * Other permissible values are
+# * VISA, MASTERCARD, AMERICAN_EXPRESS, DISCOVER, NOVA, AMEX, DINERS, or EUROCARD,
+# * as well as generic values (to support future card types)
+# * CARD_BRAND_1, CARD_BRAND_2, CARD_BRAND_4, CARD_BRAND_5, or CARD_BRAND_6.
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getCardBrand
+# * @see com.paygateway.CreditCardRequest#setCardBrand
+# */
+sub CARD_BRAND_3 { "CARD_BRAND_3" }
+
+#**
+# * One permissible value for the parameter of the setCardBrand() method.
+# * May also be used as the cardBrand parameter in the CreditCardRequest constructor.
+# * <p>
+# * Other permissible values are
+# * VISA, MASTERCARD, AMERICAN_EXPRESS, DISCOVER, NOVA, AMEX, DINERS, or EUROCARD,
+# * as well as generic values (to support future card types)
+# * CARD_BRAND_1, CARD_BRAND_2, CARD_BRAND_3, CARD_BRAND_5, or CARD_BRAND_6.
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getCardBrand
+# * @see com.paygateway.CreditCardRequest#setCardBrand
+# */
+sub CARD_BRAND_4 { "CARD_BRAND_4" }
+
+#**
+# * One permissible value for the parameter of the setCardBrand() method.
+# * May also be used as the cardBrand parameter in the CreditCardRequest constructor.
+# * <p>
+# * Other permissible values are
+# * VISA, MASTERCARD, AMERICAN_EXPRESS, DISCOVER, NOVA, AMEX, DINERS, or EUROCARD,
+# * as well as generic values (to support future card types)
+# * CARD_BRAND_1, CARD_BRAND_2, CARD_BRAND_3, CARD_BRAND_4, or CARD_BRAND_6.
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getCardBrand
+# * @see com.paygateway.CreditCardRequest#setCardBrand
+# */
+sub CARD_BRAND_5 { "CARD_BRAND_5" }
+
+#**
+# * One permissible value for the parameter of the setCardBrand() method.
+# * May also be used as the cardBrand parameter in the CreditCardRequest constructor.
+# * <p>
+# * Other permissible values are
+# * VISA, MASTERCARD, AMERICAN_EXPRESS, DISCOVER, NOVA, AMEX, DINERS, or EUROCARD,
+# * as well as generic values (to support future card types)
+# * CARD_BRAND_1, CARD_BRAND_2, CARD_BRAND_3, CARD_BRAND_4, or CARD_BRAND_5.
+# * <p>
+# * @see com.paygateway.CreditCardRequest#getCardBrand
+# * @see com.paygateway.CreditCardRequest#setCardBrand
+# */
+sub CARD_BRAND_6 { "CARD_BRAND_6" }
+
+# Transaction Condition code values (CreditCardRequest)
+sub TCC_DEFAULT { 0 }
+sub TCC_CARDHOLDER_NOT_PRESENT_MAIL_FAX_ORDER { 1 }
+sub TCC_CARDHOLDER_NOT_PRESENT_TELEPHONE_ORDER { 2 }
+sub TCC_CARDHOLDER_NOT_PRESENT_INSTALLMENT { 3 }
+sub TCC_CARDHOLDER_NOT_PRESENT_PAYER_AUTHENTICATION { 4 }
+sub TCC_CARDHOLDER_NOT_PRESENT_SECURE_ECOMMERCE { 5 }
+sub TCC_CARDHOLDER_NOT_PRESENT_RECURRING_BILLING { 6 }
+sub TCC_CARDHOLDER_PRESENT_RETAIL_ORDER { 7 }
+sub TCC_CARDHOLDER_PRESENT_RETAIL_ORDER_WITHOUT_SIGNATURE { 8 }
+sub TCC_CARDHOLDER_PRESENT_RETAIL_ORDER_KEYED { 9 }
+sub TCC_CARDHOLDER_NOT_PRESENT_PAYER_AUTHENTICATION_ATTEMPTED { 10 }
+
+################################
+# Special Credit Card constants
+#
+# Duplicate Check
+#no, conflicts with perl# sub CHECK { "CHECK" }
+sub OVERRIDE { "OVERRIDE" }
+sub NO_CHECK { "NO_CHECK" }
+
+
+################################
+# Recurring billing constants
+#
+# Period
+sub PERIOD_WEEKLY { 1 }
+sub PERIOD_BIWEEKLY { 2 }
+sub PERIOD_SEMIMONTHLY { 3 }
+sub PERIOD_MONTHLY { 4 }
+sub PERIOD_QUARTERLY { 5 }
+sub PERIOD_ANNUAL { 6 }
+
+# Command
+sub COMMAND_ADD_CUSTOMER_ACCOUNT_ONLY { "ADD_RECURRENCE" }
+sub COMMAND_ADD_RECURRENCE_ONLY { "ADD_RECURRENCE" }
+sub COMMAND_ADD_CUSTOMER_ACCOUNT_AND_RECURRENCE { "ADD_CUSTOMER_AND_RECURRENCE" }
+
+# Account Type
+sub ACCOUNT_TYPE_CREDIT_CARD { "CREDIT_CARD" }
+
+# TransactionResponse error definitions
+sub TR_ERROR { 0 }
+sub TR_NO_ERROR { 1 }
+
+# CreditCardResponse error definitions
+sub CCR_ERROR { 0 }
+sub CCR_NO_ERROR { 1 }
+
+# BatchResponse error definitions
+sub BR_ERROR { 0 }
+sub BR_NO_ERROR { 1 }
+
+#InitSETResponse error definitions
+sub ISR_ERROR { 0 }
+sub ISR_NO_ERROR { 1 }
+
+# EClient error definitions
+sub ECLIENT_ERROR { 0 }
+sub ECLIENT_NO_ERROR { 1 }
+
+# ESETClient error definitions
+sub ESETCLIENT_ERROR { 0 }
+sub ESETCLIENT_NO_ERROR { 1 }
+
+
+# CESETClient SET result notification constants
+sub HTTP_POST_RESULT_NOTIFICATION_STRING { "HTTP_POST_RESULT_NOTIFICATION" }
+sub EMAIL_RESULT_NOTIFICATION_STRING { "EMAIL_RESULT_NOTIFICATION" }
+sub NO_RESULT_NOTIFICATION_STRING { "NO_RESULT_NOTIFICATION" }
+
+sub EMAIL_RESULT_NOTIFICATION { 1 }
+sub HTTP_POST_RESULT_NOTIFICATION { 2 }
+sub NO_RESULT_NOTIFICATION { 3 }
+
+
+################################
+# Payer Authentication constants
+#
+
+# status
+sub STATUS_ENROLLED { "Y" }
+sub STATUS_NOT_ENROLLED { "N" }
+sub STATUS_ENROLLED_BUT_AUTHENTICATION_UNAVAILABLE { "U" }
+sub AUTHENTICATION_PREFIX {"authentication_"}
+
+
+################################
+# ACH constants
+#
+
+# Account Type
+sub CHECKING { 1 }
+sub SAVINGS { 0 }
+
+# Account Class
+sub PERSONAL { 0 }
+sub CORPORATE { 1 }
+
+################################
+# Industry type constants
+#
+
+# Industry Type
+sub DIRECT_MARKETING { "DIRECT_MARKETING" }
+sub RETAIL { "RETAIL" }
+sub LODGING { "LODGING" }
+sub RESTAURANT { "RESTAURANT" }
+
+1;
diff --git a/t/Business-OnlinePayment-PPIPayMover.t b/t/Business-OnlinePayment-PPIPayMover.t
new file mode 100644
index 0000000..7d69c0d
--- /dev/null
+++ b/t/Business-OnlinePayment-PPIPayMover.t
@@ -0,0 +1,17 @@
+# Before `make install' is performed this script should be runnable with
+# `make test'. After `make install' it should work as `perl Business-OnlinePayment-PPIPayMover.t'
+
+#########################
+
+# change 'tests => 1' to 'tests => last_test_to_print';
+
+use Test;
+BEGIN { plan tests => 1 };
+use Business::OnlinePayment::PPIPayMover;
+ok(1); # If we made it this far, we're ok.
+
+#########################
+
+# Insert your test code below, the Test::More module is use()ed here so read
+# its man page ( perldoc Test::More ) for help writing this test script.
+
diff --git a/t/bad_card.t b/t/bad_card.t
new file mode 100644
index 0000000..0895d63
--- /dev/null
+++ b/t/bad_card.t
@@ -0,0 +1,38 @@
+BEGIN { $| = 1; print "1..1\n"; }
+
+eval "use Net::SSLeay;";
+if ( $@ ) {
+ print "ok 1 # Skipped: Net::SSLeay is not installed\n"; exit;
+}
+
+use Business::OnlinePayment;
+
+my $tx = new Business::OnlinePayment("PPIPayMover");
+$tx->content(
+ type => 'VISA',
+ 'login' => '195325FCC230184964CAB3A8D93EEB31888C42C714E39CBBB2E541884485D04B', #token
+ action => 'Normal Authorization',
+ description => 'Business::OnlinePayment visa test',
+ amount => '0.10',
+ invoice_number => '100100',
+ customer_id => 'jsk',
+ first_name => 'Tofu',
+ last_name => 'Beast',
+ address => '123 Anystreet',
+ city => 'Anywhere',
+ state => 'UT',
+ zip => '84058',
+ phone => '420-543-2199',
+ card_number => '4007000000027',
+ expiration => '08/09',
+);
+$tx->test_transaction(1); # test, dont really charge
+$tx->submit();
+
+if($tx->is_success()) {
+ print "not ok 1\n";
+} else {
+ #warn $tx->server_response."\n";
+ #warn $tx->error_message. "\n";
+ print "ok 1\n";
+}
diff --git a/t/bop.t b/t/bop.t
new file mode 100644
index 0000000..64332c5
--- /dev/null
+++ b/t/bop.t
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n"; }
+END {print "not ok 1\n" unless $loaded;}
+use Business::OnlinePayment;
+$loaded = 1;
+print "ok 1\n";
diff --git a/t/capture.t b/t/capture.t
new file mode 100644
index 0000000..353bf27
--- /dev/null
+++ b/t/capture.t
@@ -0,0 +1,62 @@
+BEGIN { $| = 1; print "1..2\n"; }
+
+#print "ok 1 # Skipped: no separate auth + capture test yet\n";
+#print "ok 2 # Skipped: no separate auth + capture test yet\n";
+#exit;
+
+use Business::OnlinePayment;
+
+my $tx = new Business::OnlinePayment("PPIPayMover");
+$tx->content(
+ type => 'VISA',
+ 'login' => '195325FCC230184964CAB3A8D93EEB31888C42C714E39CBBB2E541884485D04B', #token
+ action => 'Authorization Only',
+ description => 'Business::OnlinePayment auth + capture test',
+ amount => '0.01',
+ invoice_number => '100100',
+ customer_id => '5454',
+ first_name => 'Tofu',
+ last_name => 'Beast',
+ address => '123 Anystreet',
+ city => 'Anywhere',
+ state => 'UT',
+ zip => '84058',
+ card_number => '4007000000027',
+ expiration => '08/06',
+);
+$tx->test_transaction(1); # test, dont really charge
+$tx->submit();
+
+unless($tx->is_success()) {
+ print "not ok 1\n";
+ print "not ok 2\n";
+} else {
+ my $order_number = $tx->order_number;
+ #warn $order_number;
+ print "ok 1\n";
+
+ my $settle_tx = new Business::OnlinePayment("PPIPayMover");
+ $settle_tx->content(
+ type => 'VISA',
+ 'login' => '195325FCC230184964CAB3A8D93EEB31888C42C714E39CBBB2E541884485D04B', #token
+ action => 'Post Authorization',
+ description => 'Business::OnlinePayment auth + capture test',
+ amount => '0.01',
+ invoice_number => '100100',
+ order_number => $order_number,
+ card_number => '4007000000027',
+ expiration => '08/06',
+ customer_id => '5454',
+ );
+
+ $settle_tx->test_transaction(1); # test, dont really charge
+ $settle_tx->submit();
+
+ if($settle_tx->is_success()) {
+ print "ok 2\n";
+ } else {
+ warn $settle_tx->error_message;
+ print "not ok 2\n";
+ }
+
+}
diff --git a/t/credit_card.t b/t/credit_card.t
new file mode 100644
index 0000000..3f00834
--- /dev/null
+++ b/t/credit_card.t
@@ -0,0 +1,39 @@
+BEGIN { $| = 1; print "1..1\n"; }
+
+eval "use Net::SSLeay;";
+if ( $@ ) {
+ print "ok 1 # Skipped: Net::SSLeay is not installed\n"; exit;
+}
+
+use Business::OnlinePayment;
+
+my $tx = new Business::OnlinePayment("PPIPayMover");
+$tx->content(
+ type => 'VISA',
+ 'login' => '195325FCC230184964CAB3A8D93EEB31888C42C714E39CBBB2E541884485D04B', #token
+ action => 'Normal Authorization',
+ description => 'Business::OnlinePayment visa test',
+ amount => '0.01',
+ invoice_number => '100100',
+ customer_id => 'jsk',
+ first_name => 'Tofu',
+ last_name => 'Beast',
+ address => '123 Anystreet',
+ city => 'Anywhere',
+ state => 'UT',
+ zip => '84058',
+ phone => '420-543-2199',
+ card_number => '4005550000000019',
+ expiration => '08/09',
+);
+$tx->test_transaction(1); # test, dont really charge
+$tx->submit();
+
+if($tx->is_success()) {
+ print "ok 1\n";
+} else {
+ #warn $tx->server_response."\n";
+ warn $tx->error_message. "\n";
+ print "not ok 1\n";
+}
+
diff --git a/t/load.t b/t/load.t
new file mode 100644
index 0000000..15c0bea
--- /dev/null
+++ b/t/load.t
@@ -0,0 +1,12 @@
+BEGIN {
+ $| = 1; print "1..1\n";
+ eval "use Net::SSLeay;";
+ if ( $@ ) {
+ print "ok 1 # Skipped: Net::SSLeay is not installed\n"; exit;
+ }
+
+}
+END {print "not ok 1\n" unless $loaded;}
+use Business::OnlinePayment::PPIPayMover;
+$loaded = 1;
+print "ok 1\n";
diff --git a/t/void.t b/t/void.t
new file mode 100644
index 0000000..2b17c5a
--- /dev/null
+++ b/t/void.t
@@ -0,0 +1,65 @@
+BEGIN { $| = 1; print "1..2\n"; }
+
+eval "use Net::SSLeay;";
+if ( $@ ) {
+ print "ok 1 # Skipped: Net::SSLeay is not installed\n"; exit;
+}
+
+use Business::OnlinePayment;
+
+my $tx = new Business::OnlinePayment("PPIPayMover");
+
+$tx->content(
+ type => 'VISA',
+ 'login' => '195325FCC230184964CAB3A8D93EEB31888C42C714E39CBBB2E541884485D04B', #token
+ action => 'Normal Authorization',
+ description => 'Business::OnlinePayment void test',
+ amount => '0.01',
+ card_number => '4445999922225',
+ expiration => '03/10',
+ cvv2 => '999',
+ name => 'Tofu Beast',
+ address => '8320',
+ city => 'Anywhere',
+ state => 'UT',
+ zip => '85284',
+ phone => '415-420-5454',
+ email => 'ivan-ppipaymover-test@420.am',
+ customer_id => '5454',
+);
+$tx->test_transaction(1); # test, dont really charge
+$tx->submit();
+
+if($tx->is_success()) {
+ print "ok 1\n";
+} else {
+ #warn $tx->server_response."\n";
+ warn $tx->error_message. "\n";
+ print "not ok 1\n";
+}
+
+my $v_tx = new Business::OnlinePayment("PPIPayMover");
+
+$v_tx->content(
+ type => 'VISA',
+ 'login' => '195325FCC230184964CAB3A8D93EEB31888C42C714E39CBBB2E541884485D04B', #token
+ action => 'Void',
+ description => 'Business::OnlinePayment::PPIPayMover test',
+ customer_id => '5454',
+ order_number => $tx->order_number(),
+);
+
+$v_tx->test_transaction(1); # test, dont really charge
+$v_tx->submit();
+
+if($v_tx->is_success()) {
+ print "ok 2\n";
+} else {
+ #warn $v_tx->server_response."\n";
+ warn $v_tx->error_message. "\n";
+ print "not ok 2\n";
+}
+
+
+
+