adyen-ruby-api-library 6.2.0 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1b091a2aaf201f3a22b41a22c069321d1d181daee6e33da275d94ab970b9b9ab
4
- data.tar.gz: 1806d42c9f609c9ff3b6e84e31ff1be9f4d4503d15f5a0c300a664a779a5c295
3
+ metadata.gz: 45627b45fc5df26d004c1a86d7640412d615383ccac35201f24f0e3ebed99394
4
+ data.tar.gz: 72a067ba4b95419ed87e526a371db2377d5b1af7056f9ac035a6e11327715da0
5
5
  SHA512:
6
- metadata.gz: f9c9221b5d0c164cd4a90c5d7e6531e6361c116e00139662fcff37588309c07c21740d8a3c277ec4b7febbad4d5af752a772eab0df5625430f66b3b47fcbfc92
7
- data.tar.gz: 4b89bec481b6b2e900325a9f9bc11a69e87b42d61a1358205e53d3a17f90c722377e4fdf7accafc11124ac2e4d70d88b36cdd214cb5f9b7d576e216d9ca6b31b
6
+ metadata.gz: a893d921b3236805bb89b6ca5fc1c553888d010c84c1927689f6bc47e1a78b23302c081edbc979d596ac70c0b6f23cad61b9a83cc11c6f8b22e1d73520951bdb
7
+ data.tar.gz: 3cc14ff3d1550ffb11f6ec08c37ae7858b5e39e1b14023e6323e3a132441b59ee383e39ca6db6dcb83eff24e4b9ae937bff416bc9684e1ba6cb8ba7b20e37405
data/.github/CODEOWNERS CHANGED
@@ -1 +1 @@
1
- * @crrood @wboereboom @AlexandrosMor @michaelpaul
1
+ * @Adyen/api-libraries-reviewers
@@ -0,0 +1,41 @@
1
+ name: "CodeQL"
2
+
3
+ on:
4
+ push:
5
+ branches: [ "develop", "main" ]
6
+ pull_request:
7
+ branches: [ "develop" ]
8
+ schedule:
9
+ - cron: "40 12 * * 0"
10
+
11
+ jobs:
12
+ analyze:
13
+ name: Analyze
14
+ runs-on: ubuntu-latest
15
+ permissions:
16
+ actions: read
17
+ contents: read
18
+ security-events: write
19
+
20
+ strategy:
21
+ fail-fast: false
22
+ matrix:
23
+ language: [ javascript ]
24
+
25
+ steps:
26
+ - name: Checkout
27
+ uses: actions/checkout@v3
28
+
29
+ - name: Initialize CodeQL
30
+ uses: github/codeql-action/init@v2
31
+ with:
32
+ languages: ${{ matrix.language }}
33
+ queries: +security-and-quality
34
+
35
+ - name: Autobuild
36
+ uses: github/codeql-action/autobuild@v2
37
+
38
+ - name: Perform CodeQL Analysis
39
+ uses: github/codeql-action/analyze@v2
40
+ with:
41
+ category: "/language:${{ matrix.language }}"
@@ -12,7 +12,7 @@ jobs:
12
12
  ruby: [2.5, 2.6, 2.7, '3.0', head]
13
13
  runs-on: ${{ matrix.os }}
14
14
  steps:
15
- - uses: actions/checkout@v2
15
+ - uses: actions/checkout@v3
16
16
  - uses: ruby/setup-ruby@v1
17
17
  with:
18
18
  ruby-version: ${{ matrix.ruby }}
@@ -9,7 +9,7 @@ jobs:
9
9
  runs-on: ubuntu-latest
10
10
 
11
11
  steps:
12
- - uses: actions/checkout@v1
12
+ - uses: actions/checkout@v3
13
13
 
14
14
  - name: Release Gem on RubyGems
15
15
  if: contains(github.ref, 'refs/tags/v')
data/lib/adyen/client.rb CHANGED
@@ -144,6 +144,13 @@ module Adyen
144
144
  raise connection_error, "Connection to #{url} failed"
145
145
  end
146
146
  end
147
+ if action.fetch(:method) == "delete"
148
+ begin
149
+ response = conn.delete
150
+ rescue Faraday::ConnectionFailed => connection_error
151
+ raise connection_error, "Connection to #{url} failed"
152
+ end
153
+ end
147
154
  if action.fetch(:method) == "patch"
148
155
  begin
149
156
  response = conn.patch do |req|
@@ -169,11 +176,16 @@ module Adyen
169
176
  when 401
170
177
  raise Adyen::AuthenticationError.new("Invalid API authentication; https://docs.adyen.com/user-management/how-to-get-the-api-key", request_data)
171
178
  when 403
172
- raise Adyen::PermissionError.new("Missing user permissions; https://docs.adyen.com/user-management/user-roles", request_data)
179
+ raise Adyen::PermissionError.new("Missing user permissions; https://docs.adyen.com/user-management/user-roles", request_data, response.body)
173
180
  end
174
-
175
- formatted_response = AdyenResult.new(response.body, response.headers, response.status)
176
-
181
+
182
+ # delete has no response.body (unless it throws an error)
183
+ if response.body == nil
184
+ formatted_response = AdyenResult.new("{}", response.headers, response.status)
185
+ else
186
+ formatted_response = AdyenResult.new(response.body, response.headers, response.status)
187
+ end
188
+
177
189
  formatted_response
178
190
  end
179
191
 
data/lib/adyen/errors.rb CHANGED
@@ -70,8 +70,8 @@ module Adyen
70
70
  end
71
71
 
72
72
  class PermissionError < AdyenError
73
- def initialize(msg, request)
74
- super(request, nil, msg, 403)
73
+ def initialize(msg, request, response)
74
+ super(request, response, msg, 403)
75
75
  end
76
76
  end
77
77
 
@@ -2,7 +2,7 @@ require_relative "service"
2
2
 
3
3
  module Adyen
4
4
  class Checkout < Service
5
- DEFAULT_VERSION = 68
5
+ DEFAULT_VERSION = 70
6
6
 
7
7
  def initialize(client, version = DEFAULT_VERSION)
8
8
  service = "Checkout"
@@ -13,7 +13,7 @@ module Adyen
13
13
  ]
14
14
 
15
15
  with_application_info = [
16
- :payment_session,
16
+ :payment_session
17
17
  ]
18
18
 
19
19
  super(client, version, service, method_names, with_application_info)
@@ -42,7 +42,7 @@ module Adyen
42
42
  else
43
43
  action = "paymentLinks"
44
44
  args[1] ||= {} # optional headers arg
45
- @client.call_adyen_api(@service, action, args[0], args[1], @version, true)
45
+ @client.call_adyen_api(@service, action, args[0], args[1], @version)
46
46
  end
47
47
  end
48
48
 
@@ -75,6 +75,10 @@ module Adyen
75
75
  def modifications
76
76
  @modifications ||= Adyen::Modifications.new(@client, @version)
77
77
  end
78
+
79
+ def stored_payment_methods
80
+ @stored_payment_methods ||= Adyen::StoredPaymentMethods.new(@client, @version)
81
+ end
78
82
  end
79
83
 
80
84
  class CheckoutDetail < Service
@@ -93,6 +97,16 @@ module Adyen
93
97
  action = "payments/result"
94
98
  @client.call_adyen_api(@service, action, request, headers, @version)
95
99
  end
100
+
101
+ def donations(request, headers = {})
102
+ action = "donations"
103
+ @client.call_adyen_api(@service, action, request, headers, @version)
104
+ end
105
+
106
+ def card_details(request, headers = {})
107
+ action = "cardDetails"
108
+ @client.call_adyen_api(@service, action, request, headers, @version)
109
+ end
96
110
  end
97
111
 
98
112
  class CheckoutLink < Service
@@ -104,12 +118,12 @@ module Adyen
104
118
 
105
119
  def get(linkId, headers = {})
106
120
  action = { method: 'get', url: "paymentLinks/" + linkId }
107
- @client.call_adyen_api(@service, action, {}, headers, @version, true)
121
+ @client.call_adyen_api(@service, action, {}, headers, @version)
108
122
  end
109
123
 
110
124
  def update(linkId, request, headers = {})
111
125
  action = { method: 'patch', url: "paymentLinks/" + linkId }
112
- @client.call_adyen_api(@service, action, request, headers, @version, false)
126
+ @client.call_adyen_api(@service, action, request, headers, @version)
113
127
  end
114
128
  end
115
129
 
@@ -161,12 +175,12 @@ module Adyen
161
175
 
162
176
  def capture(linkId, request, headers = {})
163
177
  action = "payments/" + linkId + "/captures"
164
- @client.call_adyen_api(@service, action, request, headers, @version, false)
178
+ @client.call_adyen_api(@service, action, request, headers, @version)
165
179
  end
166
180
 
167
181
  def cancel(linkId, request, headers = {})
168
182
  action = "payments/" + linkId + "/cancels"
169
- @client.call_adyen_api(@service, action, request, headers, @version, false)
183
+ @client.call_adyen_api(@service, action, request, headers, @version)
170
184
  end
171
185
 
172
186
  def genericCancel(request, headers = {})
@@ -176,17 +190,35 @@ module Adyen
176
190
 
177
191
  def refund(linkId, request, headers = {})
178
192
  action = "payments/" + linkId + "/refunds"
179
- @client.call_adyen_api(@service, action, request, headers, @version, false)
193
+ @client.call_adyen_api(@service, action, request, headers, @version)
180
194
  end
181
195
 
182
196
  def reversal(linkId, request, headers = {})
183
197
  action = "payments/" + linkId + "/reversals"
184
- @client.call_adyen_api(@service, action, request, headers, @version, false)
198
+ @client.call_adyen_api(@service, action, request, headers, @version)
185
199
  end
186
200
 
187
201
  def amountUpdate(linkId, request, headers = {})
188
202
  action = "payments/" + linkId + "/amountUpdates"
189
- @client.call_adyen_api(@service, action, request, headers, @version, false)
203
+ @client.call_adyen_api(@service, action, request, headers, @version)
204
+ end
205
+ end
206
+
207
+ class StoredPaymentMethods < Service
208
+ def initialize(client, version = DEFAULT_VERSION)
209
+ @service = "Checkout"
210
+ @client = client
211
+ @version = version
212
+ end
213
+
214
+ def get(query_array={}, headers = {})
215
+ action = { method: 'get', url: "storedPaymentMethods" + create_query_string(query_array)}
216
+ @client.call_adyen_api(@service, action, {}, headers, @version)
217
+ end
218
+
219
+ def delete(recurringId, query_array={}, headers = {})
220
+ action = { method: 'delete', url: "storedPaymentMethods/%s" % recurringId + create_query_string(query_array)}
221
+ @client.call_adyen_api(@service, action, {}, headers, @version)
190
222
  end
191
223
  end
192
- end
224
+ end
@@ -24,5 +24,10 @@ module Adyen
24
24
  end
25
25
  end
26
26
  end
27
+
28
+ # create query parameter from an array
29
+ def create_query_string(arr)
30
+ "?" + URI.encode_www_form(arr)
31
+ end
27
32
  end
28
33
  end
@@ -22,16 +22,15 @@ module Adyen
22
22
  end
23
23
 
24
24
  def data_to_sign(notification_request_item)
25
- NOTIFICATION_VALIDATION_KEYS.map { |key| fetch(notification_request_item, key).to_s }
26
- .map { |value| value.gsub('\\', '\\\\').gsub(':', '\\:') }
25
+ data = NOTIFICATION_VALIDATION_KEYS.map { |key| fetch(notification_request_item, key).to_s }
27
26
  .join(DATA_SEPARATOR)
27
+ return data
28
28
  end
29
29
 
30
30
  private
31
31
 
32
32
  def fetch(hash, keys)
33
33
  value = hash
34
-
35
34
  keys.to_s.split('.').each do |key|
36
35
  value = if key.to_i.to_s == key
37
36
  value[key.to_i]
data/lib/adyen/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Adyen
2
2
  NAME = "adyen-ruby-api-library"
3
- VERSION = "6.2.0".freeze
4
- end
3
+ VERSION = "6.3.0".freeze
4
+ end
@@ -597,6 +597,56 @@ RSpec.describe Adyen::Checkout, service: "checkout" do
597
597
  to eq("12345")
598
598
  end
599
599
 
600
+ it "makes a get storedPaymentMethods call" do
601
+ response_body = json_from_file("mocks/responses/Checkout/stored_payment_methods.json")
602
+
603
+ url = @shared_values[:client].service_url(@shared_values[:service], "storedPaymentMethods?merchantAccount=TestMerchantAccount&shopperReference=test-1234", @shared_values[:client].checkout.version)
604
+ WebMock.stub_request(:get, url).
605
+ with(
606
+ headers: {
607
+ "x-api-key" => @shared_values[:client].api_key
608
+ }
609
+ ).
610
+ to_return(
611
+ body: response_body
612
+ )
613
+
614
+ result = @shared_values[:client].checkout.stored_payment_methods.get({"merchantAccount" => "TestMerchantAccount", "shopperReference" => "test-1234"})
615
+ response_hash = result.response
616
+
617
+ expect(result.status).
618
+ to eq(200)
619
+ expect(response_hash).
620
+ to eq(JSON.parse(response_body))
621
+ expect(response_hash).
622
+ to be_a Adyen::HashWithAccessors
623
+ expect(response_hash).
624
+ to be_a_kind_of Hash
625
+ expect(response_hash["shopperReference"]).
626
+ to eq("test-1234")
627
+ end
628
+
629
+ it "makes a delete storedPaymentMethods call" do
630
+ response_body = json_from_file("mocks/responses/Checkout/stored_payment_methods.json")
631
+
632
+ url = @shared_values[:client].service_url(@shared_values[:service], "storedPaymentMethods/RL8FW7WZM6KXWD82?merchantAccount=TestMerchantAccount&shopperReference=test-1234", @shared_values[:client].checkout.version)
633
+ WebMock.stub_request(:delete, url).
634
+ with(
635
+ headers: {
636
+ "x-api-key" => @shared_values[:client].api_key
637
+ }
638
+ ).
639
+ to_return(
640
+ body: response_body
641
+ )
642
+
643
+ result = @shared_values[:client].checkout.stored_payment_methods.delete("RL8FW7WZM6KXWD82", {"merchantAccount" => "TestMerchantAccount", "shopperReference" => "test-1234"})
644
+ response_hash = result.response
645
+
646
+ expect(result.status).
647
+ to eq(200)
648
+ end
649
+
600
650
  # create client for automated tests
601
651
  client = create_client(:api_key)
602
652
 
data/spec/client_spec.rb CHANGED
@@ -106,7 +106,7 @@ RSpec.describe Adyen do
106
106
  mock_response = Faraday::Response.new(status: 200)
107
107
 
108
108
  expect(Adyen::AdyenResult).to receive(:new)
109
- expect(Faraday).to receive(:new).with("http://localhost:3001/v68/payments/details", connection_options).and_return(mock_faraday_connection)
109
+ expect(Faraday).to receive(:new).with("http://localhost:3001/v70/payments/details", connection_options).and_return(mock_faraday_connection)
110
110
  expect(mock_faraday_connection).to receive(:post).and_return(mock_response)
111
111
  client.checkout.payments.details(request_body)
112
112
  end
data/spec/errors_spec.rb CHANGED
@@ -33,7 +33,7 @@ RSpec.describe Adyen::AdyenError do
33
33
  expect(Adyen::AdyenError.new(@shared_values[:request], nil, nil, 'code').to_s).to eq("Adyen::AdyenError code:code, request:#{@shared_values[:request]}")
34
34
  end
35
35
  it 'uses the proper error class name' do
36
- expect(Adyen::PermissionError.new('message', @shared_values[:request]).to_s).to eq("Adyen::PermissionError code:403, msg:message, request:#{@shared_values[:request]}")
36
+ expect(Adyen::PermissionError.new('message', @shared_values[:request], 'response').to_s).to eq("Adyen::PermissionError code:403, msg:message, request:#{@shared_values[:request]}, response:response")
37
37
  end
38
38
  end
39
39
  describe '#masking' do
@@ -0,0 +1 @@
1
+ {"merchantAccount":"TestMerchantAccount", "shopperReference":"test-1234"}
@@ -0,0 +1,41 @@
1
+ {
2
+ "additionalData": {
3
+ "acquirerCode": "TestPmmAcquirer",
4
+ "acquirerReference": "DZMKWLXW6N6",
5
+ "authCode": "076181",
6
+ "avsResult": "5 No AVS data provided",
7
+ "avsResultRaw": "5",
8
+ "cardSummary": "1111",
9
+ "checkout.cardAddedBrand": "visa",
10
+ "cvcResult": "1 Matches",
11
+ "cvcResultRaw": "M",
12
+ "expiryDate": "03/2030",
13
+ "hmacSignature": "nIgT81gaB5oJpn2jPXupDq68iRo2wUlBsuYjtYfwKqo=",
14
+ "paymentMethod": "visa",
15
+ "refusalReasonRaw": "AUTHORISED",
16
+ "retry.attempt1.acquirer": "TestPmmAcquirer",
17
+ "retry.attempt1.acquirerAccount": "TestPmmAcquirerAccount",
18
+ "retry.attempt1.avsResultRaw": "5",
19
+ "retry.attempt1.rawResponse": "AUTHORISED",
20
+ "retry.attempt1.responseCode": "Approved",
21
+ "retry.attempt1.scaExemptionRequested": "lowValue",
22
+ "scaExemptionRequested": "lowValue"
23
+ },
24
+ "amount": {
25
+ "currency": "EUR",
26
+ "value": 1000
27
+ },
28
+ "eventCode": "AUTHORISATION",
29
+ "eventDate": "2023-01-09T16:27:29+01:00",
30
+ "merchantAccountCode": "AntoniStroinski",
31
+ "merchantReference": "\\\\slashes are fun",
32
+ "operations": [
33
+ "CANCEL",
34
+ "CAPTURE",
35
+ "REFUND"
36
+ ],
37
+ "paymentMethod": "visa",
38
+ "pspReference": "T7FD4VM4D3RZNN82",
39
+ "reason": "076181:1111:03/2030",
40
+ "success": "true"
41
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "additionalData": {
3
+ "acquirerCode": "TestPmmAcquirer",
4
+ "acquirerReference": "8NQH5BNF58M",
5
+ "authCode": "039404",
6
+ "avsResult": "5 No AVS data provided",
7
+ "avsResultRaw": "5",
8
+ "cardSummary": "1111",
9
+ "checkout.cardAddedBrand": "visa",
10
+ "cvcResult": "1 Matches",
11
+ "cvcResultRaw": "M",
12
+ "expiryDate": "03/2030",
13
+ "hmacSignature": "2EQYm7YJpKO4EtHSPu55SQTyWf8dkW5u2nD1tJFpViA=",
14
+ "paymentMethod": "visa",
15
+ "refusalReasonRaw": "AUTHORISED",
16
+ "retry.attempt1.acquirer": "TestPmmAcquirer",
17
+ "retry.attempt1.acquirerAccount": "TestPmmAcquirerAccount",
18
+ "retry.attempt1.avsResultRaw": "5",
19
+ "retry.attempt1.rawResponse": "AUTHORISED",
20
+ "retry.attempt1.responseCode": "Approved",
21
+ "retry.attempt1.scaExemptionRequested": "lowValue",
22
+ "scaExemptionRequested": "lowValue"
23
+ },
24
+ "amount": {
25
+ "currency": "EUR",
26
+ "value": 1000
27
+ },
28
+ "eventCode": "AUTHORISATION",
29
+ "eventDate": "2023-01-10T13:40:54+01:00",
30
+ "merchantAccountCode": "AntoniStroinski",
31
+ "merchantReference": ":slashes are fun",
32
+ "operations": [
33
+ "CANCEL",
34
+ "CAPTURE",
35
+ "REFUND"
36
+ ],
37
+ "paymentMethod": "visa",
38
+ "pspReference": "M8NB66SBZSGLNK82",
39
+ "reason": "039404:1111:03/2030",
40
+ "success": "true"
41
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "amount": {
3
+ "value": 1000,
4
+ "currency": "EUR"
5
+ },
6
+ "reason": "087330:1111:03/2030",
7
+ "success": "true",
8
+ "eventCode": "AUTHORISATION",
9
+ "eventDate": "2023-01-10T13:37:30+01:00",
10
+ "operations": [
11
+ "CANCEL",
12
+ "CAPTURE",
13
+ "REFUND"
14
+ ],
15
+ "pspReference": "X3GWNS6KJ8NKGK82",
16
+ "paymentMethod": "visa",
17
+ "additionalData": {
18
+ "authCode": "087330",
19
+ "avsResult": "5 No AVS data provided",
20
+ "cvcResult": "1 Matches",
21
+ "expiryDate": "03/2030",
22
+ "cardSummary": "1111",
23
+ "acquirerCode": "TestPmmAcquirer",
24
+ "avsResultRaw": "5",
25
+ "cvcResultRaw": "M",
26
+ "hmacSignature": "9Z0xdpG9Xi3zcmXv14t/BvMBut77O/Xq9D4CQXSDUi4=",
27
+ "paymentMethod": "visa",
28
+ "refusalReasonRaw": "AUTHORISED",
29
+ "acquirerReference": "HHCCC326PH6",
30
+ "scaExemptionRequested": "lowValue",
31
+ "checkout.cardAddedBrand": "visa",
32
+ "retry.attempt1.acquirer": "TestPmmAcquirer",
33
+ "retry.attempt1.rawResponse": "AUTHORISED",
34
+ "retry.attempt1.avsResultRaw": "5",
35
+ "retry.attempt1.responseCode": "Approved",
36
+ "retry.attempt1.acquirerAccount": "TestPmmAcquirerAccount",
37
+ "retry.attempt1.scaExemptionRequested": "lowValue"
38
+ },
39
+ "merchantReference": "//slashes are fun",
40
+ "merchantAccountCode": "AntoniStroinski"
41
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "additionalData": {
3
+ "acquirerCode": "TestPmmAcquirer",
4
+ "acquirerReference": "J8DXDJ2PV6P",
5
+ "authCode": "052095",
6
+ "avsResult": "5 No AVS data provided",
7
+ "avsResultRaw": "5",
8
+ "cardSummary": "1111",
9
+ "checkout.cardAddedBrand": "visa",
10
+ "cvcResult": "1 Matches",
11
+ "cvcResultRaw": "M",
12
+ "expiryDate": "03/2030",
13
+ "hmacSignature": "CZErGCNQaSsxbaQfZaJlakqo7KPP+mIa8a+wx3yNs9A=",
14
+ "paymentMethod": "visa",
15
+ "refusalReasonRaw": "AUTHORISED",
16
+ "retry.attempt1.acquirer": "TestPmmAcquirer",
17
+ "retry.attempt1.acquirerAccount": "TestPmmAcquirerAccount",
18
+ "retry.attempt1.avsResultRaw": "5",
19
+ "retry.attempt1.rawResponse": "AUTHORISED",
20
+ "retry.attempt1.responseCode": "Approved",
21
+ "retry.attempt1.scaExemptionRequested": "lowValue",
22
+ "scaExemptionRequested": "lowValue"
23
+ },
24
+ "amount": {
25
+ "currency": "EUR",
26
+ "value": 1000
27
+ },
28
+ "eventCode": "AUTHORISATION",
29
+ "eventDate": "2023-01-10T13:42:29+01:00",
30
+ "merchantAccountCode": "AntoniStroinski",
31
+ "merchantReference": "\\:/\\/slashes are fun",
32
+ "operations": [
33
+ "CANCEL",
34
+ "CAPTURE",
35
+ "REFUND"
36
+ ],
37
+ "paymentMethod": "visa",
38
+ "pspReference": "ZVWN7D3WSMK2WN82",
39
+ "reason": "052095:1111:03/2030",
40
+ "success": "true"
41
+ }
@@ -28,12 +28,6 @@ RSpec.describe Adyen::Utils::HmacValidator do
28
28
  expect(data_to_sign).to eq '7914073381342284::TestMerchant:TestPayment-1407325143704:1130:EUR:AUTHORISATION:true'
29
29
  end
30
30
 
31
- it 'should get correct data with escaped characters' do
32
- notification_request_item['merchantAccountCode'] = 'Test:\\Merchant'
33
- data_to_sign = validator.data_to_sign(notification_request_item)
34
- expect(data_to_sign).to eq '7914073381342284::Test\\:\\Merchant:TestPayment-1407325143704:1130:EUR:AUTHORISATION:true'
35
- end
36
-
37
31
  it 'should encrypt properly' do
38
32
  encrypted = validator.calculate_notification_hmac(notification_request_item, key)
39
33
  expect(encrypted).to eq expected_sign
@@ -48,5 +42,25 @@ RSpec.describe Adyen::Utils::HmacValidator do
48
42
 
49
43
  expect(validator.valid_notification_hmac?(notification_request_item, key)).to be false
50
44
  end
45
+
46
+ it 'should validate backslashes correctly' do
47
+ webhook = JSON.parse(json_from_file("mocks/responses/Webhooks/backslash_notification.json"))
48
+ expect(validator.valid_notification_hmac?(webhook, '74F490DD33F7327BAECC88B2947C011FC02D014A473AAA33A8EC93E4DC069174')).to be true
49
+ end
50
+
51
+ it 'should validate colons correctly' do
52
+ webhook = JSON.parse(json_from_file("mocks/responses/Webhooks/colon_notification.json"))
53
+ expect(validator.valid_notification_hmac?(webhook, '74F490DD33F7327BAECC88B2947C011FC02D014A473AAA33A8EC93E4DC069174')).to be true
54
+ end
55
+
56
+ it 'should validate forward slashes correctly' do
57
+ webhook = JSON.parse(json_from_file("mocks/responses/Webhooks/forwardslash_notification.json"))
58
+ expect(validator.valid_notification_hmac?(webhook, '74F490DD33F7327BAECC88B2947C011FC02D014A473AAA33A8EC93E4DC069174')).to be true
59
+ end
60
+
61
+ it 'should validate mix of slashes and colon correctly' do
62
+ webhook = JSON.parse(json_from_file("mocks/responses/Webhooks/mixed_notification.json"))
63
+ expect(validator.valid_notification_hmac?(webhook, '74F490DD33F7327BAECC88B2947C011FC02D014A473AAA33A8EC93E4DC069174')).to be true
64
+ end
51
65
  end
52
66
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adyen-ruby-api-library
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.2.0
4
+ version: 6.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adyen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-17 00:00:00.000000000 Z
11
+ date: 2023-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -81,6 +81,7 @@ files:
81
81
  - ".github/ISSUE_TEMPLATE/feature_request.md"
82
82
  - ".github/PULL_REQUEST_TEMPLATE.md"
83
83
  - ".github/dependabot.yml"
84
+ - ".github/workflows/codeql.yml"
84
85
  - ".github/workflows/ruby.yml"
85
86
  - ".github/workflows/rubygems_release.yml"
86
87
  - ".gitignore"
@@ -256,6 +257,7 @@ files:
256
257
  - spec/mocks/responses/Checkout/psp_cancel.json
257
258
  - spec/mocks/responses/Checkout/refund.json
258
259
  - spec/mocks/responses/Checkout/sessions-success.json
260
+ - spec/mocks/responses/Checkout/stored_payment_methods.json
259
261
  - spec/mocks/responses/Checkout/update-payment-link.json
260
262
  - spec/mocks/responses/Checkout/verify.json
261
263
  - spec/mocks/responses/DataProtectionService/request_subject_erasure.json
@@ -303,6 +305,10 @@ files:
303
305
  - spec/mocks/responses/Terminal/assign_terminals.json
304
306
  - spec/mocks/responses/Terminal/find_terminal.json
305
307
  - spec/mocks/responses/Terminal/get_terminals_under_account.json
308
+ - spec/mocks/responses/Webhooks/backslash_notification.json
309
+ - spec/mocks/responses/Webhooks/colon_notification.json
310
+ - spec/mocks/responses/Webhooks/forwardslash_notification.json
311
+ - spec/mocks/responses/Webhooks/mixed_notification.json
306
312
  - spec/notification_spec.rb
307
313
  - spec/payments_spec.rb
308
314
  - spec/payouts_spec.rb
@@ -333,7 +339,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
333
339
  - !ruby/object:Gem::Version
334
340
  version: '0'
335
341
  requirements: []
336
- rubygems_version: 3.3.7
342
+ rubygems_version: 3.1.2
337
343
  signing_key:
338
344
  specification_version: 4
339
345
  summary: Official Adyen Ruby API Library