X-Git-Url: http://git.freeside.biz/gitweb/?p=Business-OnlinePayment-Bambora.git;a=blobdiff_plain;f=lib%2FBusiness%2FOnlinePayment%2FBambora.pm;fp=lib%2FBusiness%2FOnlinePayment%2FBambora.pm;h=ea1a698184bff26ea87288345084f7ead07868a4;hp=f0c7916aefbd27d739e6f521a5d342b2b99d1e64;hb=ef8b468214d2917b90f0537130f14c217ea71224;hpb=24c86c6b9136ad878a118d57fc9b876eee3672f8 diff --git a/lib/Business/OnlinePayment/Bambora.pm b/lib/Business/OnlinePayment/Bambora.pm index f0c7916..ea1a698 100755 --- a/lib/Business/OnlinePayment/Bambora.pm +++ b/lib/Business/OnlinePayment/Bambora.pm @@ -79,9 +79,10 @@ sub submit { my $method = $action_dispatch_table{$action}; - $self->submit_action_unsupported() - unless $method - && $self->can($method); + unless ( $method && $self->can($method) ) { + warn $self->error_message( "Action is unsupported ($action)" ); + return $self->is_success(0); + } $self->$method(@_); } @@ -116,33 +117,49 @@ sub submit_normal_authorization { my %post = ( order_number => $self->truncate( $content->{invoice_number}, 30 ), amount => $content->{amount}, - billing => $self->jhref_billing_address, ); - # Credit Card - if ( $content->{card_number} ) { + if ( + $content->{card_token} + || ( $content->{card_number} && $content->{card_number} =~ /^99\d{14}$/ ) + ) { + # Process payment against a stored Payment Profile, whose + # customer_code is used as the card_token + + my $card_token = $content->{card_token} || $content->{card_number}; + + unless ( $card_token =~ /^99\d{14}$/ ) { + $self->error_message( + "Invalid card_token($card_token): Expected 16-digit " + . " beginning with 99" + ); + return $self->is_success(0); + } + + $post{payment_method} = 'payment_profile'; + + $post{payment_profile} = { + customer_code => $card_token, + card_id => 1, + }; + + } elsif ( $content->{card_number} ) { + $post{payment_method} = 'card'; # Add card payment details to %post $post{card} = $self->jhref_card; return if $self->error_message; + # Add billing address to card + $post{billing} = $self->jhref_billing_address; + # Designate recurring payment label $post{card}->{recurring_payment} = $content->{recurring_payment} ? 1 : 0; # Direct API to issue a complete auth, instead of pre-auth $post{card}->{complete} = 1; - # $post{card} = { - # number => $self->truncate( $content->{card_number}, 20 ), - # name => $self->truncate( $content->{owner}, 64 ), - # expiry_month => sprintf( '%02d', $content->{expiry_month} ), - # expiry_year => sprintf( '%02d', $content->{expiry_year} ), - # cvd => $content->{cvv2}, - # recurring_payment => $content->{recurring_payment} ? 1 : 0, - # complete => 1, - # }; - } else { croak 'unknown/unsupported payment method!'; } @@ -156,7 +173,13 @@ sub submit_normal_authorization { } elsif ( $action eq 'authorization only' ) { # Perform pre-authorization $self->path('/v1/payments'); - $post{card}->{complete} = 0; + + # Set the 'complete' flag to false, directing API to perform pre-auth + if ( ref $post{payment_profile} ) { + $post{payment_profile}->{complete} = 0; + } elsif ( ref $post{card} ) { + $post{card}->{complete} = 0; + } } elsif ( $action eq 'post authorization' ) { # Complete a pre-authorization @@ -279,27 +302,33 @@ sub submit_void { ); my $post_body = encode_json( \%post ); + $self->path( sprintf '/v1/payments/%s/returns', $content->{order_number} ); if ( $DEBUG ) { warn Dumper({ + path => $self->path, post => \%post, post_body => $post_body, }); } - $self->path( sprintf '/v1/payments/%s/returns', $content->{order_number} ); my $response = $self->submit_api_request( $post_body ); + return if $self->error_message; + + $self->is_success(1); + + $response; } =head2 submit_tokenize Bambora tokenization is based on the Payment Profile feature of their API. -The token created by this method represnets the Bambora customer_code for the +The token created by this method represents the Bambora customer_code for the Payment Profile. The token resembles a credit card number. It is 16 digits long, beginning with 99. No valid card number can begin with the digits 99. -This method creates the payment profile, then replaces the customer_code -generated by Bambora with the card number resembling token. +This method creates the payment profile and reports the customer_code +as the card_token =cut @@ -420,8 +449,9 @@ sub submit_api_request { } $self->response_decoded( $response ); - # Response returned an error if ( $response->{code} && $response->{code} != 1 ) { + # Response returned an error + $self->is_success( 0 ); $self->result_code( $response->{code} ); @@ -438,16 +468,6 @@ sub submit_api_request { return $response; } -=head2 submit_action_unsupported - -Croak with the error message Action $action unsupported - -=cut - -sub submit_action_unsupported { - croak sprintf 'Action %s unsupported', shift->{_content}{action} -} - =head2 authorization_header Bambora REST requests authenticate via a HTTP header of the format: @@ -485,9 +505,9 @@ representing the RequestBillingAddress for the API sub jhref_billing_address { my $self = shift; - $self->set_province; + $self->parse_province; $self->set_country; - $self->set_phone_number; + $self->parse_phone_number; my $content = $self->{_content}; @@ -636,28 +656,7 @@ sub set_expiration { ); } -=head2 set_payment_method - -Set payment_method value to one of the following strings - - card - token - payment_profile - cash - cheque - interac - apple_pay - android_pay - -=cut - -sub set_payment_method { - # todo - determine correct payment method - warn "set_payment_method() STUB FUNCTION ALWAYS RETURNS card!\n"; - shift->{_content}->{payment_method} = 'card'; -} - -=head2 set_phone_number +=head2 parse_phone_number Set value for field phone_number, from value in field phone @@ -666,7 +665,7 @@ characters =cut -sub set_phone_number { +sub parse_phone_number { my $self = shift; my $content = $self->{_content}; @@ -677,7 +676,7 @@ sub set_phone_number { $content->{phone_number} = $phone; } -=head2 set_province +=head2 parse_province Set value for field province, from value in field state @@ -687,7 +686,7 @@ formatted to upper case, and truncated to 2 characters. =cut -sub set_province { +sub parse_province { my $self = shift; my $content = $self->{_content}; my $country = uc $content->{country};