Skip to content

Commit

Permalink
Worldpay: Encyrpted ApplePay and GooglePay
Browse files Browse the repository at this point in the history
Add support for encrypted ApplePay and GooglePay.
  • Loading branch information
Alma Malambo committed Apr 15, 2024
1 parent c2f4d7c commit dac72a6
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 2 deletions.
29 changes: 28 additions & 1 deletion lib/active_merchant/billing/gateways/worldpay.rb
Expand Up @@ -573,6 +573,8 @@ def add_payment_method(xml, amount, payment_method, options)
add_amount_for_pay_as_order(xml, amount, payment_method, options)
when :network_token
add_network_tokenization_card(xml, payment_method, options)
when :encrypted_wallet
add_encrypted_wallet(xml, payment_method, options)
else
add_card_or_token(xml, payment_method, options)
end
Expand Down Expand Up @@ -612,6 +614,23 @@ def add_network_tokenization_card(xml, payment_method, options)
end
end

def add_encrypted_wallet(xml, payment_method, options)
source = payment_method.source == :apple_pay ? 'APPLEPAY' : 'PAYWITHGOOGLE'

xml.paymentDetails do
xml.tag! "#{source}-SSL" do
xml.header do
xml.ephemeralPublicKey payment_method.payment_data.dig(:header, :ephemeralPublicKey)
xml.publicKeyHash payment_method.payment_data.dig(:header, :publicKeyHash)
xml.transactionId payment_method.payment_data.dig(:header, :transactionId)
end
xml.signature payment_method.payment_data[:signature]
xml.version payment_method.payment_data[:version]
xml.data payment_method.payment_data[:data]
end
end
end

def add_card_or_token(xml, payment_method, options)
xml.paymentDetails credit_fund_transfer_attribute(options) do
if options[:payment_type] == :token
Expand Down Expand Up @@ -981,7 +1000,15 @@ def payment_details(payment_method, options = {})
when String
token_type_and_details(payment_method)
else
type = network_token?(payment_method) || options[:wallet_type] == :google_pay ? :network_token : :credit
type = if network_token?(payment_method) || options[:wallet_type] == :google_pay
if network_token?(payment_method) && payment_method.payment_data
:encrypted_wallet
else
:network_token
end
else
:credit
end

{ payment_type: type }
end
Expand Down
52 changes: 51 additions & 1 deletion test/unit/gateways/worldpay_test.rb
Expand Up @@ -164,7 +164,7 @@ def test_payment_type_for_network_card

def test_payment_type_returns_network_token_if_the_payment_method_responds_to_source_payment_cryptogram_and_eci
payment_method = mock
payment_method.stubs(source: nil, payment_cryptogram: nil, eci: nil)
payment_method.stubs(source: nil, payment_cryptogram: nil, eci: nil, payment_data: nil)
result = @gateway.send(:payment_details, payment_method)
assert_equal({ payment_type: :network_token }, result)
end
Expand Down Expand Up @@ -219,6 +219,56 @@ def test_successful_authorize_without_name
assert_equal 'R50704213207145707', response.authorization
end

def test_successful_authorize_encrypted_apple_pay
apple_pay = ActiveMerchant::Billing::NetworkTokenizationCreditCard.new({
source: :apple_pay,
payment_data: {
version: 'EC_v1',
data: 'QlzLxRFnNP9/GTaMhBwgmZ2ywntbr9',
signature: 'signature',
header: {
ephemeralPublicKey: 'ephemeralPublicKey',
publicKeyHash: 'publicKeyHash',
transactionId: 'transactionId'
}
}
})

stub_comms do
@gateway.authorize(@amount, apple_pay, @options)
end.check_request do |_endpoint, data, _headers|
assert_match(/APPLEPAY-SSL/, data)
assert_match(%r(<version>EC_v1</version>), data)
assert_match(%r(<transactionId>transactionId</transactionId>), data)
assert_match(%r(<data>QlzLxRFnNP9/GTaMhBwgmZ2ywntbr9</data>), data)
end.respond_with(successful_authorize_response)
end

def test_successful_authorize_encrypted_google_pay
google_pay = ActiveMerchant::Billing::NetworkTokenizationCreditCard.new({
source: :google_pay,
payment_data: {
version: 'EC_v1',
data: 'QlzLxRFnNP9/GTaMhBwgmZ2ywntbr9',
signature: 'signature',
header: {
ephemeralPublicKey: 'ephemeralPublicKey',
publicKeyHash: 'publicKeyHash',
transactionId: 'transactionId'
}
}
})

stub_comms do
@gateway.authorize(@amount, google_pay, @options)
end.check_request do |_endpoint, data, _headers|
assert_match(/PAYWITHGOOGLE-SSL/, data)
assert_match(%r(<version>EC_v1</version>), data)
assert_match(%r(<transactionId>transactionId</transactionId>), data)
assert_match(%r(<data>QlzLxRFnNP9/GTaMhBwgmZ2ywntbr9</data>), data)
end.respond_with(successful_authorize_response)
end

def test_successful_authorize_by_reference
response = stub_comms do
@gateway.authorize(@amount, @options[:order_id].to_s, @options)
Expand Down

0 comments on commit dac72a6

Please sign in to comment.