From 775e7c0cd1eea41d5f7d5fa980db865e44162a80 Mon Sep 17 00:00:00 2001 From: Mitch Jackson Date: Tue, 16 Apr 2019 20:19:10 -0400 Subject: [PATCH] Pre-auth and voids --- lib/Business/OnlinePayment/Bambora.pm | 46 +++++++---- ...ayments-card-pre-authorization-complete-void.t} | 90 +++++++++++++++++----- 2 files changed, 99 insertions(+), 37 deletions(-) rename t/{022-payments-card-pre-authorization.t => 022-payments-card-pre-authorization-complete-void.t} (60%) mode change 100644 => 100755 diff --git a/lib/Business/OnlinePayment/Bambora.pm b/lib/Business/OnlinePayment/Bambora.pm index c721838..c92ff09 100755 --- a/lib/Business/OnlinePayment/Bambora.pm +++ b/lib/Business/OnlinePayment/Bambora.pm @@ -13,7 +13,7 @@ use URI::Escape; use vars qw/ $VERSION $DEBUG /; $VERSION = '0.01'; -$DEBUG = 1; +$DEBUG = 0; if ( $DEBUG ) { $Data::Dumper::Sortkeys = 1; @@ -59,7 +59,7 @@ my %action_dispatch_table = ( 'authorization only' => 'submit_authorization_only', 'post authorization' => 'submit_post_authorization', 'reverse authorization' => 'submit_reverse_authorization', - 'void' => 'submit_viod', + 'void' => 'submit_void', 'credit' => 'submit_credit', 'tokenize' => 'submit_tokenize', 'recurring authorization' => 'submit_recurring_authorization', @@ -83,7 +83,7 @@ sub submit { =head2 submit_normal_authorization -Compliete a payment transaction by with an API POST to B +Complete a payment transaction by with an API POST to B See L @@ -136,6 +136,7 @@ sub submit_normal_authorization { } my $action = lc $content->{action}; + if ( $action eq 'normal authorization' ) { $self->path('/v1/payments'); } elsif ( $action eq 'authorization only' ) { @@ -151,7 +152,7 @@ sub submit_normal_authorization { unless $content->{order_number}; $self->path( - sprintf 'v1/payments/%s/completions', + sprintf '/v1/payments/%s/completions', $content->{order_number} ); @@ -172,9 +173,6 @@ sub submit_normal_authorization { }); } - - $self->path('/v1/payments'); - my $response = $self->submit_api_request( $post_body ); # Error messages already populated upon failure @@ -208,7 +206,7 @@ sub submit_authorization_only { $self->is_success && ( ref $response - && $response->{type} != 'PA' + && $response->{type} ne 'PA' ) ) { # Bambora API uses nearly identical API calls for normal @@ -241,7 +239,7 @@ sub submit_reverse_authorization { =head2 submit_void -Void a transaction +Process a return against a transaction for the given amount =cut @@ -249,7 +247,7 @@ sub submit_void { my $self = shift; my $content = $self->{_content}; - for my $f (qw/ order_number invoice_number amount/) { + for my $f (qw/ order_number amount/) { unless ( $content->{$f} ) { $self->error_message("Cannot process void - missing required content $f"); warn $self->error_message if $DEBUG; @@ -259,7 +257,7 @@ sub submit_void { } my %post = ( - order_number => $self->truncate( $content->{invoice_number}, 30 ), +# order_number => $self->truncate( $content->{invoice_number}, 30 ), amount => $content->{amount}, ); my $post_body = encode_json( \%post ); @@ -270,7 +268,7 @@ sub submit_void { post_body => $post_body, }); } - $self->path( sprintf '/v1/payments/%s/void', $content->{order_number} ); + $self->path( sprintf '/v1/payments/%s/returns', $content->{order_number} ); my $response = $self->submit_api_request( $post_body ); @@ -345,12 +343,12 @@ Croak with the error message Action $action unsupported =cut sub submit_action_unsupported { - croak sprintf 'Action %s unsupported', shift->action + croak sprintf 'Action %s unsupported', shift->{_content}{action} } =head2 authorization_header -Bambora POST requests authenticate via a HTTP header of the format: +Bambora REST requests authenticate via a HTTP header of the format: Authorization: Passcode Base64Encoded(merchant_id:passcode) Returns a hash representing the authorization header derived from @@ -411,7 +409,7 @@ Sets string to upper case. Dies unless country is a two-letter string. -In the future, could be extended to convert country names to their respective +Could be extended to convert country names to their respective country codes See: L @@ -433,7 +431,7 @@ sub set_country { =head2 set_expiration_month_year -Split standard expiration field, which may be in the format +Split B::OP expiration field, which may be in the format MM/YY or MMYY, into separate expiry_month and expiry_year fields Will die if values are not numeric @@ -445,6 +443,12 @@ sub set_expiration { my $content = $self->{_content}; my $expiration = $content->{expiration}; + unless ( $expiration ) { + $content->{expiry_month} = undef; + $content->{expiry_year} = undef; + return; + } + my ( $mm, $yy ) = ( $expiration =~ /\// ? split( /\//, $expiration ) @@ -483,6 +487,11 @@ sub set_payment_method { =head2 set_phone_number +Set value for field phone_number, from value in field phone + +Bambora API expects only digits in a phone number. Strips all non-digit +characters + =cut sub set_phone_number { @@ -498,8 +507,11 @@ sub set_phone_number { =head2 set_province +Set value for field province, from value in field state + Outside the US/Canada, API expect province set to the string "--", -otherwise to be a 2 character string +otherwise expects a 2 character string. Value for province is +formatted to upper case, and truncated to 2 characters. =cut diff --git a/t/022-payments-card-pre-authorization.t b/t/022-payments-card-pre-authorization-complete-void.t old mode 100644 new mode 100755 similarity index 60% rename from t/022-payments-card-pre-authorization.t rename to t/022-payments-card-pre-authorization-complete-void.t index acceee5..00c25f9 --- a/t/022-payments-card-pre-authorization.t +++ b/t/022-payments-card-pre-authorization-complete-void.t @@ -60,6 +60,7 @@ SKIP: { created order_number risk_score + id ); ok( $response = $tr->response_decoded, 'response_decoded' ); @@ -81,13 +82,14 @@ SKIP: { %content = ( %content, - action => 'post authorization', + action => 'Post Authorization', order_number => $tr->order_number, + amount => '8.99', # $1 Less than pre-auth ); my $tr_pa; ok( $tr_pa = Business::OnlinePayment->new('Bambora'), 'Instantiate $tr_pa' ); - ok( $tr->content( %content ), 'Set transaction content onto $tr_pa' ); + ok( $tr_pa->content( %content ), 'Set transaction content onto $tr_pa' ); { local $@; eval { $tr_pa->submit }; @@ -95,27 +97,75 @@ SKIP: { warn "Error: $@" if $@; } - my $response_pa; - + %expect = ( + amount => '8.99', + approved => '1', + message => 'Approved', + message_id => '1', + type => 'PAC', + ); + @expect = (qw/ + authorizing_merchant_id + card + created + order_number + id + /); + my $response_pa; ok( $response_pa = $tr_pa->response_decoded, 'response_decoded' ); - # for my $attr (qw/ - # message_id - # authorization - # order_number - # txn_date - # avs_code - # is_success - # /) { - # ok( - # defined $tr->$attr(), - # sprintf '%s $tr->%s() = %s', - # $name, - # $attr, - # $tr->$attr() - # ); - # } + for my $k ( keys %expect ) { + ok( + $response_pa->{$k} eq $expect{$k}, + sprintf '$tr->%s == %s', $k, $expect{$k} + ); + } + + for my $k ( @expect ) { + ok( + defined $response_pa->{$k}, + sprintf '$r->%s (%s)', + $k, $response_pa->{$k} + ); + } + + # + # Void Transaction + # + + my %content_void = ( + action => 'Void', + login => $content{login}, + password => $content{password}, + order_number => $tr_pa->order_number, + amount => '8.99', + ); + + my $tr_void; + ok( $tr_void = Business::OnlinePayment->new('Bambora'), 'Instantiate $tr_void' ); + ok( $tr_void->content( %content_void ), 'Set transaction content onto $tr_void' ); + { + local $@; + eval { $tr_void->submit }; + ok( !$@, "Submit void" ); + warn "Error: $@" if $@; + } + + %expect = ( + amount => '8.99', + approved => '1', + message => 'Approved', + message_id => '1', + type => 'R', + ); + @expect = (qw/ + authorizing_merchant_id + card + created + order_number + id + /); } -- 2.11.0