Skip to content

Commit

Permalink
OPPS-225 Worldpay Idempotency key fix
Browse files Browse the repository at this point in the history
  • Loading branch information
jherreraa committed Dec 4, 2024
1 parent 447aad3 commit 9191189
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 8 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@
* Decidir and DecicirPlus: Add the wallet_id field [yunnydang] #5354
* Worldpay: Update where to pass shopperIPAddress [almalee24] #5348
* Braintree: Account for BraintreeError [almalee24] #5346
* Worldpay: Fix stored credentials unscheduled reason type [Buitragox] #5352
* Worldpay: Fix stored credentials unscheduled reason type [Buitragox] #5352
* Worldpay: Worldpay: Idempotency key fix [jherreraa] #5359


== Version 1.137.0 (August 2, 2024)
* Unlock dependency on `rexml` to allow fixing a CVE (#5181).
Expand Down
9 changes: 7 additions & 2 deletions lib/active_merchant/billing/gateways/worldpay.rb
Original file line number Diff line number Diff line change
Expand Up @@ -947,7 +947,7 @@ def parse_elements(node, response)
end

def headers(options)
idempotency_key = options[:idempotency_key]
@idempotency_key ||= options[:idempotency_key]

headers = {
'Content-Type' => 'text/xml',
Expand All @@ -960,7 +960,12 @@ def headers(options)
cookie = options[:cookie] || cookie
headers['Cookie'] = cookie if cookie

headers['Idempotency-Key'] = idempotency_key if idempotency_key
# Required because Worldpay does not accept duplicate idempotency keys
# for different transactions, such as in the case of an authorize => capture flow.
if @idempotency_key
headers['Idempotency-Key'] = @idempotency_key
@idempotency_key = SecureRandom.uuid
end
headers
end

Expand Down
10 changes: 5 additions & 5 deletions test/remote/gateways/remote_worldpay_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -307,17 +307,17 @@ def test_unsucessfull_authorize_without_token_number_apple_pay
response = @gateway.authorize(@amount, @apple_pay_network_token, @options)

assert_failure response
assert_equal response.error_code, '5'
assert_equal "Element 'tokenNumber' must have valid numeric content.", response.message
assert_equal response.error_code, '2'
assert_match "Missing required elements 'tokenNumber'", response.message
end

def test_unsucessfull_authorize_with_token_number_as_empty_string_apple_pay
@apple_pay_network_token.number = ''
response = @gateway.authorize(@amount, @apple_pay_network_token, @options)

assert_failure response
assert_equal response.error_code, '5'
assert_equal "Element 'tokenNumber' must have valid numeric content.", response.message
assert_equal response.error_code, '2'
assert_match "Missing required elements 'tokenNumber'", response.message
end

def test_unsucessfull_authorize_with_invalid_token_number_apple_pay
Expand Down Expand Up @@ -1340,7 +1340,7 @@ def test_failed_refund_synchronous_response

refund = @cftgateway.refund(@amount * 2, auth.authorization, authorization_validated: true)
assert_failure refund
assert_equal 'Refund amount too high', refund.message
assert_equal 'Invalid amount: The refund amount should be equal to the captured value', refund.message
end

def test_successful_purchase_with_options_synchronous_response
Expand Down
11 changes: 11 additions & 0 deletions test/unit/gateways/worldpay_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,17 @@ def test_payment_type_for_credit_card
assert_equal payment, :credit
end

def test_successful_purchase_checking_idempotency_header
headers_list = []
response = stub_comms do
@gateway.purchase(@amount, @credit_card, @options.merge!({ idempotency_key: 'test123' }))
end.check_request do |_endpoint, _data, headers|
headers_list << headers
end.respond_with(successful_authorize_response, successful_capture_response)
assert_not_equal headers_list[0]['Idempotency-Key'], headers_list[1]['Idempotency-Key']
assert_success response
end

def test_successful_authorize
response = stub_comms do
@gateway.authorize(@amount, @credit_card, @options)
Expand Down

0 comments on commit 9191189

Please sign in to comment.