Skip to content

Commit

Permalink
NMI: Adding GooglePay and ApplePay (#5146)
Browse files Browse the repository at this point in the history
Description
-------------------------
This commit add support to create transaction with GooglePay and
ApplePay.
This payment methods are working for nmi_secure.

Unit test
-------------------------
Finished in 11.283174 seconds.

59 tests, 475 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications

100% passed

5.23 tests/s, 42.10 assertions/s

Remote test
-------------------------
Finished in 115.513346 seconds.

55 tests, 199 assertions, 12 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications

78.1818% passed

0.48 tests/s, 1.72 assertions/s

Rubocop
-------------------------
798 files inspected, no offenses detected

Co-authored-by: Javier Pedroza <jpedroza@spreedly.com>
  • Loading branch information
javierpedrozaing and Javier Pedroza committed Jul 17, 2024
1 parent 957dd75 commit 941c6d2
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 11 deletions.
14 changes: 13 additions & 1 deletion lib/active_merchant/billing/gateways/nmi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ def scrub(transcript)
gsub(%r((cvv=)\d+), '\1[FILTERED]').
gsub(%r((checkaba=)\d+), '\1[FILTERED]').
gsub(%r((checkaccount=)\d+), '\1[FILTERED]').
gsub(%r((cavv=)[^&\n]*), '\1[FILTERED]').
gsub(%r((cryptogram=)[^&]+(&?)), '\1[FILTERED]\2')
end

Expand Down Expand Up @@ -166,7 +167,7 @@ def add_payment_method(post, payment_method, options)
elsif payment_method.is_a?(NetworkTokenizationCreditCard)
post[:ccnumber] = payment_method.number
post[:ccexp] = exp_date(payment_method)
post[:token_cryptogram] = payment_method.payment_cryptogram
add_network_token_fields(post, payment_method)
elsif card_brand(payment_method) == 'check'
post[:payment] = 'check'
post[:firstname] = payment_method.first_name
Expand All @@ -187,6 +188,17 @@ def add_payment_method(post, payment_method, options)
end
end

def add_network_token_fields(post, payment_method)
if payment_method.source == :apple_pay || payment_method.source == :google_pay
post[:cavv] = payment_method.payment_cryptogram
post[:eci] = payment_method.eci
post[:decrypted_applepay_data] = 1
post[:decrypted_googlepay_data] = 1
else
post[:token_cryptogram] = payment_method.payment_cryptogram
end
end

def add_stored_credential(post, options)
return unless (stored_credential = options[:stored_credential])

Expand Down
58 changes: 48 additions & 10 deletions test/remote/gateways/remote_nmi_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,26 @@ def setup
routing_number: '123123123',
account_number: '123123123'
)
@apple_pay_card = network_tokenization_credit_card(
@apple_pay = network_tokenization_credit_card(
'4111111111111111',
payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=',
month: '01',
year: '2024',
year: Time.new.year + 2,
source: :apple_pay,
eci: '5',
transaction_id: '123456789'
)

@google_pay = network_tokenization_credit_card(
'4111111111111111',
payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=',
month: '01',
year: Time.new.year + 2,
source: :google_pay,
transaction_id: '123456789',
eci: '05'
)

@options = {
order_id: generate_unique_id,
billing_address: address,
Expand Down Expand Up @@ -130,17 +141,33 @@ def test_failed_purchase_with_echeck
assert_equal 'FAILED', response.message
end

def test_successful_purchase_with_apple_pay_card
assert @gateway.supports_network_tokenization?
assert response = @gateway.purchase(@amount, @apple_pay_card, @options)
def test_successful_purchase_with_apple_pay
assert @gateway_secure.supports_network_tokenization?
assert response = @gateway_secure.purchase(@amount, @apple_pay, @options)
assert_success response
assert response.test?
assert_equal 'Succeeded', response.message
assert response.authorization
end

def test_successful_purchase_with_google_pay
assert @gateway_secure.supports_network_tokenization?
assert response = @gateway_secure.purchase(@amount, @google_pay, @options)
assert_success response
assert response.test?
assert_equal 'Succeeded', response.message
assert response.authorization
end

def test_failed_purchase_with_apple_pay_card
assert response = @gateway.purchase(99, @apple_pay_card, @options)
def test_failed_purchase_with_apple_pay
assert response = @gateway_secure.purchase(1, @apple_pay, @options)
assert_failure response
assert response.test?
assert_equal 'DECLINE', response.message
end

def test_failed_purchase_with_google_pay
assert response = @gateway_secure.purchase(1, @google_pay, @options)
assert_failure response
assert response.test?
assert_equal 'DECLINE', response.message
Expand Down Expand Up @@ -482,12 +509,23 @@ def test_check_transcript_scrubbing

def test_network_tokenization_transcript_scrubbing
transcript = capture_transcript(@gateway) do
@gateway.purchase(@amount, @apple_pay_card, @options)
@gateway.purchase(@amount, @apple_pay, @options)
end
clean_transcript = @gateway.scrub(transcript)

assert_scrubbed(@apple_pay_card.number, clean_transcript)
assert_scrubbed(@apple_pay_card.payment_cryptogram, clean_transcript)
assert_scrubbed(@apple_pay.number, clean_transcript)
assert_scrubbed(@apple_pay.payment_cryptogram, clean_transcript)
assert_password_scrubbed(clean_transcript)
end

def test_transcript_scrubbing_with_google_pay
transcript = capture_transcript(@gateway) do
@gateway.purchase(@amount, @google_pay, @options)
end

clean_transcript = @gateway.scrub(transcript)
assert_scrubbed(@apple_pay.number, clean_transcript)
assert_scrubbed(@apple_pay.payment_cryptogram, clean_transcript)
assert_password_scrubbed(clean_transcript)
end

Expand Down
46 changes: 46 additions & 0 deletions test/unit/gateways/nmi_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,52 @@ def setup
descriptor_merchant_id: '120',
descriptor_url: 'url'
}

@google_pay = network_tokenization_credit_card(
'4111111111111111',
brand: 'visa',
eci: '05',
month: '02',
year: '2035',
source: :google_pay,
payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=',
transaction_id: '13456789'
)

@apple_pay = network_tokenization_credit_card(
'4111111111111111',
brand: 'visa',
eci: '05',
month: '02',
year: '2035',
source: :apple_pay,
payment_cryptogram: 'EHuWW9PiBkWvqE5juRwDzAUFBAk=',
transaction_id: '13456789'
)
end

def test_successful_apple_pay_purchase
stub_comms do
@gateway.purchase(@amount, @apple_pay)
end.check_request do |_endpoint, data, _headers|
assert_match(/type=sale/, data)
assert_match(/ccnumber=4111111111111111/, data)
assert_match(/ccexp=#{sprintf("%.2i", @apple_pay.month)}#{@apple_pay.year.to_s[-2..-1]}/, data)
assert_match(/cavv=EHuWW9PiBkWvqE5juRwDzAUFBAk%3D/, data)
assert_match(/eci=05/, data)
end.respond_with(successful_purchase_response)
end

def test_successful_google_pay_purchase
stub_comms do
@gateway.purchase(@amount, @google_pay)
end.check_request do |_endpoint, data, _headers|
assert_match(/type=sale/, data)
assert_match(/ccnumber=4111111111111111/, data)
assert_match(/ccexp=#{sprintf("%.2i", @google_pay.month)}#{@google_pay.year.to_s[-2..-1]}/, data)
assert_match(/cavv=EHuWW9PiBkWvqE5juRwDzAUFBAk%3D/, data)
assert_match(/eci=05/, data)
end.respond_with(successful_purchase_response)
end

def test_successful_authorize_and_capture_using_security_key
Expand Down

0 comments on commit 941c6d2

Please sign in to comment.