X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=IPPay.pm;h=496048364f5458e31f53a3faf02f0462e625a6fc;hb=a5b53c10d1014b408075e2fe1cc31ea4042ecafc;hp=bc974463cedad375e1af7109a0b92530429420b1;hpb=5c008be3b9bb7eb5c7423cf174399c57a19ee707;p=Business-OnlinePayment-IPPay.git diff --git a/IPPay.pm b/IPPay.pm index bc97446..4960483 100644 --- a/IPPay.pm +++ b/IPPay.pm @@ -11,7 +11,7 @@ use Business::OnlinePayment::HTTPS; use vars qw($VERSION $DEBUG @ISA $me); @ISA = qw(Business::OnlinePayment::HTTPS); -$VERSION = '0.05_01'; +$VERSION = '0.08'; $VERSION = eval $VERSION; # modperlstyle: convert the string into a number $DEBUG = 0; @@ -28,6 +28,7 @@ sub _info { 'Post Authorization', 'Void', 'Credit', + 'Reverse Authorization', ], 'ECHECK' => [ 'Normal Authorization', @@ -36,6 +37,7 @@ sub _info { ], }, 'CC_void_requires_card' => 1, + 'ECHECK_void_requires_account' => 1, }; } @@ -44,9 +46,9 @@ sub set_defaults { my %opts = @_; # standard B::OP methods/data - $self->server('gateway17.jetpay.com') unless $self->server; + $self->server('gtwy.ippay.com') unless $self->server; $self->port('443') unless $self->port; - $self->path('/jetpay') unless $self->path; + $self->path('/ippay') unless $self->path; $self->build_subs(qw( order_number avs_code cvv2_response response_page response_code response_headers @@ -88,6 +90,7 @@ sub map_fields { ( 'normal authorization' => 'SALE', 'authorization only' => 'AUTHONLY', 'post authorization' => 'CAPT', + 'reverse authorization' => 'REVERSEAUTH', 'void' => 'VOID', 'credit' => 'CREDIT', ); @@ -96,20 +99,25 @@ sub map_fields { 'void' => 'VOIDACH', 'credit' => 'REVERSAL', ); + if ($self->transaction_type eq 'CC') { $content{'TransactionType'} = $actions{$action} || $action; - }elsif ($self->transaction_type eq 'ECHECK') { - $content{'TransactionType'} = $check_actions{$action} || $action; - } + } elsif ($self->transaction_type eq 'ECHECK') { + $content{'TransactionType'} = $check_actions{$action} || $action; - # ACCOUNT TYPE MAP - my %account_types = ('personal checking' => 'Checking', - 'personal savings' => 'Savings', - 'business checking' => 'BusinessCk', - ); - $content{'account_type'} = $account_types{lc($content{'account_type'})} - || $content{'account_type'}; + # ACCOUNT TYPE MAP + my %account_types = ('personal checking' => 'CHECKING', + 'personal savings' => 'SAVINGS', + 'business checking' => 'CHECKING', + 'business savings' => 'SAVINGS', + #not technically B:OP valid i guess? + 'checking' => 'CHECKING', + 'savings' => 'SAVINGS', + ); + $content{'account_type'} = $account_types{lc($content{'account_type'})} + || $content{'account_type'}; + } $content{Origin} = 'RECURRING' if ($content{recurring_billing} &&$content{recurring_billing} eq 'YES' ); @@ -188,6 +196,8 @@ sub submit { }elsif ( $action eq 'post authorization' && $type eq 'CC') { push @required_fields, qw( order_number ); + }elsif ( $action eq 'reverse authorization' && $type eq 'CC') { + push @required_fields, qw( order_number card_number expiration amount ); }elsif ( $action eq 'void') { push @required_fields, qw( order_number amount ); @@ -208,14 +218,19 @@ sub submit { foreach ( keys ( %{($self->{_defaults})} ) ) { $content{$_} = $self->{_defaults}->{$_} unless exists($content{$_}); } + if ($self->test_transaction()) { + $content{'login'} = 'TESTTERMINAL'; + } $self->content(%content); $self->required_fields(@required_fields); - if ($self->test_transaction()) { - $self->server('test1.jetpay.com'); - $self->port('443'); - $self->path('/jetpay'); + #quick validation because ippay dumps an error indecipherable to the end user + if (grep { /^routing_code$/ } @required_fields) { + unless( $content{routing_code} =~ /^\d{9}$/ ) { + $self->_error_response('Invalid routing code'); + return; + } } my $transaction_id = $content{'order_number'}; @@ -270,6 +285,8 @@ sub submit { tie my %ach, 'Tie::IxHash', $self->revmap_fields( + #wtf, this is a "Type"" attribute of the ACH element, + # not a child element like the others #AccountType => 'account_type', AccountNumber => 'account_number', ABA => 'routing_code', @@ -300,6 +317,7 @@ sub submit { Phone => 'phone', ); } + delete $shippingaddr{Country} unless $shippingaddr{Country}; tie my %shippinginfo, 'Tie::IxHash', $self->revmap_fields( @@ -353,6 +371,7 @@ sub submit { IndustryInfo => \%industryinfo, ShippingInfo => \%shippinginfo, ); + delete $req{BillingCountry} unless $req{BillingCountry}; my $post_data; my $writer = new XML::Writer( OUTPUT => \$post_data, @@ -380,7 +399,7 @@ sub submit { if ( exists($response->{ActionCode}) && !exists($response->{ErrMsg})) { $self->error_message($response->{ResponseText}); }else{ - $self->error_message($response->{Errmsg}); + $self->error_message($response->{ErrMsg}); } # }else{ # $self->error_message("Server Failed"); @@ -407,9 +426,29 @@ sub submit { } +sub _error_response { + my ($self, $error_message) = (shift, shift); + $self->result_code(''); + $self->order_number(''); + $self->authorization(''); + $self->cvv2_response(''); + $self->avs_code(''); + $self->is_success( 0); + $self->error_message($error_message); +} + sub _xmlwrite { my ($self, $writer, $item, $value) = @_; - $writer->startTag($item); + + my %att = (); + if ( $item eq 'ACH' ) { + $att{'Type'} = $self->{_content}->{'account_type'} + if $self->{_content}->{'account_type'}; #necessary so we don't pass empty? + $att{'SEC'} = 'PPD'; + } + + $writer->startTag($item, %att); + if ( ref( $value ) eq 'HASH' ) { foreach ( keys ( %$value ) ) { $self->_xmlwrite($writer, $_, $value->{$_}); @@ -417,6 +456,7 @@ sub _xmlwrite { }else{ $writer->characters($value); } + $writer->endTag($item); } @@ -499,6 +539,7 @@ The following actions are valid normal authorization authorization only + reverse authorization post authorization credit void @@ -566,14 +607,20 @@ from content(%content): =head1 COMPATIBILITY +Version 0.07 changes the server name and path for IPPay's late 2012 update. + Business::OnlinePayment::IPPay uses IPPay XML Product Specifications version 1.1.2. See http://www.ippay.com/ for more information. -=head1 AUTHOR +=head1 AUTHORS + +Original author: Jeff Finucane + +Current maintainer: Ivan Kohler -Jeff Finucane, ippay@weasellips.com +Reverse Authorization patch from dougforpres =head1 SEE ALSO