--- /dev/null
+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.
+
--- /dev/null
+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<Business::OnlinePayment> for the complete list. The following methods either override the methods in L<Business::OnlinePayment> 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<< <ivan-bop-cardfortress at freeside.biz> >>
+
+=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;
--- /dev/null
+#!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');
+
+
+}
+