diff --git a/lib/active_merchant/billing/gateways/adyen.rb b/lib/active_merchant/billing/gateways/adyen.rb index 648cb4299a8..cca8e564328 100644 --- a/lib/active_merchant/billing/gateways/adyen.rb +++ b/lib/active_merchant/billing/gateways/adyen.rb @@ -63,7 +63,7 @@ def authorize(money, payment, options = {}) add_3ds(post, options) add_3ds_authenticated_data(post, options) add_splits(post, options) - add_recurring_contract(post, options) + add_recurring_contract(post, options, payment) add_network_transaction_reference(post, options) add_application_info(post, options) add_level_2_data(post, options) @@ -622,20 +622,33 @@ def add_mpi_data_for_network_tokenization_card(post, payment, options) post[:mpiData] = {} post[:mpiData][:authenticationResponse] = 'Y' - post[:mpiData][:cavv] = payment.payment_cryptogram + if NETWORK_TOKENIZATION_CARD_SOURCE[payment.source.to_s].nil? && options[:switch_cryptogram_mapping_nt] + post[:mpiData][:tokenAuthenticationVerificationValue] = payment.payment_cryptogram + else + post[:mpiData][:cavv] = payment.payment_cryptogram + end post[:mpiData][:directoryResponse] = 'Y' post[:mpiData][:eci] = payment.eci || '07' end - def add_recurring_contract(post, options = {}) - return unless options[:recurring_contract_type] + def add_recurring_contract(post, options = {}, payment = nil) + return unless options[:recurring_contract_type] || (payment.is_a?(NetworkTokenizationCreditCard) && options[:switch_cryptogram_mapping_nt]) - post[:recurring] = {} - post[:recurring][:contract] = options[:recurring_contract_type] - post[:recurring][:recurringDetailName] = options[:recurring_detail_name] if options[:recurring_detail_name] - post[:recurring][:recurringExpiry] = options[:recurring_expiry] if options[:recurring_expiry] - post[:recurring][:recurringFrequency] = options[:recurring_frequency] if options[:recurring_frequency] - post[:recurring][:tokenService] = options[:token_service] if options[:token_service] + post[:recurring] ||= {} + + if options[:recurring_contract_type] + post[:recurring][:contract] ||= options[:recurring_contract_type] + post[:recurring][:recurringDetailName] = options[:recurring_detail_name] + post[:recurring][:recurringExpiry] = options[:recurring_expiry] + post[:recurring][:recurringFrequency] = options[:recurring_frequency] + post[:recurring][:tokenService] ||= options[:token_service] + elsif payment.is_a?(NetworkTokenizationCreditCard) && options[:switch_cryptogram_mapping_nt] + post[:recurring][:contract] = 'EXTERNAL' + post[:recurring][:tokenService] = case payment.brand + when 'visa' then 'VISATOKENSERVICE' + else 'MCTOKENSERVICE' + end + end end def add_application_info(post, options) diff --git a/test/remote/gateways/remote_adyen_test.rb b/test/remote/gateways/remote_adyen_test.rb index 70fea7c9c1a..777636f7d91 100644 --- a/test/remote/gateways/remote_adyen_test.rb +++ b/test/remote/gateways/remote_adyen_test.rb @@ -287,7 +287,7 @@ def test_successful_authorize_with_3ds2_browser_client_data end def test_successful_authorize_with_network_token - response = @gateway.authorize(@amount, @nt_credit_card, @options) + response = @gateway.authorize(@amount, @nt_credit_card, @options.merge(switch_cryptogram_mapping_nt: true)) assert_success response assert_equal 'Authorised', response.message end @@ -562,7 +562,13 @@ def test_successful_purchase_with_shipping_default_country_code end def test_successful_purchase_with_apple_pay - response = @gateway.purchase(@amount, @apple_pay_card, @options) + response = @gateway.purchase(@amount, @apple_pay_card, @options.merge(switch_cryptogram_mapping_nt: true)) + assert_success response + assert_equal '[capture-received]', response.message + end + + def test_successful_purchase_with_apple_pay_with_ld_flag_false + response = @gateway.purchase(@amount, @apple_pay_card, @options.merge(switch_cryptogram_mapping_nt: false)) assert_success response assert_equal '[capture-received]', response.message end @@ -580,13 +586,13 @@ def test_succesful_purchase_with_brand_override_with_execute_threed_false end def test_successful_purchase_with_google_pay - response = @gateway.purchase(@amount, @google_pay_card, @options) + response = @gateway.purchase(@amount, @google_pay_card, @options.merge(switch_cryptogram_mapping_nt: true)) assert_success response assert_equal '[capture-received]', response.message end def test_successful_purchase_with_google_pay_and_truncate_order_id - response = @gateway.purchase(@amount, @google_pay_card, @options.merge(order_id: @long_order_id)) + response = @gateway.purchase(@amount, @google_pay_card, @options.merge(order_id: @long_order_id, switch_cryptogram_mapping_nt: true)) assert_success response assert_equal '[capture-received]', response.message end @@ -610,7 +616,7 @@ def test_successful_purchase_with_unionpay_card end def test_successful_purchase_with_network_token - response = @gateway.purchase(@amount, @nt_credit_card, @options) + response = @gateway.purchase(@amount, @nt_credit_card, @options.merge(switch_cryptogram_mapping_nt: true)) assert_success response assert_equal '[capture-received]', response.message end @@ -1426,7 +1432,8 @@ def test_purchase_with_skip_mpi_data first_options = options.merge( order_id: generate_unique_id, shopper_interaction: 'Ecommerce', - recurring_processing_model: 'Subscription' + recurring_processing_model: 'Subscription', + switch_cryptogram_mapping_nt: true ) assert auth = @gateway.authorize(@amount, @apple_pay_card, first_options) assert_success auth @@ -1441,7 +1448,8 @@ def test_purchase_with_skip_mpi_data skip_mpi_data: 'Y', shopper_interaction: 'ContAuth', recurring_processing_model: 'Subscription', - network_transaction_id: auth.network_transaction_id + network_transaction_id: auth.network_transaction_id, + switch_cryptogram_mapping_nt: true ) assert purchase = @gateway.purchase(@amount, @apple_pay_card, used_options) diff --git a/test/unit/gateways/adyen_test.rb b/test/unit/gateways/adyen_test.rb index e673cc9251b..71e79d9a9d5 100644 --- a/test/unit/gateways/adyen_test.rb +++ b/test/unit/gateways/adyen_test.rb @@ -1222,7 +1222,7 @@ def test_authorize_with_network_tokenization_credit_card_no_name def test_authorize_with_network_tokenization_credit_card response = stub_comms do - @gateway.authorize(@amount, @apple_pay_card, @options) + @gateway.authorize(@amount, @apple_pay_card, @options.merge(switch_cryptogram_mapping_nt: false)) end.check_request do |_endpoint, data, _headers| parsed = JSON.parse(data) assert_equal 'YwAAAAAABaYcCMX/OhNRQAAAAAA=', parsed['mpiData']['cavv'] @@ -1232,6 +1232,34 @@ def test_authorize_with_network_tokenization_credit_card assert_success response end + def test_authorize_with_network_tokenization_credit_card_using_ld_option + response = stub_comms do + @gateway.authorize(@amount, @apple_pay_card, @options.merge(switch_cryptogram_mapping_nt: true)) + end.check_request do |_endpoint, data, _headers| + parsed = JSON.parse(data) + assert_equal 'YwAAAAAABaYcCMX/OhNRQAAAAAA=', parsed['mpiData']['cavv'] + assert_equal '07', parsed['mpiData']['eci'] + assert_equal 'applepay', parsed['additionalData']['paymentdatasource.type'] + assert_equal 'VISATOKENSERVICE', parsed['recurring']['tokenService'] + assert_equal 'EXTERNAL', parsed['recurring']['contract'] + end.respond_with(successful_authorize_response) + assert_success response + end + + def test_authorize_with_network_tokenization_credit_card_no_apple_no_google + response = stub_comms do + @gateway.authorize(@amount, @nt_credit_card, @options.merge(switch_cryptogram_mapping_nt: true)) + end.check_request do |_endpoint, data, _headers| + parsed = JSON.parse(data) + assert_equal 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', parsed['mpiData']['tokenAuthenticationVerificationValue'] + assert_equal '07', parsed['mpiData']['eci'] + assert_nil parsed['additionalData']['paymentdatasource.type'] + assert_equal 'VISATOKENSERVICE', parsed['recurring']['tokenService'] + assert_equal 'EXTERNAL', parsed['recurring']['contract'] + end.respond_with(successful_authorize_response) + assert_success response + end + def test_authorize_and_capture_with_network_transaction_id auth = stub_comms do @gateway.authorize(@amount, @credit_card, @options)