From 0aae49345c4ed31a94a19328693af3c669207bd1 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 24 Aug 2005 14:58:23 +0000 Subject: [PATCH] initial import --- Changes | 6 + MANIFEST | 6 + Makefile.PL | 22 +++ README | 13 ++ lib/Business/OnlinePayment/Capstone.pm | 280 +++++++++++++++++++++++++++++++++ t/Business-OnlinePayment-Capstone.t | 17 ++ t/bad_card.t | 35 +++++ t/bop.t | 5 + t/credit_card.t | 45 ++++++ t/crypt_bad_card.t | 35 +++++ t/crypt_credit_card.t | 49 ++++++ t/crypt_load.t | 13 ++ t/load.t | 12 ++ 13 files changed, 538 insertions(+) create mode 100644 Changes create mode 100644 MANIFEST create mode 100644 Makefile.PL create mode 100644 README create mode 100644 lib/Business/OnlinePayment/Capstone.pm create mode 100644 t/Business-OnlinePayment-Capstone.t create mode 100644 t/bad_card.t create mode 100644 t/bop.t create mode 100644 t/credit_card.t create mode 100644 t/crypt_bad_card.t create mode 100644 t/crypt_credit_card.t create mode 100644 t/crypt_load.t create mode 100644 t/load.t diff --git a/Changes b/Changes new file mode 100644 index 0000000..7ab03fe --- /dev/null +++ b/Changes @@ -0,0 +1,6 @@ +Revision history for Perl extension Business::OnlinePayment::Capstone. + +0.01 Thu Aug 18 01:43:39 2005 + - original version; created by h2xs 1.23 with options + -X -b 5.5.0 -n Business::OnlinePayment::Capstone -v 0.01 + diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..825e8f5 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,6 @@ +Changes +Makefile.PL +MANIFEST +README +t/Business-OnlinePayment-Capstone.t +lib/Business/OnlinePayment/Capstone.pm diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..b098892 --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,22 @@ +use 5.005; +use ExtUtils::MakeMaker; +# See lib/ExtUtils/MakeMaker.pm for details of how to influence +# the contents of the Makefile that is written. +WriteMakefile( + NAME => 'Business::OnlinePayment::Capstone', + VERSION_FROM => 'lib/Business/OnlinePayment/Capstone.pm', # finds $VERSION + PREREQ_PM => { # e.g., Module::Name => 1.1 + 'Business::OnlinePayment' => 0, + + # for HTTPS (maybe it should be a separate dist?) + 'URI::Escape' => 0, + 'Tie::IxHash' => 0, + + # 'Net::SSLeay' => 0, + # or 'Crypt::SSLeay' => 0, + # 'URI + }, + ($] >= 5.005 ? ## Add these new keywords supported since 5.005 + (ABSTRACT_FROM => 'lib/Business/OnlinePayment/Capstone.pm', # retrieve abstract from module + AUTHOR => 'Ivan Kohler ') : ()), +); diff --git a/README b/README new file mode 100644 index 0000000..5aaa6fc --- /dev/null +++ b/README @@ -0,0 +1,13 @@ +Copyright (c) 2004 Ivan Kohler +All rights reserved. This program is free software; you can redistribute it +and/or modify it under the same terms as Perl itself. + +This is Business::OnlinePayment::Capstone, an Business::OnlinePayment +backend module for the CapstonePay gateway . It is only +useful if you have a merchant account with Capstone: +http://www.capstonepay.com/ + +Business::OnlinePayment is a generic interface for processing payments through +online credit card processors, online check acceptance houses, etc. (If you +like buzzwords, call it an "multiplatform ecommerce-enabling middleware +solution"). diff --git a/lib/Business/OnlinePayment/Capstone.pm b/lib/Business/OnlinePayment/Capstone.pm new file mode 100644 index 0000000..ed645bb --- /dev/null +++ b/lib/Business/OnlinePayment/Capstone.pm @@ -0,0 +1,280 @@ +package Business::OnlinePayment::Capstone; + +use strict; +use Carp; +#use Tie::IxHash; +use URI::Escape; +use Business::OnlinePayment 3; +use Business::OnlinePayment::HTTPS 0.03; +use vars qw($VERSION $DEBUG @ISA); + +@ISA = qw(Business::OnlinePayment::HTTPS); +$VERSION = '0.01'; +$DEBUG = 0; + +sub set_defaults { + my $self = shift; + + $self->server('www.capstonepay.com'); + $self->port('443'); + $self->path('/cgi-bin/client/transaction.cgi'); + + $self->build_subs(qw( order_number avs_code cvv2_response )); +} + +sub submit { + my($self) = @_; + + my $action = $self->{_content}{'action'}; + if ( $self->{_content}{'action'} =~ /^\s*normal\s*authorization\s*$/i ) { + $action = 'authpostauth'; + } elsif ( $self->{_content}{'action'} =~ /^\s*authorization\s*only\s*$/i ) { + $action = 'auth'; + } elsif ( $self->{_content}{'action'} =~ /^\s*post\s*authorization\s*$/i ) { + $action = 'postauth'; + } elsif ( $self->{_content}{'action'} =~ /^\s*void\s*$/i ) { + $action = 'void'; + } elsif ( $self->{_content}{'action'} =~ /^\s*credit\s*$/i ) { + $action = 'return'; + } + + #$self->map_fields(); + $self->revmap_fields( + merchantid =>'login', + account_password => 'password', + action => \$action, + amount => 'amount', + name => 'name', + address1 => 'address', + #address2 + city => 'city', + state => 'state', + postal => 'zip', + country => 'country', + currency => \'USD', #XXX fix me + email => 'email', + ipaddress => 'customer_ip', + card_num => 'card_number', + #card_exp => 'expiration', #strip / + card_cvv => 'cvv2', + #start_date => 'card_start', #strip / + issue_num => 'issue_number', + #bank_name #XXX fix to support ACH + #bank_phone #XXX fix to support ACH + orderid => 'order_number', + custom0 => 'description', + ); + + + # => 'order_type', + # => 'transaction_type', + + #authorization => + + #company => + #country => + #phone => + #fax => + + #invoice_number => + #customer_id => + #authorization => 'txn_number' + + # XXXfix check required fields! +# if ( $action =~ /^(purchase|preauth|ind_refund)$/ ) { +# +# $self->required_fields( +# qw( login password amount card_number expiration ) +# ); +# + $self->{_content}{'expiration'} =~ /^(\d+)\D+\d*(\d{2})$/ + or croak "unparsable expiration ". $self->{_content}{expiration}; + my( $month, $year ) = ( $1, $2 ); + $month = '0'. $month if $month =~ /^\d$/; + $self->{_content}{card_exp} = $month.$year; + + if ( $self->{_content}{'card_start'} ) { + $self->{_content}{'card_start'} =~ /^(\d+)\D+\d*(\d{2})$/ + or croak "unparsable expiration ". $self->{_content}{card_start}; + my( $month, $year ) = ( $1, $2 ); + $month = '0'. $month if $month =~ /^\d$/; + $self->{_content}{start_date} = $month.$year; + } + +# $self->generate_order_id; +# +# $self->{_content}{amount} = sprintf('%.2f', $self->{_content}{amount} ); +# +# } elsif ( $action eq 'completion' || $action eq 'void' ) { +# +# $self->required_fields( qw( login password order_number authorization ) ); +# +# } elsif ( $action eq 'refund' ) { +# +# $self->required_fields( +# qw( login password order_number authorization ) +# ); +# +# } + + #warn $self->get_fields('zip'); + #warn $self->get_fields('postal'); + + $self->{'_content'}{country} ||= 'US'; + + #tie my %post_data, 'Tie::IxHash', $self->get_fields(qw( + my %post_data = $self->get_fields(qw( + merchantid + account_password + action + amount + name + address1 + city + state + postal + country + currency + email + ipaddress + card_num + card_exp + card_cvv + state_date + issue_num + bank_name + bank_phone + orderid + custom0 + )); + + warn join("\n", map { "$_: ". $post_data{$_} } keys %post_data ) + if $DEBUG; + + #my( $page, $response, @reply_headers) = $self->https_post( \%post_data ); + my( $page, $response, @reply_headers) = $self->https_post( %post_data ); + + #my %reply_headers = @reply_headers; + #warn join('', map { " $_ => $reply_headers{$_}\n" } keys %reply_headers ) + # if $DEBUG; + + #XXX check $response and die if not 200? + + $self->server_response($page); + + #warn "****** $page *******"; + + $page =~ s/^\n+//; + + my %result = map { + /^(\w+)=(.*)$/ or die "can't parse response: $_"; + ($1, uri_unescape($2)); + } + split(/\&/, $page); + + $self->result_code( $result{'status_code'} ); + $self->avs_code( $result{'avs_resp'} ); + $self->cvv2_response( $result{'cvv_resp'} ); + + if ( $result{'status'} eq 'good' ) { + $self->is_success(1); + $self->authorization( $result{'auth_code'} ); + $self->order_number( $result{'orderid'} ); + } elsif ( $result{'status'} =~ /^(bad|error|fraud)$/ ) { + $self->is_success(0); + $self->error_message("$1: ". $result{'status_msg'}); + } else { + die "unparsable response received from gateway". + ( $DEBUG ? ": $page" : '' ); + } + +} + +sub revmap_fields { + my($self, %map) = @_; + my %content = $self->content(); + foreach(keys %map) { +# warn "$_ = ". ( ref($map{$_}) +# ? ${ $map{$_} } +# : $content{$map{$_}} ). "\n"; + $content{$_} = ref($map{$_}) + ? ${ $map{$_} } + : $content{$map{$_}}; + } + $self->content(%content); +} + +1; + +__END__ + +=head1 NAME + +Business::OnlinePayment::Capstone - CapstonePay backend module for Business::OnlinePayment + +=head1 SYNOPSIS + + use Business::OnlinePayment; + + #### + # One step transaction, the simple case. + #### + + my $tx = new Business::OnlinePayment("Capstone"); + $tx->content( + type => 'VISA', + login => 'Merchant ID', + password => 'API password', + action => 'Normal Authorization', + description => 'Business::OnlinePayment test', + amount => '49.95', + name => 'Tofu Beast', + address => '123 Anystreet', + city => 'Anywhere', + state => 'UT', + zip => '84058', + phone => '420-867-5309', + email => 'tofu.beast@example.com', + card_number => '4005550000000019', + expiration => '08/06', + card_start => '05/04', #switch/solo + issue_number => '5678', # + cvv2 => '1234', #optional + ); + $tx->submit(); + + if($tx->is_success()) { + print "Card processed successfully: ".$tx->authorization."\n"; + } else { + print "Card was rejected: ".$tx->error_message."\n"; + } + +=head1 SUPPORTED TRANSACTION TYPES + +=head2 CC, Visa, MasterCard, American Express, Discover + +Content required: type, login, password, action, amount, card_number, expiration. + +=head1 PREREQUISITES + + URI::Escape + #Tie::IxHash + + Net::SSLeay _or_ ( Crypt::SSLeay and LWP ) + +=head1 DESCRIPTION + +For detailed information see L. + +=head1 NOTE + +=head1 AUTHOR + +Ivan Kohler + +=head1 SEE ALSO + +perl(1). L. + +=cut + diff --git a/t/Business-OnlinePayment-Capstone.t b/t/Business-OnlinePayment-Capstone.t new file mode 100644 index 0000000..0ca339a --- /dev/null +++ b/t/Business-OnlinePayment-Capstone.t @@ -0,0 +1,17 @@ +# Before `make install' is performed this script should be runnable with +# `make test'. After `make install' it should work as `perl Business-OnlinePayment-Capstone.t' + +######################### + +# change 'tests => 1' to 'tests => last_test_to_print'; + +use Test; +BEGIN { plan tests => 1 }; +use Business::OnlinePayment::Capstone; +ok(1); # If we made it this far, we're ok. + +######################### + +# Insert your test code below, the Test::More module is use()ed here so read +# its man page ( perldoc Test::More ) for help writing this test script. + diff --git a/t/bad_card.t b/t/bad_card.t new file mode 100644 index 0000000..f744c61 --- /dev/null +++ b/t/bad_card.t @@ -0,0 +1,35 @@ +BEGIN {$| = 1; print "1..1\n"; } + +eval "use Net::SSLeay;"; +if ( $@ ) { + print "ok 1 # Skipped: Net::SSLeay is not installed\n"; exit; +} + +use Business::OnlinePayment; + +my $tx = new Business::OnlinePayment("Capstone"); + +#$Business::OnlinePayment::HTTPS::DEBUG = 1; +#$Business::OnlinePayment::HTTPS::DEBUG = 1; +#$Business::OnlinePayment::Capstone::DEBUG = 1; +#$Business::OnlinePayment::Capstone::DEBUG = 1; + +$tx->content( + type => 'VISA', + login => '10217', + password => 'testing', + action => 'Normal Authorization', + amount => '32.32', + card_number => '4242424242424242', + expiration => '08/06', +); +$tx->test_transaction(1); # test, dont really charge +$tx->submit(); + +if($tx->is_success()) { + print "not ok 1\n"; +} else { + #warn $tx->server_response."\n"; + #warn $tx->error_message. "\n"; + print "ok 1\n"; +} diff --git a/t/bop.t b/t/bop.t new file mode 100644 index 0000000..64332c5 --- /dev/null +++ b/t/bop.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n"; } +END {print "not ok 1\n" unless $loaded;} +use Business::OnlinePayment; +$loaded = 1; +print "ok 1\n"; diff --git a/t/credit_card.t b/t/credit_card.t new file mode 100644 index 0000000..c70cb4e --- /dev/null +++ b/t/credit_card.t @@ -0,0 +1,45 @@ +BEGIN { $| = 1; print "1..1\n"; } + +eval "use Net::SSLeay;"; +if ( $@ ) { + print "ok 1 # Skipped: Net::SSLeay is not installed\n"; exit; +} + +use Business::OnlinePayment; + +my $tx = new Business::OnlinePayment("Capstone"); + +#$Business::OnlinePayment::HTTPS::DEBUG = 1; +#$Business::OnlinePayment::HTTPS::DEBUG = 1; +#$Business::OnlinePayment::Capstone::DEBUG = 1; +#$Business::OnlinePayment::Capstone::DEBUG = 1; + +$tx->content( + type => 'VISA', + login => '10217', + password => 'testing', + action => 'Normal Authorization', + description => 'Business::OnlinePayment::Capstone test', + amount => '32', + card_number => '4242424242424242', + expiration => '01/06', + cvv2 => '420', + name => 'Tofu Beast', + address => '123 Anystreet', + city => 'Anywhere', + state => 'UT', + zip => '84058', + country => 'US', + email => 'ivan-capstone-test@420.am', +); +$tx->test_transaction(1); # test, dont really charge +$tx->submit(); + +if($tx->is_success()) { + print "ok 1\n"; +} else { + #warn $tx->server_response."\n"; + warn $tx->error_message. "\n"; + print "not ok 1\n"; +} + diff --git a/t/crypt_bad_card.t b/t/crypt_bad_card.t new file mode 100644 index 0000000..cc36356 --- /dev/null +++ b/t/crypt_bad_card.t @@ -0,0 +1,35 @@ +BEGIN { + $| = 1; print "1..1\n"; + $Business::OnlinePayment::HTTPS::skip_NetSSLeay=1; + $Business::OnlinePayment::HTTPS::skip_NetSSLeay=1; +} + +eval "use Crypt::SSLeay;"; +if ( $@ ) { + print "ok 1 # Skipped: Crypt::SSLeay is not installed\n"; exit; +} + +use Business::OnlinePayment; + +my $tx = new Business::OnlinePayment("Capstone"); + +$tx->content( + type => 'VISA', + login => '10217', + password => 'testing', + action => 'Normal Authorization', + amount => '32.32', + card_number => '4242424242424242', + expiration => '08/06', +); +$tx->test_transaction(1); # test, dont really charge +$tx->submit(); + +if($tx->is_success()) { + print "not ok 1\n"; +} else { + #warn $tx->server_response."\n"; + #warn $tx->error_message. "\n"; + print "ok 1\n"; +} + diff --git a/t/crypt_credit_card.t b/t/crypt_credit_card.t new file mode 100644 index 0000000..153a0be --- /dev/null +++ b/t/crypt_credit_card.t @@ -0,0 +1,49 @@ +BEGIN { + $| = 1; print "1..1\n"; + $Business::OnlinePayment::HTTPS::skip_NetSSLeay=1; + $Business::OnlinePayment::HTTPS::skip_NetSSLeay=1; +} + +eval "use Crypt::SSLeay;"; +if ( $@ ) { + print "ok 1 # Skipped: Crypt::SSLeay is not installed\n"; exit; +} + +use Business::OnlinePayment; + +my $tx = new Business::OnlinePayment("Capstone"); + +#$Business::OnlinePayment::HTTPS::DEBUG = 1; +#$Business::OnlinePayment::HTTPS::DEBUG = 1; +#$Business::OnlinePayment::Capstone::DEBUG = 1; +#$Business::OnlinePayment::Capstone::DEBUG = 1; + +$tx->content( + type => 'VISA', + login => '10217', + password => 'testing', + action => 'Normal Authorization', + description => 'Business::OnlinePayment::Capstone test', + amount => '54.01', + card_number => '4111111111111111', + expiration => '08/06', + cvv2 => '420', + name => 'Tofu Beast', + address => '123 Anystreet', + city => 'Anywhere', + state => 'UT', + zip => '84058', + country => 'US', + email => 'ivan-capstone-test@420.am', +); +$tx->test_transaction(1); # test, dont really charge +$tx->submit(); + +if($tx->is_success()) { + print "ok 1\n"; +} else { + #warn $tx->server_response."\n"; + warn $tx->error_message. "\n"; + print "not ok 1\n"; +} + diff --git a/t/crypt_load.t b/t/crypt_load.t new file mode 100644 index 0000000..c82905a --- /dev/null +++ b/t/crypt_load.t @@ -0,0 +1,13 @@ +BEGIN { + $| = 1; print "1..1\n"; + eval "use Crypt::SSLeay;"; + if ( $@ ) { + print "ok 1 # Skipped: Crypt::SSLeay is not installed\n"; exit; + } + $Business::OnlinePayment::HTTPS::skip_NetSSLeay=1; + $Business::OnlinePayment::HTTPS::skip_NetSSLeay=1; +} +END {print "not ok 1\n" unless $loaded;} +use Business::OnlinePayment::Capstone; +$loaded = 1; +print "ok 1\n"; diff --git a/t/load.t b/t/load.t new file mode 100644 index 0000000..7ccee3d --- /dev/null +++ b/t/load.t @@ -0,0 +1,12 @@ +BEGIN { + $| = 1; print "1..1\n"; + eval "use Net::SSLeay;"; + if ( $@ ) { + print "ok 1 # Skipped: Net::SSLeay is not installed\n"; exit; + } + +} +END {print "not ok 1\n" unless $loaded;} +use Business::OnlinePayment::Capstone; +$loaded = 1; +print "ok 1\n"; -- 2.11.0