package Business::OnlinePayment::CyberSource::Role::TransactionHandling;
use 5.010;
use strict;
use warnings;
use namespace::autoclean;
use DateTime;
use Moose::Role;
use MooseX::StrictConstructor;
use Try::Tiny;
use Business::OnlinePayment::CyberSource::Client;
# ABSTRACT: Transaction handling role for BOP::CyberSource
our $VERSION = '3.000006'; # VERSION
#### Subroutine Definitions ####
# Submits the transaction request to CyberSource
# Accepts: Nothing
# Returns: Nothing
sub submit {
my ( $self ) = @_;
my $content = { $self->content() };
# Default values
my $data = {
reference_code => $content->{invoice_number}
};
$content->{currency} ||= 'USD';
# purchaser information
my $map = {
ip => 'customer_ip',
first_name => 'first_name',
last_name => 'last_name',
email => 'email',
phone_number => 'phone',
street1 => 'address',
city => 'city',
state => 'state',
postal_code => 'zip',
country => 'country',
};
foreach my $name ( keys %$map ) {
if (
$content->{ $map->{$name} }
&& $content->{action} !~ /^Post\ Authorization|Void$/ix
) {
$data->{bill_to}->{$name} = $content->{ $map->{$name} }
unless ( $content->{po_number} && $content->{action} =~ /^Credit$/ix );
}
}
# Purchase totals information
$data->{purchase_totals} = {
total => $content->{amount},
currency => $content->{currency},
};
$data->{service} = { request_id => $content->{po_number} }
if $content->{po_number};
$data->{reference_code} = $content->{invoice_number}
if $content->{invoice_number}
;
# Other fields
$data->{comments} = $content->{description} if $content->{description};
$self->transaction_type( $content->{type} );
if ( $content->{action} =~ qr/^authorization\ only|normal\ authorization|credit$/ix ) {
given ( $content->{type} ) {
when ( /^CC$/x ) {
#Credit Card information
my $expiration = $self->_expiration_to_datetime( $content->{expiration} );
$data->{card}->{account_number} = $content->{card_number};
$data->{card}->{expiration} = $expiration if $expiration;
$data->{card}->{security_code} = $content->{cvv2} if $content->{cvv2};
}
default {
Exception::Base->throw("$_ is an invalid payment type");
}
}
}
$self->username( $content->{login} );
$self->password( $content->{password} );
my $result = 0;
given ( $content->{action} ) {
when ( /^authorization\ only$/ix ) {
$result = $self->authorize( $data );
}
when ( /^normal\ authorization$/ix ) {
$result = $self->sale( $data );
}
when ( /^post\ authorization$/ix ) {
$result = $self->capture( $data );
}
when ( /^void$/ix ) {
$result = $self->auth_reversal( $data );
}
when ( /^credit$/ix ) {
$result = $self->credit( $data );
}
default {
Exception::Base->throw( "$_ is an invalid action" );
}
}
return $result;
}
# Converts an expiration date string to a DateTime object
# Accepts: An expiration date expressed as YYYY-MM-DD, MM/YY, or MMYY
# Returns: A DateTime object on success and undef otherwise
sub _expiration_to_datetime {
my ( undef, $date ) = @_;
my $year = 0;
my $month = 0;
return unless defined $date;
$date = '' unless $date;
if ( $date ) {
if ( $date =~ /^\d{2}\/\d{2,4}$/x ) {
( $month, $year ) = split '/', $date;
}
if ( $date =~ /^\d{4}$/x ) {
$month = substr $date, 0, 2;
$year = substr $date, 2, 2;
}
if ( $date =~ /^\d{4}-\d{2}-\d{2}\b/x ) {
( $year, $month ) = split '-', $date;
}
}
$year = 0 if ( $year < 0 );
$year += 2000 if ( $year < 100 && $year >= 0 );
my $expiration = DateTime->last_day_of_month( year => $year, month => $month );
return $expiration;
}
#### Object Attributes ####
## no critic ( RegularExpressions::ProhibitComplexRegexes )
has _client => (
isa => 'Business::OnlinePayment::CyberSource::Client',
is => 'bare',
default => sub { Business::OnlinePayment::CyberSource::Client->new() },
required => 0,
handles => qr/^(?:
is_\w+
|auth\w+
|order\w+
|card\w+
|fraud\w+
|\w*response\w*
|\w+code
|\w*transaction\w*
|require\w+
|server
|sale
|port
|path
|username
|login
|password
| error_message
| failure_status
| capture
|invoice_number
|credit
)$/x,
init_arg => undef,
lazy => 1,
);
#### Method Modifiers ####
1;
__END__
=pod
=head1 NAME
Business::OnlinePayment::CyberSource::Role::TransactionHandling - Transaction handling role for BOP::CyberSource
=head1 VERSION
version 3.000006
=head1 SYNOPSIS
package Thing;
use Moose;
with 'Business::OnlinePayment::CyberSource::Role::TransactionHandling';
1;
my $thing = Thing->new();
$thing->submit();
=head1 DESCRIPTION
This role provides consumers with methods for sending transaction requests to CyberSource and handling responses to those requests.
=head1 METHODS
=head2 submit
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website
https://github.com/hgdev/Business-OnlinePayment-CyberSource/issues
When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.
=head1 AUTHORS
=over 4
=item *
Jad Wauthier <Jadrien dot Wauthier at GMail dot com>
=item *
Caleb Cushing <xenoterracide@gmail.com>
=item *
Peter Bowen <peter@bowenfamily.org>
=back
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2012 by Hostgator.com.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut