240 lines
6.8 KiB
Perl
240 lines
6.8 KiB
Perl
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;
|
|
|