diff --git a/lib/active_merchant/billing/gateways/worldpay.rb b/lib/active_merchant/billing/gateways/worldpay.rb
index 9d77455b005..db893f56528 100644
--- a/lib/active_merchant/billing/gateways/worldpay.rb
+++ b/lib/active_merchant/billing/gateways/worldpay.rb
@@ -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
@@ -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
@@ -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
diff --git a/test/unit/gateways/worldpay_test.rb b/test/unit/gateways/worldpay_test.rb
index f2dc5f177c5..b6770bf7160 100644
--- a/test/unit/gateways/worldpay_test.rb
+++ b/test/unit/gateways/worldpay_test.rb
@@ -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
@@ -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(EC_v1), data)
+ assert_match(%r(transactionId), data)
+ assert_match(%r(QlzLxRFnNP9/GTaMhBwgmZ2ywntbr9), 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(EC_v1), data)
+ assert_match(%r(transactionId), data)
+ assert_match(%r(QlzLxRFnNP9/GTaMhBwgmZ2ywntbr9), 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)