From 0aa824efca85bf4ae52559ea4b974b817c0a93b1 Mon Sep 17 00:00:00 2001 From: ivan Date: Sun, 23 May 2010 20:54:19 +0000 Subject: [PATCH] initial import --- Changes | 5 + MANIFEST | 11 ++ Makefile.PL | 19 +++ README | 55 +++++++++ ignore.txt | 12 ++ lib/Business/OnlinePayment/CardFortress.pm | 192 +++++++++++++++++++++++++++++ t/00-load.t | 10 ++ t/boilerplate.t | 55 +++++++++ t/manifest.t | 13 ++ t/pod-coverage.t | 18 +++ t/pod.t | 12 ++ 11 files changed, 402 insertions(+) create mode 100644 Changes create mode 100644 MANIFEST create mode 100644 Makefile.PL create mode 100644 README create mode 100644 ignore.txt create mode 100644 lib/Business/OnlinePayment/CardFortress.pm create mode 100644 t/00-load.t create mode 100644 t/boilerplate.t create mode 100644 t/manifest.t create mode 100644 t/pod-coverage.t create mode 100644 t/pod.t diff --git a/Changes b/Changes new file mode 100644 index 0000000..4233359 --- /dev/null +++ b/Changes @@ -0,0 +1,5 @@ +Revision history for Business-OnlinePayment-CardFortress + +0.01 Date/time + First version, released on an unsuspecting world. + diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..4ea168e --- /dev/null +++ b/MANIFEST @@ -0,0 +1,11 @@ +Changes +MANIFEST +Makefile.PL +README +ignore.txt +lib/Business/OnlinePayment/CardFortress.pm +t/00-load.t +t/boilerplate.t +t/manifest.t +t/pod-coverage.t +t/pod.t diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..15bd3f6 --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,19 @@ +use strict; +use warnings; +use ExtUtils::MakeMaker; + +WriteMakefile( + NAME => 'Business::OnlinePayment::CardFortress', + AUTHOR => q{Ivan Kohler }, + VERSION_FROM => 'lib/Business/OnlinePayment/CardFortress.pm', + ABSTRACT_FROM => 'lib/Business/OnlinePayment/CardFortress.pm', + ($ExtUtils::MakeMaker::VERSION >= 6.3002 + ? ('LICENSE'=> 'perl') + : ()), + PL_FILES => {}, + PREREQ_PM => { + 'Test::More' => 0, + }, + dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, + clean => { FILES => 'Business-OnlinePayment-CardFortress-*' }, +); diff --git a/README b/README new file mode 100644 index 0000000..c43b50c --- /dev/null +++ b/README @@ -0,0 +1,55 @@ +Business-OnlinePayment-CardFortress + +The README is used to introduce the module and provide instructions on +how to install the module, any machine dependencies it may have (for +example C compilers and installed libraries) and any other information +that should be provided before the module is installed. + +A README file is required for CPAN modules since CPAN extracts the README +file from a module distribution so that people browsing the archive +can use it to get an idea of the module's uses. It is usually a good idea +to provide version information here so that people can decide whether +fixes for the module are worth downloading. + + +INSTALLATION + +To install this module, run the following commands: + + perl Makefile.PL + make + make test + make install + +SUPPORT AND DOCUMENTATION + +After installing, you can find documentation for this module with the +perldoc command. + + perldoc Business::OnlinePayment::CardFortress + +You can also look for information at: + + RT, CPAN's request tracker + http://rt.cpan.org/NoAuth/Bugs.html?Dist=Business-OnlinePayment-CardFortress + + AnnoCPAN, Annotated CPAN documentation + http://annocpan.org/dist/Business-OnlinePayment-CardFortress + + CPAN Ratings + http://cpanratings.perl.org/d/Business-OnlinePayment-CardFortress + + Search CPAN + http://search.cpan.org/dist/Business-OnlinePayment-CardFortress/ + + +LICENSE AND COPYRIGHT + +Copyright (C) 2010 Ivan Kohler + +This program is free software; you can redistribute it and/or modify it +under the terms of either: the GNU General Public License as published +by the Free Software Foundation; or the Artistic License. + +See http://dev.perl.org/licenses/ for more information. + diff --git a/ignore.txt b/ignore.txt new file mode 100644 index 0000000..0a16e68 --- /dev/null +++ b/ignore.txt @@ -0,0 +1,12 @@ +blib* +Makefile +Makefile.old +Build +Build.bat +_build* +pm_to_blib* +*.tar.gz +.lwpcookies +cover_db +pod2htm*.tmp +Business-OnlinePayment-CardFortress-* diff --git a/lib/Business/OnlinePayment/CardFortress.pm b/lib/Business/OnlinePayment/CardFortress.pm new file mode 100644 index 0000000..513ed26 --- /dev/null +++ b/lib/Business/OnlinePayment/CardFortress.pm @@ -0,0 +1,192 @@ +package Business::OnlinePayment::CardFortress; + +use base qw( Business::OnlinePayment::HTTPS ); + +use warnings; +use strict; +#use vars qw( $DEBUG $me ); + +our $VERSION = 0.01; + +sub _info { + { + 'info_version' => '0.01', + 'module_version' => $VERSION, + 'supported_types' => [ 'CC' ], + 'supported_actions' => { 'CC' => [ + 'Normal Authorization', + 'Authorization Only', + 'Post Authorization', + 'Void', + 'Credit', + ], + }, + 'token_support' => 'challenge/response', + #need to figure out how to pass through for gateways that do... an option? + #'CC_void_requires_card' => 1, + }; +} + +sub set_defaults { + my $self = shift; + my %opts = @_; + + $self->server('gw.cardfortress.com') unless $self->server; + + $self->port('443') unless $self->port; + $self->path('/bop/index.html') unless $self->path; + + $self->build_subs(qw( order_number avs_code cvv2_response + response_page response_code response_headers + card_token + )); +} + +sub submit { + my $self = shift; + + $self->server('test.cardfortress.com'); + + my ($page,$server_response,%headers) = $self->https_post($self->content); + + die $server_response unless $server_response =~ /^200/; + + my %response = {}; + #this encoding good enough? wfm... if something's easier for other + #languages they can always use a different URL + foreach my $line ( grep /^\w+=/, split(/\n/, $page) ) { + $line =~ /^(\w+)=(.*)$/ or next; + $response{$1} = $2; + } + + foreach (qw( is_success error_message failure_status + authorization order_number + fraud_score fraud_transaction_id + result_code avs_code cvv2_response + card_token + )) { + $self->$_($response{$_}); + } + + #map these to gateway_response_code, etc? + # response_code() + # response_headers() + # response_page() + +} + +1; + +__END__ + +=head1 NAME + +Business::OnlinePayment::CardFortress - CardFortress backend for Business::OnlinePayment + +=head1 SYNOPSIS + + use Business::OnlinePayment; + + my $tx = new Business::OnlinePayment( 'CardFortress', + 'gateway' => 'ProcessingGateway', + 'gateway_login' => 'gwlogin', + 'gateway_password' => 'gwpass', + #private_key not necessary + ); + + $tx->content( + type => 'VISA', + login => 'cardfortress_login', + password => 'cardfortress_pass', + action => 'Normal Authorization', + description => 'Business::OnlinePayment test', + amount => '49.95', + customer_id => 'tfb', + name => 'Tofu Beast', + address => '123 Anystreet', + city => 'Anywhere', + state => 'UT', + zip => '84058', + card_number => '4007000000027', + expiration => '09/02', + cvv2 => '1234', #optional (not stored) + ); + $tx->submit(); + + if($tx->is_success()) { + print "Card processed successfully: ".$tx->authorization."\n"; + $token = $tx->card_token; + print "Card token is: $token\n"; + } else { + print "Card was rejected: ".$tx->error_message."\n"; + } + + # ... time slips by ... + + my $rx = new Business::OnlinePayment( 'CardFortress', + 'gateway' => 'ProcessingGateway', + 'gateway_login' => 'gwlogin', + 'gateway_password' => 'gwpass', + 'private_key' => '/path/to/keyfile', + ); + + $rx->content( + type => 'VISA', + login => 'cardfortress_login', + password => 'cardfortress_pass', + action => 'Normal Authorization', + description => 'Business::OnlinePayment test', + amount => '49.95', + card_token => $card_token + cvv2 => '1234', #optional, typically not necessary w/followup tx + ); + $rx->submit(); + +=head1 DESCRIPTION + +This is a Business::OnlinePayment backend module for the gateway-independent +CardFortress storage service (http://cardfortress.com/). + +=head1 SUPPORTED TRANSACTION TYPES + +=head2 CC, Visa, MasterCard, American Express, Discover + +Content required: type, login, action, amount, card_number, expiration. + +=head1 METHODS AND FUNCTIONS + +See L for the complete list. The following methods either override the methods in L or provide additional functions. + +=head2 card_token + +Returns the card token for any transaction. The card token can be used in +a subsequent transaction as a replacement for the card number and expiration +(as well as customer/AVS data). + +=head2 result_code + +Returns the response error code. + +=head2 error_message + +Returns the response error description text. + +=head2 server_response + +Returns the complete response from the server. + +=head1 AUTHOR + +Ivan Kohler C<< >> + +=head1 COPYRIGHT & LICENSE + +Copyright 2008-2010 Freeside Internet Services, Inc. (http://freeside.biz/) +All rights reserved. + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=cut + +1; diff --git a/t/00-load.t b/t/00-load.t new file mode 100644 index 0000000..1ae7f89 --- /dev/null +++ b/t/00-load.t @@ -0,0 +1,10 @@ +#!perl -T + +use Test::More tests => 1; + +BEGIN { + use_ok( 'Business::OnlinePayment::CardFortress' ) || print "Bail out! +"; +} + +diag( "Testing Business::OnlinePayment::CardFortress $Business::OnlinePayment::CardFortress::VERSION, Perl $], $^X" ); diff --git a/t/boilerplate.t b/t/boilerplate.t new file mode 100644 index 0000000..0605fd0 --- /dev/null +++ b/t/boilerplate.t @@ -0,0 +1,55 @@ +#!perl -T + +use strict; +use warnings; +use Test::More tests => 3; + +sub not_in_file_ok { + my ($filename, %regex) = @_; + open( my $fh, '<', $filename ) + or die "couldn't open $filename for reading: $!"; + + my %violated; + + while (my $line = <$fh>) { + while (my ($desc, $regex) = each %regex) { + if ($line =~ $regex) { + push @{$violated{$desc}||=[]}, $.; + } + } + } + + if (%violated) { + fail("$filename contains boilerplate text"); + diag "$_ appears on lines @{$violated{$_}}" for keys %violated; + } else { + pass("$filename contains no boilerplate text"); + } +} + +sub module_boilerplate_ok { + my ($module) = @_; + not_in_file_ok($module => + 'the great new $MODULENAME' => qr/ - The great new /, + 'boilerplate description' => qr/Quick summary of what the module/, + 'stub function definition' => qr/function[12]/, + ); +} + +TODO: { + local $TODO = "Need to replace the boilerplate text"; + + not_in_file_ok(README => + "The README is used..." => qr/The README is used/, + "'version information here'" => qr/to provide version information/, + ); + + not_in_file_ok(Changes => + "placeholder date/time" => qr(Date/time) + ); + + module_boilerplate_ok('lib/Business/OnlinePayment/CardFortress.pm'); + + +} + diff --git a/t/manifest.t b/t/manifest.t new file mode 100644 index 0000000..45eb83f --- /dev/null +++ b/t/manifest.t @@ -0,0 +1,13 @@ +#!perl -T + +use strict; +use warnings; +use Test::More; + +unless ( $ENV{RELEASE_TESTING} ) { + plan( skip_all => "Author tests not required for installation" ); +} + +eval "use Test::CheckManifest 0.9"; +plan skip_all => "Test::CheckManifest 0.9 required" if $@; +ok_manifest(); diff --git a/t/pod-coverage.t b/t/pod-coverage.t new file mode 100644 index 0000000..fc40a57 --- /dev/null +++ b/t/pod-coverage.t @@ -0,0 +1,18 @@ +use strict; +use warnings; +use Test::More; + +# Ensure a recent version of Test::Pod::Coverage +my $min_tpc = 1.08; +eval "use Test::Pod::Coverage $min_tpc"; +plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage" + if $@; + +# Test::Pod::Coverage doesn't require a minimum Pod::Coverage version, +# but older versions don't recognize some common documentation styles +my $min_pc = 0.18; +eval "use Pod::Coverage $min_pc"; +plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage" + if $@; + +all_pod_coverage_ok(); diff --git a/t/pod.t b/t/pod.t new file mode 100644 index 0000000..ee8b18a --- /dev/null +++ b/t/pod.t @@ -0,0 +1,12 @@ +#!perl -T + +use strict; +use warnings; +use Test::More; + +# Ensure a recent version of Test::Pod +my $min_tp = 1.22; +eval "use Test::Pod $min_tp"; +plan skip_all => "Test::Pod $min_tp required for testing POD" if $@; + +all_pod_files_ok(); -- 2.11.0