diff --git a/lib/active_merchant/billing/gateways/rapyd.rb b/lib/active_merchant/billing/gateways/rapyd.rb index 9761ed7f642..dbc2e6ae238 100644 --- a/lib/active_merchant/billing/gateways/rapyd.rb +++ b/lib/active_merchant/billing/gateways/rapyd.rb @@ -67,7 +67,7 @@ def store(payment, options = {}) add_metadata(post, options) add_ewallet(post, options) add_payment_fields(post, options) - add_payment_urls(post, options) + add_payment_urls(post, options, 'store') add_address(post, payment, options) commit(:post, 'customers', post) end @@ -135,7 +135,7 @@ def add_payment(post, payment, options) elsif payment.is_a?(Check) add_ach(post, payment, options) else - add_token(post, payment, options) + add_tokens(post, payment, options) end end @@ -174,10 +174,13 @@ def add_ach(post, payment, options) post[:payment_method][:fields][:payment_purpose] = options[:payment_purpose] if options[:payment_purpose] end - def add_token(post, payment, options) - return unless token = payment.split('|')[1] + def add_tokens(post, payment, options) + return unless payment.respond_to?(:split) + + customer_id, card_id = payment.split('|') - post[:payment_method] = token + post[:customer] = customer_id + post[:payment_method] = card_id end def add_3ds(post, payment, options) @@ -201,20 +204,25 @@ def add_ewallet(post, options) end def add_payment_fields(post, options) - post[:payment] = {} - - post[:payment][:description] = options[:description] if options[:description] - post[:payment][:statement_descriptor] = options[:statement_descriptor] if options[:statement_descriptor] + post[:description] = options[:description] if options[:description] + post[:statement_descriptor] = options[:statement_descriptor] if options[:statement_descriptor] end - def add_payment_urls(post, options) - post[:complete_payment_url] = options[:complete_payment_url] if options[:complete_payment_url] - post[:error_payment_url] = options[:error_payment_url] if options[:error_payment_url] + def add_payment_urls(post, options, action = '') + if action == 'store' + url_location = post[:payment_method] + else + url_location = post + end + + url_location[:complete_payment_url] = options[:complete_payment_url] if options[:complete_payment_url] + url_location[:error_payment_url] = options[:error_payment_url] if options[:error_payment_url] end def add_customer_data(post, payment, options, action = '') post[:phone_number] = options.dig(:billing_address, :phone) .gsub(/\D/, '') unless options[:billing_address].nil? post[:email] = options[:email] + return if payment.is_a?(String) return add_customer_id(post, options) if options[:customer_id] if action == 'store' diff --git a/test/remote/gateways/remote_rapyd_test.rb b/test/remote/gateways/remote_rapyd_test.rb index 30009b817a4..ac4517c81cc 100644 --- a/test/remote/gateways/remote_rapyd_test.rb +++ b/test/remote/gateways/remote_rapyd_test.rb @@ -225,8 +225,9 @@ def test_successful_store_and_purchase assert store.params.dig('data', 'default_payment_method') # 3DS authorization is required on storing a payment method for future transactions - # purchase = @gateway.purchase(100, store.authorization, @options.merge(customer_id: customer_id)) - # assert_sucess purchase + # This test verifies that the card id and customer id are sent with the purchase + purchase = @gateway.purchase(100, store.authorization, @options) + assert_match(/The request tried to use a card ID, but the cardholder has not completed the 3DS verification process./, purchase.message) end def test_successful_store_and_unstore diff --git a/test/unit/gateways/rapyd_test.rb b/test/unit/gateways/rapyd_test.rb index 9fc082ee9b5..69e6f922c78 100644 --- a/test/unit/gateways/rapyd_test.rb +++ b/test/unit/gateways/rapyd_test.rb @@ -242,6 +242,45 @@ def test_successful_store_with_customer_object assert_success response end + def test_payment_urls_correctly_nested_by_operation + response = stub_comms(@gateway, :ssl_request) do + @gateway.store(@credit_card, @options) + end.check_request do |_method, _endpoint, data, _headers| + request_body = JSON.parse(data) + assert_equal @options[:complete_payment_url], request_body['payment_method']['complete_payment_url'] + assert_equal @options[:error_payment_url], request_body['payment_method']['error_payment_url'] + end.respond_with(successful_store_response) + + assert_success response + + response = stub_comms(@gateway, :ssl_request) do + @gateway.purchase(@amount, @credit_card, @options) + end.check_request do |_method, _endpoint, data, _headers| + request_body = JSON.parse(data) + assert_equal @options[:complete_payment_url], request_body['complete_payment_url'] + assert_equal @options[:error_payment_url], request_body['error_payment_url'] + end.respond_with(successful_store_response) + + assert_success response + end + + def test_purchase_with_customer_and_card_id + store = stub_comms(@gateway, :ssl_request) do + @gateway.store(@credit_card, @options) + end.respond_with(successful_store_response) + + assert customer_id = store.params.dig('data', 'id') + assert card_id = store.params.dig('data', 'default_payment_method') + + stub_comms(@gateway, :ssl_request) do + @gateway.purchase(@amount, store.authorization, @options) + end.check_request do |_method, _endpoint, data, _headers| + request_body = JSON.parse(data) + assert_equal request_body['customer'], customer_id + assert_equal request_body['payment_method'], card_id + end.respond_with(successful_purchase_response) + end + def test_three_d_secure options = { three_d_secure: {