From 69e40572070140dfdef0f69bb5fb4255b255a8f1 Mon Sep 17 00:00:00 2001 From: Luis Urrea Date: Thu, 25 Apr 2024 11:26:55 -0500 Subject: [PATCH] Checkout V2: Update Authorization to include Bearer for secret_key Start sending requests using http Auth:Bearer Spreedly reference: [ECS-3487](https://spreedly.atlassian.net/browse/ECS-3487) Unit: 66 tests, 403 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications 100% passed 2821.48 tests/s, 17228.11 assertions/s Remote: 103 tests, 254 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications 100% passed 0.63 tests/s, 1.56 assertions/s --- CHANGELOG | 1 + .../billing/gateways/checkout_v2.rb | 14 +++-- .../gateways/remote_checkout_v2_test.rb | 55 +++++++++++-------- 3 files changed, 40 insertions(+), 30 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index d31d6c941c2..ed95c59a8da 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -110,6 +110,7 @@ * CommerceHub: Update merchantInvoiceNumber & merchantTransactionId [almalee24] #5374 * VersaPay: refactor authorization from structure [gasb150] #5363 * VersaPay: Improve Message Error and Error Mapping [gasb150] #5357 +* CheckoutV2: Update Authorization from Basic to Bearer [sinourain] #5381 == Version 1.137.0 (August 2, 2024) * Unlock dependency on `rexml` to allow fixing a CVE (#5181). diff --git a/lib/active_merchant/billing/gateways/checkout_v2.rb b/lib/active_merchant/billing/gateways/checkout_v2.rb index f31a16e9257..f3937e4949c 100644 --- a/lib/active_merchant/billing/gateways/checkout_v2.rb +++ b/lib/active_merchant/billing/gateways/checkout_v2.rb @@ -585,16 +585,18 @@ def response(action, succeeded, response, options = {}, source_id = nil) end def headers(action, options) - auth_token = @options[:access_token] ? "Bearer #{@options[:access_token]}" : @options[:secret_key] - auth_token = @options[:public_key] if action == :tokens - headers = { - 'Authorization' => auth_token, - 'Content-Type' => 'application/json;charset=UTF-8' - } + headers = { 'Authorization' => auth_token(action), 'Content-Type' => 'application/json;charset=UTF-8' } headers['Cko-Idempotency-Key'] = options[:idempotency_key] if options[:idempotency_key] + headers end + def auth_token(action) + return @options[:public_key] if action == :tokens + + "Bearer #{@options[:access_token] || @options[:secret_key]}" + end + def tokenize(payment_method, options = {}) post = {} add_authorization_type(post, options) diff --git a/test/remote/gateways/remote_checkout_v2_test.rb b/test/remote/gateways/remote_checkout_v2_test.rb index b46ad64bb3f..becc97df46f 100644 --- a/test/remote/gateways/remote_checkout_v2_test.rb +++ b/test/remote/gateways/remote_checkout_v2_test.rb @@ -5,9 +5,9 @@ class RemoteCheckoutV2Test < Test::Unit::TestCase def setup gateway_fixtures = fixtures(:checkout_v2) gateway_token_fixtures = fixtures(:checkout_v2_token) - @gateway = CheckoutV2Gateway.new(secret_key: gateway_fixtures[:secret_key]) - @gateway_oauth = CheckoutV2Gateway.new({ client_id: gateway_fixtures[:client_id], client_secret: gateway_fixtures[:client_secret] }) - @gateway_token = CheckoutV2Gateway.new(secret_key: gateway_token_fixtures[:secret_key], public_key: gateway_token_fixtures[:public_key]) + @gateway = CheckoutV2Gateway.new(gateway_token_fixtures) + @gateway_basic_auth = CheckoutV2Gateway.new(secret_key: gateway_fixtures[:secret_key]) + @gateway_oauth = CheckoutV2Gateway.new(client_id: gateway_fixtures[:client_id], client_secret: gateway_fixtures[:client_secret]) @amount = 200 @credit_card = credit_card('4242424242424242', verification_value: '100', month: '6', year: Time.now.year + 1) @@ -88,8 +88,7 @@ def setup @additional_options = @options.merge( card_on_file: true, transaction_indicator: 2, - previous_charge_id: 'pay_123', - processing_channel_id: 'pc_123' + previous_charge_id: 'pay_123' ) @additional_options_3ds = @options.merge( execute_threed: true, @@ -215,7 +214,7 @@ def test_network_transaction_scrubbing def test_store_transcript_scrubbing response = nil transcript = capture_transcript(@gateway) do - response = @gateway_token.store(@credit_card, @options) + response = @gateway.store(@credit_card, @options) end token = response.responses.first.params['token'] transcript = @gateway.scrub(transcript) @@ -297,6 +296,12 @@ def test_successful_purchase_with_an_expired_access_token end end + def test_successful_purchase_for_secret_key_basic_authorization_header + response = @gateway_basic_auth.purchase(@amount, @credit_card, @options) + assert_success response + assert_equal 'Succeeded', response.message + end + def test_successful_purchase_with_vts_network_token response = @gateway.purchase(100, @vts_network_token, @options) assert_success response @@ -452,8 +457,8 @@ def test_successful_purchase_includes_avs_result response = @gateway.purchase(@amount, @credit_card, @options) assert_success response assert_equal 'Succeeded', response.message - assert_equal 'S', response.avs_result['code'] - assert_equal 'U.S.-issuing bank does not support AVS.', response.avs_result['message'] + assert_equal 'G', response.avs_result['code'] + assert_equal 'Non-U.S. issuing bank does not support AVS.', response.avs_result['message'] end def test_successful_purchase_includes_avs_result_via_oauth @@ -468,8 +473,8 @@ def test_successful_authorize_includes_avs_result response = @gateway.authorize(@amount, @credit_card, @options) assert_success response assert_equal 'Succeeded', response.message - assert_equal 'S', response.avs_result['code'] - assert_equal 'U.S.-issuing bank does not support AVS.', response.avs_result['message'] + assert_equal 'G', response.avs_result['code'] + assert_equal 'Non-U.S. issuing bank does not support AVS.', response.avs_result['message'] end def test_successful_purchase_includes_cvv_result @@ -522,7 +527,7 @@ def test_successful_authorize_with_estimated_type_via_oauth end def test_successful_authorize_with_processing_channel_id - response = @gateway.authorize(@amount, @credit_card, @options.merge({ processing_channel_id: 'pc_ovo75iz4hdyudnx6tu74mum3fq' })) + response = @gateway.authorize(@amount, @credit_card, @options) assert_success response assert_equal 'Succeeded', response.message end @@ -557,7 +562,6 @@ def test_successful_purchase_with_processing_data options = @options.merge( processing: { aft: true, - preferred_scheme: 'cartes_bancaires', app_id: 'com.iap.linker_portal', airline_data: [ { @@ -712,19 +716,22 @@ def test_successful_purchase_with_metadata_via_oauth end def test_successful_purchase_with_minimal_options - response = @gateway.purchase(@amount, @credit_card, billing_address: address) + min_options = { billing_address: address, processing_channel_id: 'pc_lxgl7aqahkzubkundd2l546hdm' } + response = @gateway.purchase(@amount, @credit_card, min_options) assert_success response assert_equal 'Succeeded', response.message end def test_successful_purchase_with_shipping_address - response = @gateway.purchase(@amount, @credit_card, shipping_address: address) + min_options = { shipping_address: address, processing_channel_id: 'pc_lxgl7aqahkzubkundd2l546hdm' } + response = @gateway.purchase(@amount, @credit_card, min_options) assert_success response assert_equal 'Succeeded', response.message end def test_successful_purchase_without_phone_number - response = @gateway.purchase(@amount, @credit_card, billing_address: address.update(phone: nil)) + min_options = { billing_address: address.update(phone: nil), processing_channel_id: 'pc_lxgl7aqahkzubkundd2l546hdm' } + response = @gateway.purchase(@amount, @credit_card, min_options) assert_success response assert_equal 'Succeeded', response.message end @@ -738,7 +745,7 @@ def test_successful_purchase_without_name end def test_successful_purchase_with_ip - response = @gateway.purchase(@amount, @credit_card, ip: '96.125.185.52') + response = @gateway.purchase(@amount, @credit_card, @options.merge(ip: '96.125.185.52')) assert_success response assert_equal 'Succeeded', response.message end @@ -746,7 +753,7 @@ def test_successful_purchase_with_ip def test_failed_purchase response = @gateway.purchase(100, @credit_card_dnh, @options) assert_failure response - assert_equal 'Invalid Card Number', response.message + assert_equal 'Declined - Do Not Honour', response.message end def test_failed_purchase_via_oauth @@ -770,7 +777,7 @@ def test_avs_failed_authorize def test_invalid_shipping_address response = @gateway.authorize(@amount, @credit_card, shipping_address: address.update(country: 'Canada')) assert_failure response - assert_equal 'request_invalid: country_address_invalid', response.message + assert_equal 'request_invalid: address_country_invalid', response.message end def test_successful_authorize_and_capture @@ -937,17 +944,17 @@ def test_money_transfer_payout_handles_blank_destination_address end def test_successful_store - response = @gateway_token.store(@credit_card, @options) + response = @gateway.store(@credit_card, @options) assert_success response assert_equal 'Succeeded', response.message end def test_successful_unstore_after_store - store = @gateway_token.store(@credit_card, @options) + store = @gateway.store(@credit_card, @options) assert_success store assert_equal 'Succeeded', store.message source_id = store.params['id'] - response = @gateway_token.unstore(source_id, @options) + response = @gateway.unstore(source_id, @options) assert_success response assert_equal response.params['response_code'], '204' end @@ -991,7 +998,7 @@ def test_failed_store_oauth_credit_card end def test_successful_purchase_oauth_after_store_credit_card - store = @gateway_token.store(@credit_card, @options) + store = @gateway.store(@credit_card, @options) assert_success store token = store.params['id'] response = @gateway_oauth.purchase(@amount, token, @options) @@ -1152,8 +1159,8 @@ def test_failed_verify def test_expired_card_returns_error_code response = @gateway.purchase(@amount, @expired_card, @options) assert_failure response - assert_equal 'request_invalid: card_expired', response.message - assert_equal 'request_invalid: card_expired', response.error_code + assert_equal 'processing_error: card_expired', response.message + assert_equal 'processing_error: card_expired', response.error_code end def test_successful_purchase_with_idempotency_key