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 +4 -4
- data/.github/CODEOWNERS +1 -1
- data/.github/workflows/codeql.yml +41 -0
- data/.github/workflows/ruby.yml +1 -1
- data/.github/workflows/rubygems_release.yml +1 -1
- data/lib/adyen/client.rb +16 -4
- data/lib/adyen/errors.rb +2 -2
- data/lib/adyen/services/checkout.rb +43 -11
- data/lib/adyen/services/service.rb +5 -0
- data/lib/adyen/utils/hmac_validator.rb +2 -3
- data/lib/adyen/version.rb +2 -2
- data/spec/checkout_spec.rb +50 -0
- data/spec/client_spec.rb +1 -1
- data/spec/errors_spec.rb +1 -1
- data/spec/mocks/responses/Checkout/stored_payment_methods.json +1 -0
- data/spec/mocks/responses/Webhooks/backslash_notification.json +41 -0
- data/spec/mocks/responses/Webhooks/colon_notification.json +41 -0
- data/spec/mocks/responses/Webhooks/forwardslash_notification.json +41 -0
- data/spec/mocks/responses/Webhooks/mixed_notification.json +41 -0
- data/spec/utils/hmac_validator_spec.rb +20 -6
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 45627b45fc5df26d004c1a86d7640412d615383ccac35201f24f0e3ebed99394
|
4
|
+
data.tar.gz: 72a067ba4b95419ed87e526a371db2377d5b1af7056f9ac035a6e11327715da0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a893d921b3236805bb89b6ca5fc1c553888d010c84c1927689f6bc47e1a78b23302c081edbc979d596ac70c0b6f23cad61b9a83cc11c6f8b22e1d73520951bdb
|
7
|
+
data.tar.gz: 3cc14ff3d1550ffb11f6ec08c37ae7858b5e39e1b14023e6323e3a132441b59ee383e39ca6db6dcb83eff24e4b9ae937bff416bc9684e1ba6cb8ba7b20e37405
|
data/.github/CODEOWNERS
CHANGED
@@ -1 +1 @@
|
|
1
|
-
* @
|
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 }}"
|
data/.github/workflows/ruby.yml
CHANGED
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
|
-
|
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
@@ -2,7 +2,7 @@ require_relative "service"
|
|
2
2
|
|
3
3
|
module Adyen
|
4
4
|
class Checkout < Service
|
5
|
-
DEFAULT_VERSION =
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
@@ -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
data/spec/checkout_spec.rb
CHANGED
@@ -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/
|
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.
|
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:
|
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.
|
342
|
+
rubygems_version: 3.1.2
|
337
343
|
signing_key:
|
338
344
|
specification_version: 4
|
339
345
|
summary: Official Adyen Ruby API Library
|