From 7d8253e2ac3dda28c8013aca209570d3e4496567 Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 17 Dec 2002 19:14:09 +0000 Subject: [PATCH] finally working --- MANIFEST | 4 +- PaymentsGateway.pm | 178 ++++++++++++++++++++++++++++++++++++++++++-------- README | 3 - {t2 => t}/bad_check.t | 13 ++-- {t2 => t}/check.t | 8 +-- 5 files changed, 163 insertions(+), 43 deletions(-) rename {t2 => t}/bad_check.t (72%) rename {t2 => t}/check.t (80%) diff --git a/MANIFEST b/MANIFEST index 1b977f8..e79145a 100644 --- a/MANIFEST +++ b/MANIFEST @@ -5,5 +5,5 @@ Makefile.PL README t/load.t t/bop.t -t2/check.t.t -t2/bad_check.t +t/check.t +t/bad_check.t diff --git a/PaymentsGateway.pm b/PaymentsGateway.pm index 9070e1d..4f86106 100644 --- a/PaymentsGateway.pm +++ b/PaymentsGateway.pm @@ -2,24 +2,75 @@ package Business::OnlinePayment::PaymentsGateway; use strict; use Carp; -use Business::OnlinePayment +use Business::OnlinePayment; use Net::SSLeay qw(sslcat); use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $DEBUG); require Exporter; -@ISA - qw( Exporter AutoLoader Business::OnlinePayment); +@ISA = qw( Exporter AutoLoader Business::OnlinePayment); @EXPORT = qw(); @EXPORT_OK = qw(); $VERSION = '0.01'; $DEBUG = 0; +my %pg_response_code = ( + 'A01' => 'Transaction approved/completed', + 'U01' => 'Merchant not allowed to access customer account', + 'U02' => 'Customer account is in the ACH Direct "known bad" list', + 'U03' => 'Merchant daily limit exceeded', + 'U04' => 'Merchant monthly limit exceeded', + 'U05' => 'AVS state/zipcode check failed', + 'U06' => 'AVS state/area code check failed', + 'U07' => 'AVS anonymous email check failed', + 'U08' => 'Account has more transactions than the merchant\'s daily velocity'. + ' limit allows for', + 'U09' => 'Account has more transactions than the merchant\'s velocity'. + ' window allows for', + 'U10' => 'Transaction has the same attributes as another transaction'. + ' within the time set by the merchant', + 'U11' => '(RECUR TRANS NOT FOUND) Transaction types 40-42 only', + 'U12' => 'Original transaction not voidable or capture-able', + 'U13' => 'Transaction to be voided or captured was not found', + 'U14' => 'void/capture and original transaction types do not agree (CC/EFT)', + 'U18' => 'Void or Capture failed', + #'U19' => 'Account ABA number if invalid', + 'U19' => 'Account ABA number is invalid', + 'U20' => 'Credit card number is invalid', + 'U21' => 'Date is malformed', + 'U22' => 'Swipe data is malformed', + 'U23' => 'Malformed expiration date', + 'U51' => 'Merchant is not "live"', + 'U52' => 'Merchant not approved for transaction type (CC or EFT)', + 'U53' => 'Transaction amount exceeds merchant\'s per transaction limit', + 'U54' => 'Merchant\'s configuration requires updating ­ call customer'. + ' support', + 'U80' => 'Transaction was declined due to preauthorization (ATM Verify)'. + ' result', + 'U84' => 'Preauthorizer not responding', + 'U85' => 'Preauthorizer error', + 'U83' => 'Transaction was declined due to authorizer declination', + 'U84' => 'Authorizer not responding', + 'U85' => 'Authorizer error', + 'U86' => 'Authorizer AVS check failed', + 'F01' => 'Required field is missing', + 'F03' => 'Name is not recognized', + 'F04' => 'Value is not allowed', + 'F05' => 'Field is repeated in message', + 'F07' => 'Fields cannot both be present', + #'E10' => 'Merchant id or password in incorrect', + 'E10' => 'Merchant id or password is incorrect', + 'E20' => 'Transaction message not received (I/O flush required?)', + 'E90' => 'Originating IP not on merchant\'s approved IP list', + 'E99' => 'An unspecified error has occurred', +); + sub set_defaults { my $self = shift; - $self->server(''); - $self->port( 5050 + 1000 * $self->test_transaction() ); - #$self->build_subs(); + $self->server('paymentsgateway.net'); + $self->port( 5050 ); + $self->build_subs(qw(test_transaction)); } sub map_fields { @@ -66,10 +117,10 @@ sub submit { my $self = shift; $self->map_fields(); - my %content = $self->content(); + #my %content = $self->content(); $self->revmap_fields( - 'pg_merchant_id' => 'login', + 'PG_MERCHANT_ID' => 'login', 'pg_password' => 'password', 'pg_transaction_type' => \($self->transaction_type()), #'pg_merchant_data_1' @@ -99,6 +150,7 @@ sub submit { 'ecom_payment_check_account_type' => \'C', #checking #'ecom_payment_check_checkno' => ); + my %content = $self->content(); # name (first_name & last_name ) ? # fax @@ -107,49 +159,121 @@ sub submit { #account_number routing_code bank_name - my @fields = qw( pg_merchant_id pg_password pg_transaction_type ), - ( map { "pg_merchant_$_" } (1..9) ), - qw( pg_total_amount pg_sales_tax_amount pg_consumer_id - ecom_consumerorderid ecom_walletid - pg_billto_postal_name_company - ecom_billto_postal_name_first ecom_billto_postal_name_last - ecom_billto_postal_street_line1 - ecom_billto_postal_street_line2 - ecom_billto_postal_city ecom_billto_postal_stateprov - ecom_billto_postal_postalcode ecom_billto_postal_countrycode - ecom_billto_telecom_phone_number ecom_billto_online_email - pg_billto_ssn pg_billto_dl_number pg_billto_dl_state - ); + my @fields = ( + qw( PG_MERCHANT_ID pg_password pg_transaction_type ), + ( map { "pg_merchant_$_" } ( 1 .. 9 ) ), + qw( pg_total_amount pg_sales_tax_amount pg_consumer_id + ecom_consumerorderid ecom_walletid + pg_billto_postal_name_company + ecom_billto_postal_name_first ecom_billto_postal_name_last + ecom_billto_postal_street_line1 + ecom_billto_postal_street_line2 + ecom_billto_postal_city ecom_billto_postal_stateprov + ecom_billto_postal_postalcode ecom_billto_postal_countrycode + ecom_billto_telecom_phone_number ecom_billto_online_email + pg_billto_ssn pg_billto_dl_number pg_billto_dl_state + ) + ); if ( $content{'type'} =~ /^check$/i ) { push @fields, qw( ecom_payment_check_trn ecom_payment_check_account ecom_payment_check_account_type ); } else { - croak $content{$type}. ' not (yet) supported'; + croak $content{'type'}. ' not (yet) supported'; } - my $request = join("\n", map { "$_=$content{$_}" } @fields ). "\n"; + my $request = join("\n", map { "$_=". $content{$_} } + grep { $content{$_} ne '' } + @fields ). + "\nendofdata\n"; + + warn $request if $DEBUG; + + warn "TEST: ". $self->test_transaction(). "\n" if $DEBUG; + + $self->port( $self->port() + 1000 ) if $self->test_transaction(); + + warn "SERVER ". $self->server(). "\n" if $DEBUG; + warn "PORT ". $self->port(). "\n" if $DEBUG; my $reply = sslcat( $self->server(), $self->port(), $request ); + die "no reply from server" unless $reply; - my %response = map { /^(\w+)=(.*)$/ + warn "reply from server: $reply\n" if $DEBUG; + + my %response = map { /^(\w+)=(.*)$/ or /^(endofdata)()$/ or warn "can't parse response line: $_"; ($1, $2); } split(/\n/, $reply); if ( $response{'pg_response_type'} eq 'A' ) { $self->is_success(1); - $self->response_code($response{'pg_response_code'}); + $self->result_code($response{'pg_response_code'}); $self->authorization($response{'pg_authorization_code'}); } else { $self->is_success(0); - $self->response_code($response{'pg_response_code'}); - $self->error_message($response{'pg_response_description'}); + $self->result_code($response{'pg_response_code'}); + $self->error_message( $pg_response_code{$response{'pg_response_code'}}. + ': '. $response{'pg_response_description'} ); } } 1; -#pod goes here +__END__ + +=head1 NAME + +Business::OnlinePayment::PaymentsGateway - PaymentsGateway.Net backend for Business::OnlinePayment + +=head1 SYNOPSIS + + use Business::OnlinePayment; + + my $tx = new Business::OnlinePayment("PaymentsGateway"); + $tx->content( + type => 'CHECK', + login => 'test', + password => 'test', + action => 'Normal Authorization', + description => 'Business::OnlinePayment test', + amount => '49.95', + invoice_number => '100100', + name => 'Tofu Beast', + account_number => '12345', + routing_code => '123456789', + bank_name => 'First National Test Bank', + ); + $tx->submit(); + + if($tx->is_success()) { + print "Card processed successfully: ".$tx->authorization."\n"; + } else { + print "Card was rejected: ".$tx->error_message."\n"; + } + +=head1 DESCRIPTION + +For detailed information see L. + +=head1 NOTE + +This module only implements 'CHECK' (ACH) transactions at this time. Credit +card transactions are not (yet) supported. + +=head1 COMPATIBILITY + +This module implements the interface documented in the +"PaymentsGateway.net Integration Guide, Version 2.1, September 2002" + +=head1 AUTHOR + +Ivan Kohler + +=head1 SEE ALSO + +perl(1). L + +=cut diff --git a/README b/README index a02ad6a..212933f 100644 --- a/README +++ b/README @@ -10,9 +10,6 @@ have a merchant account with PaymentsGateway.net This module implements the interface documented in the "PaymentsGateway.net Integration Guide, Version 2.1, September 2002" -There are additional tests in t2/ that may be useful to you once you have a -login and password. - Ivan Kohler Business::OnlinePayment is a generic interface for processing payments through diff --git a/t2/bad_check.t b/t/bad_check.t similarity index 72% rename from t2/bad_check.t rename to t/bad_check.t index 3ce505e..5aa127b 100644 --- a/t2/bad_check.t +++ b/t/bad_check.t @@ -2,22 +2,21 @@ BEGIN { $| = 1; print "1..1\n"; } use Business::OnlinePayment; -# checks are broken it seems my $ctx = new Business::OnlinePayment("PaymentsGateway"); $ctx->content( type => 'CHECK', - login => 'testing', - password => 'testing', + login => '2000', + password => 'merchant4demo', action => 'Normal Authorization', amount => '49.95', invoice_number => '100100', customer_id => 'jsk', first_name => 'Tofu', last_name => 'Beast', - #account_number => '12345', - account_number => 'badaccountnumber', - #routing_code => '123456789', - routing_code => 'badroutingcode', + account_number => '12345', + #account_number => 'badaccountnumber', + routing_code => '123456789', + #routing_code => 'badroutingcode', bank_name => 'First National Test Bank', ); $ctx->test_transaction(1); # test, dont really charge diff --git a/t2/check.t b/t/check.t similarity index 80% rename from t2/check.t rename to t/check.t index e253e24..00a9540 100644 --- a/t2/check.t +++ b/t/check.t @@ -2,12 +2,11 @@ BEGIN { $| = 1; print "1..1\n"; } use Business::OnlinePayment; -# checks are broken it seems my $ctx = new Business::OnlinePayment("PaymentsGateway"); $ctx->content( type => 'CHECK', - login => 'testing', - password => 'testing', + login => '2000', + password => 'merchant4demo', action => 'Normal Authorization', amount => '49.95', invoice_number => '100100', @@ -15,7 +14,7 @@ $ctx->content( first_name => 'Tofu', last_name => 'Beast', account_number => '12345', - routing_code => '123456789', + routing_code => '321076441', bank_name => 'First National Test Bank', ); $ctx->test_transaction(1); # test, dont really charge @@ -26,5 +25,6 @@ print $ctx->is_success()."\n"; if($ctx->is_success()) { print "ok 1\n"; } else { + warn $ctx->result_code. ': '. $ctx->error_message(); print "not ok 1 (".$ctx->error_message().")\n"; } -- 2.11.0