From 1d54196f449ba5f5f1ab9ac67cd2ad7086dd3497 Mon Sep 17 00:00:00 2001 From: Colin Kuskie Date: Wed, 27 Jul 2011 13:23:35 -0700 Subject: [PATCH] Add payment driver for Authorize.net. i18n, upgrade script, config file changes, and new template. --- .../shopping-cart-collateral-items.wgpkg | Bin 0 -> 78938 bytes docs/upgrades/upgrade_7.10.21-7.10.22.pl | 11 + etc/WebGUI.conf.original | 1 + lib/WebGUI/Shop/PayDriver/CreditCard.pm | 240 ++++++++++++++++ .../Shop/PayDriver/CreditCard/AuthorizeNet.pm | 267 ++++++++++++++++++ .../i18n/English/PayDriver_AuthorizeNet.pm | 50 ++++ .../i18n/English/PayDriver_CreditCard.pm | 161 +++++++++++ sbin/testEnvironment.pl | 2 + 8 files changed, 732 insertions(+) create mode 100644 docs/upgrades/packages-7.10.22/shopping-cart-collateral-items.wgpkg create mode 100644 lib/WebGUI/Shop/PayDriver/CreditCard.pm create mode 100644 lib/WebGUI/Shop/PayDriver/CreditCard/AuthorizeNet.pm create mode 100644 lib/WebGUI/i18n/English/PayDriver_AuthorizeNet.pm create mode 100644 lib/WebGUI/i18n/English/PayDriver_CreditCard.pm diff --git a/docs/upgrades/packages-7.10.22/shopping-cart-collateral-items.wgpkg b/docs/upgrades/packages-7.10.22/shopping-cart-collateral-items.wgpkg new file mode 100644 index 0000000000000000000000000000000000000000..b48ee8eb872d97587d99bb0e4af77686e62ea6e2 GIT binary patch literal 78938 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

>@;% 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 GssjMQJ?h#3 literal 0 HcmV?d00001 diff --git a/docs/upgrades/upgrade_7.10.21-7.10.22.pl b/docs/upgrades/upgrade_7.10.21-7.10.22.pl index 660f8b034..1ee778a94 100644 --- a/docs/upgrades/upgrade_7.10.21-7.10.22.pl +++ b/docs/upgrades/upgrade_7.10.21-7.10.22.pl @@ -31,6 +31,7 @@ my $quiet; # this line required my $session = start(); # this line required # upgrade functions go here +addAuthorizePaymentDriver($session); finish($session); # this line required @@ -44,6 +45,16 @@ finish($session); # this line required # print "DONE!\n" unless $quiet; #} +#---------------------------------------------------------------------------- +# Add the Authorize.net payment driver to each config file +sub addAuthorizePaymentDriver { + my $session = shift; + print "\tAdd the Authorize.net payment driver... " unless $quiet; + # and here's our code + $session->config->addToArray('paymentDrivers', 'WebGUI::Shop::PayDriver::CreditCard::AuthorizeNet'); + print "DONE!\n" unless $quiet; +} + # -------------- DO NOT EDIT BELOW THIS LINE -------------------------------- diff --git a/etc/WebGUI.conf.original b/etc/WebGUI.conf.original index 806a9d94b..0371550b7 100644 --- a/etc/WebGUI.conf.original +++ b/etc/WebGUI.conf.original @@ -200,6 +200,7 @@ "WebGUI::Shop::PayDriver::ITransact", "WebGUI::Shop::PayDriver::PayPal::PayPalStd", "WebGUI::Shop::PayDriver::PayPal::ExpressCheckout", + "WebGUI::Shop::PayDriver::CreditCard::AuthorizeNet", "WebGUI::Shop::PayDriver::Ogone" ], diff --git a/lib/WebGUI/Shop/PayDriver/CreditCard.pm b/lib/WebGUI/Shop/PayDriver/CreditCard.pm new file mode 100644 index 000000000..fe41ac590 --- /dev/null +++ b/lib/WebGUI/Shop/PayDriver/CreditCard.pm @@ -0,0 +1,240 @@ +package WebGUI::Shop::PayDriver::CreditCard; + +use strict; +use Readonly; + +=head1 NAME + +WebGUI::Shop::PayDriver::CreditCard + +=head2 DESCRIPTION + +A base class for credit card payment drivers. They all need pretty much the +same information, the only difference is the servers you talk to. Leaves you +to handle recurring payments, processPayment, www_edit, and whatever else you +want to - but the user-facing code is pretty much taken care of. + +=head2 METHODS + +The following methods are available from this class. + +=cut + +use base qw/WebGUI::Shop::PayDriver/; + +Readonly my $I18N => 'PayDriver_CreditCard'; + +#------------------------------------------------------------------- +sub _monthYear { + my $session = shift; + my $form = $session->form; + + tie my %months, "Tie::IxHash"; + tie my %years, "Tie::IxHash"; + %months = map { sprintf( '%02d', $_ ) => sprintf( '%02d', $_ ) } 1 .. 12; + %years = map { $_ => $_ } 2004 .. 2099; + + my $monthYear = + WebGUI::Form::selectBox( $session, { + name => 'expMonth', + options => \%months, + value => [ $form->process("expMonth") ] + }) + . " / " + . WebGUI::Form::selectBox( $session, { + name => 'expYear', + options => \%years, + value => [ $form->process("expYear") ] + }); + + return $monthYear; +} + +#------------------------------------------------------------------- + +=head2 appendCredentialVars + +Add template vars for www_getCredentials. Override this to add extra fields. + +=cut + +sub appendCredentialVars { + my ($self, $var) = @_; + my $session = $self->session; + my $u = $session->user; + my $form = $session->form; + my $i18n = WebGUI::International->new($session, $I18N); + + $var->{formHeader} = WebGUI::Form::formHeader($session) + . $self->getDoFormTags('pay'); + + $var->{formFooter} = WebGUI::Form::formFooter(); + + my @fieldLoop; + + # Credit card information + $var->{cardNumberField} = WebGUI::Form::text($session, { + name => 'cardNumber', + value => $self->session->form->process("cardNumber"), + }); + $var->{monthYearField} = WebGUI::Form::readOnly($session, { + value => _monthYear( $session ), + }); + $var->{cvv2Field} = WebGUI::Form::integer($session, { + name => 'cvv2', + value => $self->session->form->process("cvv2"), + }) if $self->get('useCVV2'); + + $var->{checkoutButton} = WebGUI::Form::submit($session, { + value => $i18n->get('checkout button', 'Shop'), + }); + + return; +} + +#------------------------------------------------------------------- +sub definition { + my ($class, $session, $definition) = @_; + + my $i18n = WebGUI::International->new($session, $I18N); + + tie my %fields, 'Tie::IxHash', ( + useCVV2 => { + fieldType => 'yesNo', + label => $i18n->get('use cvv2'), + hoverHelp => $i18n->get('use cvv2 help'), + }, + credentialsTemplateId => { + fieldType => 'template', + label => $i18n->get('credentials template'), + hoverHelp => $i18n->get('credentials template help'), + namespace => 'Shop/Credentials', + defaultValue => 'itransact_credentials1', + }, + ); + + push @{ $definition }, { + name => 'Credit Card Base Class', + properties => \%fields, + }; + + return $class->SUPER::definition($session, $definition); +} + +#------------------------------------------------------------------- + +=head2 processCredentials + +Process the form where credentials (name, address, phone number and credit card information) +are entered. + +=cut + +sub processCredentials { + my $self = shift; + my $session = $self->session; + my $form = $session->form; + my $i18n = WebGUI::International->new($session, $I18N); + my @error; + + # Check credit card data + push @error, $i18n->get( 'invalid card number' ) unless $form->integer('cardNumber'); + push @error, $i18n->get( 'invalid cvv2' ) if ($self->get('useCVV2') && !$form->integer('cvv2')); + + # Check if expDate and expYear have sane values + my ($currentYear, $currentMonth) = $self->session->datetime->localtime; + my $expires = $form->integer( 'expYear' ) . sprintf '%02d', $form->integer( 'expMonth' ); + my $now = $currentYear . sprintf '%02d', $currentMonth; + + push @error, $i18n->get('invalid expiration date') unless $expires =~ m{^\d{6}$}; + push @error, $i18n->get('expired expiration date') unless $expires >= $now; + + return \@error if scalar @error; + # Everything ok process the actual data + $self->{ _cardData } = { + acct => $form->integer( 'cardNumber' ), + expMonth => $form->integer( 'expMonth' ), + expYear => $form->integer( 'expYear' ), + cvv2 => $form->integer( 'cvv2' ), + }; + + return; +} + +#------------------------------------------------------------------- + +=head2 www_getCredentials ( $errors ) + +Build a templated form for asking the user for their credentials. + +=head3 $errors + +An array reference of errors to show the user. + +=cut + +sub www_getCredentials { + my $self = shift; + my $errors = shift; + my $session = $self->session; + my $form = $session->form; + my $i18n = WebGUI::International->new($session, $I18N); + my $var = {}; + +# Process form errors + $var->{errors} = []; + if ($errors) { + $var->{error_message} = $i18n->get('error occurred message'); + foreach my $error (@{ $errors} ) { + push @{ $var->{errors} }, { error => $error }; + } + } + + $self->appendCredentialVars($var); + $self->appendCartVariables($var); + + my $template = WebGUI::Asset::Template->new($session, $self->get("credentialsTemplateId")); + my $output; + if (defined $template) { + $template->prepare; + $output = $template->process($var); + } + else { + $output = $i18n->get('template gone'); + } + + return $session->style->userStyle($output); +} + +#------------------------------------------------------------------- + +=head2 www_pay + +Makes sure that the user has all the requirements for checking out, including +getting credentials, it processes the transaction and then displays a thank +you screen. + +=cut + +sub www_pay { + my $self = shift; + my $session = $self->session; + # Check whether the user filled in the checkout form and process those. + my $credentialsErrors = $self->processCredentials; + + # Go back to checkout form if credentials are not ok + return $self->www_getCredentials( $credentialsErrors ) if $credentialsErrors; + + # Payment time! + my $transaction = $self->processTransaction( ); + + if ($transaction->get('isSuccessful')) { + return $transaction->thankYou(); + } + + # Payment has failed... + return $self->displayPaymentError($transaction); +} + +1; + diff --git a/lib/WebGUI/Shop/PayDriver/CreditCard/AuthorizeNet.pm b/lib/WebGUI/Shop/PayDriver/CreditCard/AuthorizeNet.pm new file mode 100644 index 000000000..dbeb31dee --- /dev/null +++ b/lib/WebGUI/Shop/PayDriver/CreditCard/AuthorizeNet.pm @@ -0,0 +1,267 @@ +package WebGUI::Shop::PayDriver::CreditCard::AuthorizeNet; + +use strict; + +use base qw/WebGUI::Shop::PayDriver::CreditCard/; + +use DateTime; +use Readonly; +use Business::OnlinePayment; + +Readonly my $I18N => 'PayDriver_AuthorizeNet'; + +=head1 NAME + +WebGUI::Shop::PayDriver::CreditCard::AuthorizeNet + +=head1 DESCRIPTION + +Payment driver that uses Business::OnlinePayment to process transactions +through Authorize.net + +=head1 SYNOPSIS + + # in webgui config file... + + "paymentDrivers" : [ + "WebGUI::Shop::PayDriver::Cash", + "WebGUI::Shop::PayDriver::CreditCard::AuthorizeNet", + ... + ], + +=head1 METHODS + +The following methods are available from this class: + +=cut + +#------------------------------------------------------------------- + +=head2 appendCredentialVars ( var ) + +Overridden to add the card type field + +=cut + +sub appendCredentialVars { + my ( $self, $var ) = @_; + my $session = $self->session; + my $i18n = WebGUI::International->new( $session, $I18N ); + $self->SUPER::appendCredentialVars($var); + + $var->{cardTypeField} = WebGUI::Form::selectBox( + $session, { + name => 'cardType', + options => { map { $_ => $_ } ( 'Visa', 'MasterCard', 'American Express', 'Discover', ) }, + } + ); + + return; +} ## end sub appendCredentialVars + +#------------------------------------------------------------------- + +=head2 cancelRecurringPayment ( transaction ) + +Cancels a recurring transaction. Returns an array containing ( isSuccess, gatewayStatus, gatewayError). + +=head3 transaction + +The instanciated recurring transaction object. + +=cut + +sub cancelRecurringPayment { + my ( $self, $transaction ) = @_; + my $session = $self->session; + + my $tx = $self->gatewayObject; + $tx->content( + subscription => $transaction->get('transactionCode'), + login => $self->get('login'), + password => $self->get('transaction_key'), + action => 'Cancel Recurring Authorization', + ); + $tx->submit; + + return $self->gatewayResponse($tx); +} + +#------------------------------------------------------------------- +sub definition { + my ( $class, $session, $definition ) = @_; + + my $i18n = WebGUI::International->new( $session, $I18N ); + + tie my %fields, 'Tie::IxHash', ( + login => { + fieldType => 'text', + label => $i18n->get('login'), + hoverHelp => $i18n->get('login help'), + }, + transaction_key => { + fieldType => 'text', + label => $i18n->get('transaction key'), + hoverHelp => $i18n->get('transaction key help'), + }, + testMode => { + fieldType => 'YesNo', + label => $i18n->get('test mode'), + hoverHelp => $i18n->get('test mode help'), + }, + ); + + push @{$definition}, { + name => $i18n->get('name'), + properties => \%fields, + }; + + return $class->SUPER::definition( $session, $definition ); +} ## end sub definition + +#------------------------------------------------------------------- + +=head2 gatewayObject ( params ) + +Returns a Business::OnlinePayment object, possibly with options set from the +paydriver properties. params can be a hashref of the options that would +normally be passed to tx->content, in which case these will be passed along. + +=cut + +sub gatewayObject { + my ( $self, $params ) = @_; + + my $tx = Business::OnlinePayment->new('AuthorizeNet'); + if ( $self->get('testMode') ) { + + # Yes, we need to do both these things. The BOP interfaces tend to + # ony honor one or the other of them. + $tx->test_transaction(1); + $tx->server('test.authorize.net'); + } + $tx->content(%$params) if $params; + + return $tx; +} + +#------------------------------------------------------------------- + +=head2 gatewayResponse ( tx ) + +Returns the various responses required by the PayDriver interface from the +passed Business::OnlinePayment object. + +=cut + +sub gatewayResponse { + my ( $self, $tx ) = @_; + return ( $tx->is_success, $tx->order_number, $tx->result_code, $tx->error_message ); +} + +#------------------------------------------------------------------- + +sub handlesRecurring {1} + +#------------------------------------------------------------------- + +=head2 paymentParams + +Returns a hashref of the billing address and card information, translated into +a form that Business::OnlinePayment likes + +=cut + +sub paymentParams { + my $self = shift; + my $card = $self->{_cardData}; + my $bill = $self->getCart->getBillingAddress->get(); + + my %params = ( + type => $card->{type}, + login => $self->get('login'), + transaction_key => $self->get('transaction_key'), + first_name => $bill->{firstName}, + last_name => $bill->{lastName}, + address => $bill->{address1}, + city => $bill->{city}, + state => $bill->{state}, + zip => $bill->{code}, + card_number => $card->{acct}, + expiration => sprintf '%2d/%2d', + @{$card}{ 'expMonth', 'expYear' }, + ); + $params{cvv2} = $card->{cvv2} if $self->get('useCVV2'); + return \%params; +} ## end sub paymentParams + +#------------------------------------------------------------------- + +sub processCredentials { + my $self = shift; + my $session = $self->session; + my $i18n = WebGUI::International->new( $session, $I18N ); + my $error = $self->SUPER::processCredentials; + + my $type = $session->form->process('cardType'); + + unless ($type) { + $error ||= []; + push @$error, $i18n->get('invalid cardType'); + } + + return $error if defined $error; + + $self->{_cardData}->{type} = $type; + + return; +} ## end sub processCredentials + +#------------------------------------------------------------------- + +sub processPayment { + my ( $self, $transaction ) = @_; + my $params = $self->paymentParams; + + if ( $transaction->isRecurring ) { + my $items = $transaction->getItems; + if ( @$items > 1 ) { + WebGUI::Error::InvalidParam->throw( + error => 'This payment gateway can only handle one recurring item at a time' ); + } + + my $item = $items->[0]; + my $sku = $item->getSku; + + my %translateInterval = ( + Weekly => '7 days', + BiWeekly => '14 days', + FourWeekly => '28 days', + Monthly => '1 month', + Quarterly => '3 months', + HalfYearly => '6 months', + Yearly => '12 months', + ); + + # BOP::AuthorizeNet::ARB has an API that's inconsistant with the AIM + # api -- it wants password instead of transaction_key. Go figure. + $params->{password} = delete $params->{transaction_key}; + + $params->{action} = 'Recurring Authorization'; + $params->{interval} = $translateInterval{ $sku->getRecurInterval }; + $params->{start} = DateTime->today->ymd; + $params->{periods} = '9999'; # magic value that means 'never stop' + $params->{description} = $item->get('configuredTitle'); + } ## end if ( $transaction->isRecurring) + else { + $params->{action} = 'Normal Authorization'; + } + + $params->{amount} = $transaction->get('amount'); + my $tx = $self->gatewayObject($params); + $tx->submit; + return $self->gatewayResponse($tx); +} ## end sub processPayment + +1; + diff --git a/lib/WebGUI/i18n/English/PayDriver_AuthorizeNet.pm b/lib/WebGUI/i18n/English/PayDriver_AuthorizeNet.pm new file mode 100644 index 000000000..312c19781 --- /dev/null +++ b/lib/WebGUI/i18n/English/PayDriver_AuthorizeNet.pm @@ -0,0 +1,50 @@ +package WebGUI::i18n::English::PayDriver_AuthorizeNet; + +use strict; + +our $I18N = { + 'cardType' => { + message => q{Card Type}, + lastUpdated => 1101772177, + context => q{Form label in the checkout form of the AuthorizeNet module.}, + }, + 'login' => { + message => q{API Login}, + lastUpdated => 1247613128, + context => q{Form label in the configuration form of the AuthorizeNet module.}, + }, + 'login help' => { + message => q{The API login id for your Authorize.net account}, + lastUpdated => 1247613146, + context => q{Hover help for the login field of the AuthorizeNet module}, + }, + 'name' => { + message => q{Credit Card (Authorize.net)}, + lastUpdated => 0, + context => q{Name of the Authorize.net module}, + }, + 'test mode' => { + message => q{Test Mode}, + lastUpdated => 0, + context => q{Form label for test mode toggle in AuthroizeNet module}, + }, + 'test mode help' => { + message => q{Whether calls using this gateway should be made in test mode}, + lastUpdated => 0, + context => q{Hover help for test mode form field}, + }, + 'transaction key' => { + message => q{Transaction Key}, + lastUpdated => 1247613060, + context => q{Form label in the configuration form of the AuthorizeNet module.}, + }, + 'transaction key help' => { + message => q{The Transaction Key for your Authorize.net account}, + lastUpdated => 1247613119, + context => q{Hover help for the password field of the AuthorizeNet module}, + }, +}; + +1; + +#vim:ft=perl diff --git a/lib/WebGUI/i18n/English/PayDriver_CreditCard.pm b/lib/WebGUI/i18n/English/PayDriver_CreditCard.pm new file mode 100644 index 000000000..ba38c60f4 --- /dev/null +++ b/lib/WebGUI/i18n/English/PayDriver_CreditCard.pm @@ -0,0 +1,161 @@ +package WebGUI::i18n::English::PayDriver_CreditCard; +use strict; + +our $I18N = { + 'cardNumber' => { + message => q|Credit card number|, + lastUpdated => 1101772177, + context => q|Form label in the checkout form of the Credit Card module.| + }, + 'credentials template' => { + message => q|Credentials Template|, + lastUpdated => 0, + context => q|Form label in the configuration form of the Credit Card module.| + }, + 'credentials template help' => { + message => q|Pick a template to display the form where the user will enter in their billing information and credit card information.|, + lastUpdated => 0, + context => q|Hover help for the credentials template field in the configuration form of the Credit Card module.| + }, + 'cvv2' => { + message => q|Verification number (ie. CVV2)|, + lastUpdated => 1101772182, + context => q|Form label in the checkout form of the Credit Card module.| + }, + 'error occurred message' => { + message => q|The following errors occurred:|, + lastUpdated => 0, + context => q|The message that tell the user that there were some errors in their submitted credentials.|, + }, + 'expiration date' => { + message => q|Expiration date|, + lastUpdated => 1101772180, + context => q|Form label in the checkout form of the Credit Card module.| + }, + 'expired expiration date' => { + message => q|The expiration date on your card has already passed.|, + lastUpdated => 0, + context => q|An error indicating that an an expired card was used.| + }, + 'invalid firstName' => { + message => q|You have to enter a valid first name.|, + lastUpdated => 0, + context => q|An error indicating that an invalid first name has been entered.| + }, + 'invalid lastName' => { + message => q|You have to enter a valid last name.|, + lastUpdated => 0, + context => q|An error indicating that an invalid last name has been entered.| + }, + 'invalid address' => { + message => q|You have to enter a valid address.|, + lastUpdated => 0, + context => q|An error indicating that an invalid street has been entered.| + }, + 'invalid city' => { + message => q|You have to enter a valid city.|, + lastUpdated => 0, + context => q|An error indicating that an invalid city has been entered.| + }, + 'invalid zip' => { + message => q|You have to enter a valid zipcode.|, + lastUpdated => 0, + context => q|An error indicating that an invalid zipcode has been entered.| + }, + 'invalid email' => { + message => q|You have to enter a valid email address.|, + lastUpdated => 0, + context => q|An error indicating that an invalid email address has been entered.| + }, + 'invalid card number' => { + message => q|You have to enter a valid credit card number.|, + lastUpdated => 0, + context => q|An error indicating that an invalid credit card number has been entered.| + }, + 'invalid cvv2' => { + message => q|You have to enter a valid card security code (ie. cvv2).|, + lastUpdated => 0, + context => q|An error indicating that an invalid card security code has been entered.| + }, + 'invalid expiration date' => { + message => q|You have to enter a valid expiration date.|, + lastUpdated => 0, + context => q|An error indicating that an invalid expiration date has been entered.| + }, + 'template gone' => { + message => q|The template for entering in credentials has been deleted. Please notify the site administrator.|, + lastUpdated => 0, + context => q|Error message when the getCredentials template cannot be accessed.| + }, + 'use cvv2' => { + message => q|Use CVV2|, + lastUpdated => 0, + context => q|Form label in the configuration form of the Credit Card module.| + }, + 'use cvv2 help' => { + message => q|Set this option to yes if you want to use CVV2.|, + lastUpdated => 0, + context => q|Form label in the configuration form of the Credit Card module.| + }, + + 'edit credentials template' => { + message => q|Edit Credentials Template|, + lastUpdated => 0, + context => q|Title of the help page.| + }, + 'edit credentials template help' => { + message => q|This template is used to display a form to the user where they can enter in contact and credit card billing information.|, + lastUpdated => 0, + context => q|Title of the help page.| + }, + + 'errors help' => { + message => q{A template loop containing a list of errors from processing the form.}, + lastUpdated => 0, + context => q{Template variable help.}, + }, + 'error help' => { + message => q{One error from the errors loop. It will have minimal markup.}, + lastUpdated => 0, + context => q{Template variable help.}, + }, + 'addressField help' => { + message => q{A single text field for the user to enter in their street address.}, + lastUpdated => 0, + context => q{Template variable help.}, + }, + 'emailField help' => { + message => q{A single text field for the user to enter in their email address.}, + lastUpdated => 1231192368, + context => q{Template variable help.}, + }, + 'cardNumberField help' => { + message => q{A single text field for the user to enter in their credit card number.}, + lastUpdated => 0, + context => q{Template variable help.}, + }, + 'monthYearField help' => { + message => q{A combination form field for the user to enter in the month and year of the expiration date for the credit card.}, + lastUpdated => 0, + context => q{Template variable help.}, + }, + 'cvv2Field help' => { + message => q{A single text field for the user to enter in their credit card verification number. If the PayDriver is not configured to use CVV2, then this field will be empty.}, + lastUpdated => 0, + context => q{Template variable help.}, + }, + 'checkoutButton help' => { + message => q{A button with an internationalized label to submit the form and continue the checkout process.}, + lastUpdated => 0, + context => q{Template variable help.}, + }, + + 'fields help' => { + message => q{A loop of all the available fields for convenience. Each +entry in the loop contains name (field name), label (an internationalized +label for the field), and field (the same as in stateField, cityField, etc).}, + lastUpdated => 0, + }, +}; + +1; diff --git a/sbin/testEnvironment.pl b/sbin/testEnvironment.pl index 68cfec516..1e7410c10 100755 --- a/sbin/testEnvironment.pl +++ b/sbin/testEnvironment.pl @@ -144,6 +144,8 @@ checkModule("CSS::Minifier::XS", "0.03" ); checkModule("JavaScript::Minifier::XS", "0.05" ); checkModule("Readonly", "1.03" ); checkModule("Business::PayPal::API", "0.62" ); +checkModule("Business::OnlinePayment", "3.01" ); +checkModule("Business::OnlinePayment::AuthorizeNet", "3.21" ); checkModule("Locales", "0.10" ); checkModule("Test::Harness", "3.17" ); checkModule("DateTime::Event::ICal", "0.10" );