diff --git a/lib/active_merchant/billing/gateways/authorize_net.rb b/lib/active_merchant/billing/gateways/authorize_net.rb index 2016756aaac..a68eece3059 100644 --- a/lib/active_merchant/billing/gateways/authorize_net.rb +++ b/lib/active_merchant/billing/gateways/authorize_net.rb @@ -89,7 +89,6 @@ class AuthorizeNetGateway < Gateway 2 => /\A;(?[\d]{1,19}+)=(?[\d]{0,4}|=)(?[\d]{0,3}|=)(?.*)\?\Z/ }.freeze - APPLE_PAY_DATA_DESCRIPTOR = 'COMMON.APPLE.INAPP.PAYMENT' PAYMENT_METHOD_NOT_SUPPORTED_ERROR = '155' INELIGIBLE_FOR_ISSUING_CREDIT_ERROR = '54' @@ -165,7 +164,7 @@ def credit(amount, payment, options = {}) xml.transactionType('refundTransaction') xml.amount(amount(amount)) - add_payment_source(xml, payment, options, :credit) + add_payment_method(xml, payment, options, :credit) xml.refTransId(transaction_id_from(options[:transaction_id])) if options[:transaction_id] add_invoice(xml, 'refundTransaction', options) add_customer_data(xml, payment, options) @@ -262,7 +261,7 @@ def add_auth_purchase(xml, transaction_type, amount, payment, options) xml.transactionRequest do xml.transactionType(transaction_type) xml.amount(amount(amount)) - add_payment_source(xml, payment, options) + add_payment_method(xml, payment, options) add_invoice(xml, transaction_type, options) add_tax_fields(xml, options) add_duty_fields(xml, options) @@ -287,7 +286,7 @@ def add_cim_auth_purchase(xml, transaction_type, amount, payment, options) add_tax_fields(xml, options) add_shipping_fields(xml, options) add_duty_fields(xml, options) - add_payment_source(xml, payment, options) + add_payment_method(xml, payment, options) add_invoice(xml, transaction_type, options) add_tax_exempt_status(xml, options) end @@ -407,17 +406,20 @@ def normal_void(authorization, options) end end - def add_payment_source(xml, source, options, action = nil) - return unless source + def add_payment_method(xml, payment_method, options, action = nil) + return unless payment_method - if source.is_a?(String) - add_token_payment_method(xml, source, options) - elsif card_brand(source) == 'check' - add_check(xml, source) - elsif card_brand(source) == 'apple_pay' - add_apple_pay_payment_token(xml, source) + case payment_method + when String + add_token_payment_method(xml, payment_method, options) + when Check + add_check(xml, payment_method) else - add_credit_card(xml, source, action) + if payment_method.class == NetworkTokenizationCreditCard && action != :credit + add_network_token(xml, payment_method) + else + add_credit_card(xml, payment_method) + end end end @@ -490,7 +492,7 @@ def add_user_fields(xml, amount, options) end end - def add_credit_card(xml, credit_card, action) + def add_credit_card(xml, credit_card) if credit_card.track_data add_swipe_data(xml, credit_card) else @@ -499,7 +501,6 @@ def add_credit_card(xml, credit_card, action) xml.cardNumber(truncate(credit_card.number, 16)) xml.expirationDate(format(credit_card.month, :two_digits) + '/' + format(credit_card.year, :four_digits)) xml.cardCode(credit_card.verification_value) if credit_card.valid_card_verification_value?(credit_card.verification_value, credit_card.brand) - xml.cryptogram(credit_card.payment_cryptogram) if credit_card.is_a?(NetworkTokenizationCreditCard) && action != :credit end end end @@ -526,17 +527,20 @@ def add_token_payment_method(xml, token, options) xml.customerPaymentProfileId(customer_payment_profile_id) end - def add_apple_pay_payment_token(xml, apple_pay_payment_token) + def add_network_token(xml, payment_method) xml.payment do - xml.opaqueData do - xml.dataDescriptor(APPLE_PAY_DATA_DESCRIPTOR) - xml.dataValue(Base64.strict_encode64(apple_pay_payment_token.payment_data.to_json)) + xml.creditCard do + xml.cardNumber(truncate(payment_method.number, 16)) + xml.expirationDate(format(payment_method.month, :two_digits) + '/' + format(payment_method.year, :four_digits)) + xml.isPaymentToken(true) + xml.cryptogram(payment_method.payment_cryptogram) end end end def add_market_type_device_type(xml, payment, options) - return if payment.is_a?(String) || card_brand(payment) == 'check' || card_brand(payment) == 'apple_pay' + return unless payment.is_a?(CreditCard) + return if payment.is_a?(NetworkTokenizationCreditCard) if valid_track_data xml.retail do @@ -754,13 +758,7 @@ def create_customer_payment_profile(credit_card, options) xml.customerProfileId options[:customer_profile_id] xml.paymentProfile do add_billing_address(xml, credit_card, options) - xml.payment do - xml.creditCard do - xml.cardNumber(truncate(credit_card.number, 16)) - xml.expirationDate(format(credit_card.year, :four_digits) + '-' + format(credit_card.month, :two_digits)) - xml.cardCode(credit_card.verification_value) if credit_card.verification_value - end - end + add_credit_card(xml, credit_card) end end end @@ -776,13 +774,7 @@ def create_customer_profile(credit_card, options) xml.customerType('individual') add_billing_address(xml, credit_card, options) add_shipping_address(xml, options, 'shipToList') - xml.payment do - xml.creditCard do - xml.cardNumber(truncate(credit_card.number, 16)) - xml.expirationDate(format(credit_card.year, :four_digits) + '-' + format(credit_card.month, :two_digits)) - xml.cardCode(credit_card.verification_value) if credit_card.verification_value - end - end + add_credit_card(xml, credit_card) end end end diff --git a/test/remote/gateways/remote_authorize_net_test.rb b/test/remote/gateways/remote_authorize_net_test.rb index e6388238550..6f20e910cef 100644 --- a/test/remote/gateways/remote_authorize_net_test.rb +++ b/test/remote/gateways/remote_authorize_net_test.rb @@ -903,8 +903,8 @@ def test_successful_refund_with_network_tokenization def test_successful_credit_with_network_tokenization credit_card = network_tokenization_credit_card( - '4000100011112224', - payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=', + '5424000000000015', + payment_cryptogram: 'EjRWeJASNFZ4kBI0VniQEjRWeJA=', verification_value: nil ) diff --git a/test/unit/gateways/authorize_net_test.rb b/test/unit/gateways/authorize_net_test.rb index b0f3b957b0e..9b6aeecee71 100644 --- a/test/unit/gateways/authorize_net_test.rb +++ b/test/unit/gateways/authorize_net_test.rb @@ -16,11 +16,15 @@ def setup @amount = 100 @credit_card = credit_card @check = check - @apple_pay_payment_token = ActiveMerchant::Billing::ApplePayPaymentToken.new( - { data: 'encoded_payment_data' }, - payment_instrument_name: 'SomeBank Visa', - payment_network: 'Visa', - transaction_identifier: 'transaction123' + @payment_token = network_tokenization_credit_card( + '4242424242424242', + payment_cryptogram: 'dGVzdGNyeXB0b2dyYW1YWFhYWFhYWFhYWFg9PQ==', + brand: 'visa', + eci: '05', + month: '09', + year: '2030', + first_name: 'Longbob', + last_name: 'Longsen' ) @options = { @@ -153,7 +157,7 @@ def test_device_type_used_from_options_if_included_with_valid_track_data end def test_market_type_not_included_for_apple_pay_or_echeck - [@check, @apple_pay_payment_token].each do |payment| + [@check, @payment_token].each do |payment| stub_comms do @gateway.purchase(@amount, payment) end.check_request do |_endpoint, data, _headers| @@ -264,14 +268,8 @@ def test_failed_echeck_authorization end def test_successful_apple_pay_authorization - response = stub_comms do - @gateway.authorize(@amount, @apple_pay_payment_token) - end.check_request do |_endpoint, data, _headers| - parse(data) do |doc| - assert_equal @gateway.class::APPLE_PAY_DATA_DESCRIPTOR, doc.at_xpath('//opaqueData/dataDescriptor').content - assert_equal Base64.strict_encode64(@apple_pay_payment_token.payment_data.to_json), doc.at_xpath('//opaqueData/dataValue').content - end - end.respond_with(successful_authorize_response) + @gateway.expects(:ssl_post).returns(successful_authorize_response) + response = @gateway.authorize(@amount, @payment_token) assert response assert_instance_of Response, response @@ -280,14 +278,8 @@ def test_successful_apple_pay_authorization end def test_successful_apple_pay_purchase - response = stub_comms do - @gateway.purchase(@amount, @apple_pay_payment_token) - end.check_request do |_endpoint, data, _headers| - parse(data) do |doc| - assert_equal @gateway.class::APPLE_PAY_DATA_DESCRIPTOR, doc.at_xpath('//opaqueData/dataDescriptor').content - assert_equal Base64.strict_encode64(@apple_pay_payment_token.payment_data.to_json), doc.at_xpath('//opaqueData/dataValue').content - end - end.respond_with(successful_purchase_response) + @gateway.expects(:ssl_post).returns(successful_purchase_response) + response = @gateway.purchase(@amount, @payment_token) assert response assert_instance_of Response, response