adyen-ruby-api-library 6.2.0 → 6.3.0

Sign up to get free protection for your applications and to get access to all the features.
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