checkout_sdk 2.8.0 → 2.8.1
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/README.md +4 -0
- data/lib/checkout_sdk/api_client.rb +8 -4
- data/lib/checkout_sdk/checkout_utils.rb +77 -2
- data/lib/checkout_sdk/error.rb +28 -6
- data/lib/checkout_sdk/events/events_client.rb +1 -1
- data/lib/checkout_sdk/oauth_sdk_credentials.rb +18 -11
- data/lib/checkout_sdk/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9849ed54d294ed9bea5fdb04bb5378fb55b942a2adb0ffe0653cb5c628cc0882
|
|
4
|
+
data.tar.gz: 7bd35374ce13e3feb72eb37a16930316ab6a01ce2cc10c49245f3e5a2daf6229
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b6f8c31a1c66aecb8b8fad6345a2b693f133b8bee59376920445caa7779db02a3f18882170318870c5f86fb728d898a4baffc32a0b71159d8b1fa4e17087c144
|
|
7
|
+
data.tar.gz: 6bdaf1a3c38c96bcafe0f52135ff77edda7a51d66946df1bc7d4b4d8e9e5729bf85f017e0a3a755567466e9132b4464428b7861ee58e56040fbf74294bc97598
|
data/README.md
CHANGED
|
@@ -172,6 +172,10 @@ api = CheckoutSdk.builder
|
|
|
172
172
|
.build
|
|
173
173
|
```
|
|
174
174
|
|
|
175
|
+
If your connection uses the `raise_error` middleware, configure it as the default client does:
|
|
176
|
+
`conn.response :raise_error, include_request: false` (the option needs Faraday 2.7.11 or later;
|
|
177
|
+
the SDK leaves the request data out of the errors it raises in any case).
|
|
178
|
+
|
|
175
179
|
You don't need to specify the URL for Faraday constructor the SDK grabs the belong URI from `CheckoutSdk::Environment`
|
|
176
180
|
however if you want to
|
|
177
181
|
use specific URI's without a proxy you can create the `Environment` object as follows.
|
|
@@ -52,10 +52,12 @@ module CheckoutSdk
|
|
|
52
52
|
json_body = CheckoutSdk::JsonSerializer.to_custom_hash(body).to_json
|
|
53
53
|
|
|
54
54
|
begin
|
|
55
|
-
@log.info "#{method}: /#{path}"
|
|
55
|
+
@log.info "#{method}: /#{CheckoutUtils.loggable_path(path)}"
|
|
56
56
|
response = @client.run_request(method, path, json_body, headers)
|
|
57
57
|
rescue Faraday::ClientError => e
|
|
58
|
-
raise CheckoutApiException
|
|
58
|
+
raise CheckoutApiException.new(e.response), cause: nil
|
|
59
|
+
rescue Faraday::Error => e
|
|
60
|
+
raise CheckoutUtils.without_request_data(e), cause: nil
|
|
59
61
|
end
|
|
60
62
|
|
|
61
63
|
parse_response(response)
|
|
@@ -140,10 +142,12 @@ module CheckoutSdk
|
|
|
140
142
|
form = build_multipart_request(file_request, file)
|
|
141
143
|
|
|
142
144
|
begin
|
|
143
|
-
@log.info "post: /#{path}"
|
|
145
|
+
@log.info "post: /#{CheckoutUtils.loggable_path(path)}"
|
|
144
146
|
response = @multipart_client.run_request(:post, path, form, headers)
|
|
145
147
|
rescue Faraday::ClientError => e
|
|
146
|
-
raise CheckoutApiException
|
|
148
|
+
raise CheckoutApiException.new(e.response), cause: nil
|
|
149
|
+
rescue Faraday::Error => e
|
|
150
|
+
raise CheckoutUtils.without_request_data(e), cause: nil
|
|
147
151
|
end
|
|
148
152
|
|
|
149
153
|
parse_response(response)
|
|
@@ -21,11 +21,86 @@ module CheckoutSdk
|
|
|
21
21
|
http_metadata
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
MAX_MESSAGE_DETAILS_LENGTH = 256
|
|
25
|
+
private_constant :MAX_MESSAGE_DETAILS_LENGTH
|
|
26
|
+
|
|
27
|
+
# Returns the request path in a form safe for a single log line: the query string is left out
|
|
28
|
+
# and control characters are escaped.
|
|
29
|
+
#
|
|
30
|
+
# @param [String, nil] path
|
|
31
|
+
# @return [String]
|
|
32
|
+
def self.loggable_path(path)
|
|
33
|
+
escape_control_characters(utf8_text(path).split('?', 2).first.to_s)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Builds an exception message from a prefix and a response body. A JSON object body adds its
|
|
37
|
+
# "key: value" pairs as details; any other non-empty body is added as is only when
|
|
38
|
+
# include_text_body is true. Details are shortened and their control characters escaped.
|
|
39
|
+
#
|
|
40
|
+
# @param [String] prefix
|
|
41
|
+
# @param [String, nil] body
|
|
42
|
+
# @param [Boolean] include_text_body
|
|
43
|
+
# @return [String]
|
|
44
|
+
def self.error_message(prefix, body, include_text_body: false)
|
|
45
|
+
text = utf8_text(body).strip
|
|
46
|
+
parsed = json_object(text)
|
|
47
|
+
details = parsed&.map { |key, value| "#{key}: #{value}" }&.join(', ')
|
|
48
|
+
details = text if details.nil? && include_text_body
|
|
49
|
+
return prefix if details.nil? || details.empty?
|
|
50
|
+
|
|
51
|
+
details = "#{details[0, MAX_MESSAGE_DETAILS_LENGTH]}..." if details.length > MAX_MESSAGE_DETAILS_LENGTH
|
|
52
|
+
"#{prefix} Details: #{escape_control_characters(details)}."
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Returns a copy of the Faraday error, of the same class and with the same backtrace and wrapped
|
|
56
|
+
# exception, that keeps only the response status, headers and body and whose message names the
|
|
57
|
+
# method and URL without the query string. Errors without a response are returned unchanged.
|
|
58
|
+
#
|
|
59
|
+
# @param [Faraday::Error] error
|
|
60
|
+
# @return [Faraday::Error]
|
|
61
|
+
def self.without_request_data(error)
|
|
62
|
+
return error if error.response.nil?
|
|
63
|
+
|
|
64
|
+
metadata = map_to_http_metadata(error.response)
|
|
65
|
+
rebuilt = error.exception(response_error_message(metadata.status_code, error.response))
|
|
66
|
+
rebuilt.instance_variable_set(:@response,
|
|
67
|
+
{ status: metadata.status_code, headers: metadata.headers, body: metadata.body })
|
|
68
|
+
rebuilt
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def self.response_error_message(status, response)
|
|
72
|
+
message = "the server responded with status #{status}"
|
|
73
|
+
request = response.is_a?(Hash) ? response[:request] : nil
|
|
74
|
+
return message unless request.is_a?(Hash) && request[:url]
|
|
75
|
+
|
|
76
|
+
"#{message} for #{request[:method].to_s.upcase} #{loggable_path(request[:url].to_s)}"
|
|
77
|
+
end
|
|
78
|
+
private_class_method :response_error_message
|
|
79
|
+
|
|
80
|
+
def self.json_object(text)
|
|
81
|
+
parsed = JSON.parse(text)
|
|
82
|
+
parsed.is_a?(Hash) ? parsed : nil
|
|
83
|
+
rescue JSON::ParserError
|
|
84
|
+
nil
|
|
85
|
+
end
|
|
86
|
+
private_class_method :json_object
|
|
87
|
+
|
|
88
|
+
# Escapes control characters and Unicode line and paragraph separators in UTF-8 text.
|
|
89
|
+
def self.escape_control_characters(text)
|
|
90
|
+
text.gsub(/[[:cntrl:]\p{Zl}\p{Zp}]/) { |char| char.dump[1..-2] }
|
|
91
|
+
end
|
|
92
|
+
private_class_method :escape_control_characters
|
|
93
|
+
|
|
94
|
+
def self.utf8_text(text)
|
|
95
|
+
text.to_s.dup.force_encoding(Encoding::UTF_8).scrub
|
|
96
|
+
end
|
|
97
|
+
private_class_method :utf8_text
|
|
98
|
+
|
|
24
99
|
# @return [Faraday::Connection]
|
|
25
100
|
def self.build_multipart_client
|
|
26
101
|
Faraday.new do |f|
|
|
27
102
|
f.request :multipart
|
|
28
|
-
f.response :raise_error
|
|
103
|
+
f.response :raise_error, include_request: false
|
|
29
104
|
end
|
|
30
105
|
end
|
|
31
106
|
|
|
@@ -33,7 +108,7 @@ module CheckoutSdk
|
|
|
33
108
|
def self.build_default_client
|
|
34
109
|
Faraday.new do |f|
|
|
35
110
|
f.response :follow_redirects
|
|
36
|
-
f.response :raise_error
|
|
111
|
+
f.response :raise_error, include_request: false
|
|
37
112
|
end
|
|
38
113
|
end
|
|
39
114
|
end
|
data/lib/checkout_sdk/error.rb
CHANGED
|
@@ -6,6 +6,16 @@ module CheckoutSdk
|
|
|
6
6
|
class CheckoutArgumentException < CheckoutException; end
|
|
7
7
|
|
|
8
8
|
class CheckoutAuthorizationException < CheckoutException
|
|
9
|
+
# @return [CheckoutSdk::HttpMetadata, nil] response status, headers and body when raised for an OAuth token response
|
|
10
|
+
attr_reader :http_metadata
|
|
11
|
+
|
|
12
|
+
# @param [String, nil] message
|
|
13
|
+
# @param [CheckoutSdk::HttpMetadata, nil] http_metadata
|
|
14
|
+
def initialize(message = nil, http_metadata = nil)
|
|
15
|
+
@http_metadata = http_metadata
|
|
16
|
+
super(message)
|
|
17
|
+
end
|
|
18
|
+
|
|
9
19
|
def self.invalid_authorization(authorization_type)
|
|
10
20
|
new("Operation requires #{authorization_type} authorization type.")
|
|
11
21
|
end
|
|
@@ -13,6 +23,22 @@ module CheckoutSdk
|
|
|
13
23
|
def self.invalid_key(key_type)
|
|
14
24
|
new("#{key_type} is required for this operation.")
|
|
15
25
|
end
|
|
26
|
+
|
|
27
|
+
# Builds the error for an unsuccessful OAuth token response from the response data only.
|
|
28
|
+
#
|
|
29
|
+
# @param [CheckoutSdk::HttpMetadata] http_metadata
|
|
30
|
+
# @return [CheckoutSdk::CheckoutAuthorizationException]
|
|
31
|
+
def self.token_request_failed(http_metadata)
|
|
32
|
+
prefix = "The OAuth token response status code (#{http_metadata.status_code}) does not indicate success."
|
|
33
|
+
new(CheckoutUtils.error_message(prefix, http_metadata.body, include_text_body: true), http_metadata)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Builds the error for an OAuth token request that failed without a response.
|
|
37
|
+
#
|
|
38
|
+
# @return [CheckoutSdk::CheckoutAuthorizationException]
|
|
39
|
+
def self.token_request_without_response
|
|
40
|
+
new('The OAuth token request failed without a response.')
|
|
41
|
+
end
|
|
16
42
|
end
|
|
17
43
|
|
|
18
44
|
class CheckoutApiException < CheckoutException
|
|
@@ -35,12 +61,8 @@ module CheckoutSdk
|
|
|
35
61
|
end
|
|
36
62
|
|
|
37
63
|
def build_error_message
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
details = @error_details.to_h.map { |key, value| "#{key}: #{value}" }.join(', ')
|
|
41
|
-
message += " Details: #{details}."
|
|
42
|
-
end
|
|
43
|
-
message
|
|
64
|
+
prefix = "The API response status code (#{http_metadata.status_code}) does not indicate success."
|
|
65
|
+
CheckoutUtils.error_message(prefix, http_metadata.body)
|
|
44
66
|
end
|
|
45
67
|
end
|
|
46
68
|
end
|
|
@@ -20,7 +20,7 @@ module CheckoutSdk
|
|
|
20
20
|
|
|
21
21
|
# @param [String,nil] version
|
|
22
22
|
def retrieve_all_event_types(version = nil)
|
|
23
|
-
query =
|
|
23
|
+
query = URI.encode_www_form(version: version) unless version.nil?
|
|
24
24
|
api_client.invoke_get(EVENT_TYPES, sdk_authorization, query)
|
|
25
25
|
end
|
|
26
26
|
|
|
@@ -65,17 +65,7 @@ module CheckoutSdk
|
|
|
65
65
|
scope: @scopes.join(' ')
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
body = URI.encode_www_form data
|
|
70
|
-
|
|
71
|
-
begin
|
|
72
|
-
@log.info "post: #{authorization_uri}"
|
|
73
|
-
response = @oauth_http_client.run_request(:post, @authorization_uri, body, headers)
|
|
74
|
-
rescue Faraday::ClientError => e
|
|
75
|
-
raise CheckoutAuthorizationException, e.response
|
|
76
|
-
rescue Faraday::ConnectionFailed => e
|
|
77
|
-
raise CheckoutArgumentException, e.wrapped_exception
|
|
78
|
-
end
|
|
68
|
+
response = request_access_token(URI.encode_www_form(data))
|
|
79
69
|
|
|
80
70
|
if !response.body.nil? && response.body != ''
|
|
81
71
|
oauth_response = JSON.parse(response.body, object_class: OpenStruct)
|
|
@@ -90,6 +80,23 @@ module CheckoutSdk
|
|
|
90
80
|
|
|
91
81
|
private
|
|
92
82
|
|
|
83
|
+
# @param [String] body
|
|
84
|
+
# @return [Faraday::Response]
|
|
85
|
+
def request_access_token(body)
|
|
86
|
+
headers = { 'Content-Type': 'application/x-www-form-urlencoded' }
|
|
87
|
+
@log.info "post: #{CheckoutUtils.loggable_path(authorization_uri)}"
|
|
88
|
+
@oauth_http_client.run_request(:post, @authorization_uri, body, headers)
|
|
89
|
+
rescue Faraday::ClientError => e
|
|
90
|
+
raise CheckoutAuthorizationException.token_request_without_response if e.response.nil?
|
|
91
|
+
|
|
92
|
+
raise CheckoutAuthorizationException.token_request_failed(CheckoutUtils.map_to_http_metadata(e.response)),
|
|
93
|
+
cause: nil
|
|
94
|
+
rescue Faraday::ConnectionFailed => e
|
|
95
|
+
raise CheckoutArgumentException, e.wrapped_exception
|
|
96
|
+
rescue Faraday::Error => e
|
|
97
|
+
raise CheckoutUtils.without_request_data(e), cause: nil
|
|
98
|
+
end
|
|
99
|
+
|
|
93
100
|
# @param [String] client_id
|
|
94
101
|
# @param [String] client_secret
|
|
95
102
|
# @param [Environment] environment
|
data/lib/checkout_sdk/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: checkout_sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.8.
|
|
4
|
+
version: 2.8.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Checkout
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-11-
|
|
11
|
+
date: 2026-11-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rake
|
|
@@ -66,6 +66,20 @@ dependencies:
|
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: '0.60'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: csv
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '3.0'
|
|
76
|
+
type: :runtime
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '3.0'
|
|
69
83
|
- !ruby/object:Gem::Dependency
|
|
70
84
|
name: faraday
|
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|