synapse_fi 0.0.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 +7 -0
- data/.DS_Store +0 -0
- data/.env.sample +9 -0
- data/.gitignore +3 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +43 -0
- data/README.md +39 -0
- data/lib/synapse_api/.DS_Store +0 -0
- data/lib/synapse_api/client.rb +355 -0
- data/lib/synapse_api/error.rb +138 -0
- data/lib/synapse_api/http_request.rb +228 -0
- data/lib/synapse_api/node.rb +19 -0
- data/lib/synapse_api/nodes.rb +19 -0
- data/lib/synapse_api/subnet.rb +13 -0
- data/lib/synapse_api/subnets.rb +16 -0
- data/lib/synapse_api/subscription.rb +15 -0
- data/lib/synapse_api/subscriptions.rb +17 -0
- data/lib/synapse_api/transaction.rb +21 -0
- data/lib/synapse_api/transactions.rb +19 -0
- data/lib/synapse_api/user.rb +734 -0
- data/lib/synapse_api/users.rb +19 -0
- data/lib/synapse_api/version.rb +6 -0
- data/node_modules/.yarn-integrity +16 -0
- data/node_modules/dotenv/CHANGELOG.md +117 -0
- data/node_modules/dotenv/LICENSE +23 -0
- data/node_modules/dotenv/README.md +295 -0
- data/node_modules/dotenv/config.js +11 -0
- data/node_modules/dotenv/lib/cli-options.js +13 -0
- data/node_modules/dotenv/lib/env-options.js +18 -0
- data/node_modules/dotenv/lib/main.js +103 -0
- data/node_modules/dotenv/package.json +45 -0
- data/package.json +5 -0
- data/samples.md +455 -0
- data/synapse_fi-0.0.0.gem +0 -0
- data/synapse_fi.gemspec +89 -0
- data/yarn.lock +8 -0
- metadata +148 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6e6933e283961c5db4a8f009d272a7aa74e501c3
|
4
|
+
data.tar.gz: 79d68318e948ea23958fe7ea0000ee9503038e54
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4d5d0707a08845b5c7469300982035c6b441eabfc5b01645cc8dc457a5264567c09a2340847e72e6ebad884c37c0842250c90ba886be3b0f3bda89533d011260
|
7
|
+
data.tar.gz: 2931dd52da4c6375de02b4b5b6bd54b0e12b38326525f793db6d105479df8b43088bbd3b49243709116810d208ffb6c414d2710d1b5bf149f772fae6c9e388c8
|
data/.DS_Store
ADDED
Binary file
|
data/.env.sample
ADDED
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
ansi (1.5.0)
|
5
|
+
builder (3.2.3)
|
6
|
+
domain_name (0.5.20180417)
|
7
|
+
unf (>= 0.0.5, < 1.0.0)
|
8
|
+
dotenv (2.5.0)
|
9
|
+
http-cookie (1.0.3)
|
10
|
+
domain_name (~> 0.5)
|
11
|
+
mime-types (3.2.2)
|
12
|
+
mime-types-data (~> 3.2015)
|
13
|
+
mime-types-data (3.2018.0812)
|
14
|
+
minitest (5.11.3)
|
15
|
+
minitest-reporters (1.3.5)
|
16
|
+
ansi
|
17
|
+
builder
|
18
|
+
minitest (>= 5.0)
|
19
|
+
ruby-progressbar
|
20
|
+
netrc (0.11.0)
|
21
|
+
rest-client (2.0.2)
|
22
|
+
http-cookie (>= 1.0.2, < 2.0)
|
23
|
+
mime-types (>= 1.16, < 4.0)
|
24
|
+
netrc (~> 0.8)
|
25
|
+
ruby-progressbar (1.10.0)
|
26
|
+
synapse_pay_rest (3.4.3)
|
27
|
+
rest-client (~> 2.0)
|
28
|
+
unf (0.1.4)
|
29
|
+
unf_ext
|
30
|
+
unf_ext (0.0.7.5)
|
31
|
+
|
32
|
+
PLATFORMS
|
33
|
+
ruby
|
34
|
+
|
35
|
+
DEPENDENCIES
|
36
|
+
bundler
|
37
|
+
dotenv
|
38
|
+
minitest
|
39
|
+
minitest-reporters
|
40
|
+
synapse_pay_rest
|
41
|
+
|
42
|
+
BUNDLED WITH
|
43
|
+
1.17.1
|
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# SynapseFI-Ruby-v2
|
2
|
+
|
3
|
+
Native API library for SynapsePay REST v3.x
|
4
|
+
|
5
|
+
Not all API endpoints are supported.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'synapse_fi'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
```bash
|
18
|
+
$ bundle
|
19
|
+
```
|
20
|
+
|
21
|
+
Or install it yourself by executing:
|
22
|
+
|
23
|
+
```bash
|
24
|
+
$ gem install synapse_fi
|
25
|
+
```
|
26
|
+
## Documentation
|
27
|
+
|
28
|
+
- [API docs](http://docs.synapsefi.com/v3.1)
|
29
|
+
- [Samples demonstrating common operations](samples.md)
|
30
|
+
|
31
|
+
## Contributing
|
32
|
+
|
33
|
+
For minor issues, please open a pull request. For larger changes or features, please email hello@synapsepay.com. Please document and test any public constants/methods.
|
34
|
+
|
35
|
+
## License
|
36
|
+
|
37
|
+
[MIT License](LICENSE)
|
38
|
+
|
39
|
+
|
Binary file
|
@@ -0,0 +1,355 @@
|
|
1
|
+
require 'json'
|
2
|
+
require_relative './http_request'
|
3
|
+
require_relative './user'
|
4
|
+
require_relative './users'
|
5
|
+
require_relative './transaction'
|
6
|
+
require_relative './transactions'
|
7
|
+
require_relative './node'
|
8
|
+
require_relative './nodes'
|
9
|
+
require_relative './subscription'
|
10
|
+
require_relative './subscriptions'
|
11
|
+
require_relative './subnet'
|
12
|
+
require_relative './subnets'
|
13
|
+
require 'pp'
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
module Synapse
|
18
|
+
# Initializes various wrapper settings such as development mode and request
|
19
|
+
# header values
|
20
|
+
|
21
|
+
class Client
|
22
|
+
|
23
|
+
VALID_QUERY_PARAMS = [:query, :page, :per_page, :full_dehydrate, :radius, :zip, :lat, :lon, :limit, :currency].freeze
|
24
|
+
|
25
|
+
attr_accessor :http_client
|
26
|
+
|
27
|
+
attr_reader :client_id
|
28
|
+
|
29
|
+
# Alias for #http_client
|
30
|
+
alias_method :client, :http_client
|
31
|
+
|
32
|
+
|
33
|
+
# @param client_id [String] should be stored in environment variable
|
34
|
+
# @param client_secret [String] should be stored in environment variable
|
35
|
+
# @param ip_address [String] user's IP address
|
36
|
+
# @param fingerprint [String] a hashed value, either unique to user or static
|
37
|
+
# @param development_mode [String] default true
|
38
|
+
# @param raise_for_202 [Boolean]
|
39
|
+
# @param logging [Boolean] (optional) logs to stdout when true
|
40
|
+
# @param log_to [String] (optional) file path to log to file (logging must be true)
|
41
|
+
def initialize(client_id:, client_secret:, ip_address:, fingerprint:nil,development_mode: true, raise_for_202:nil, **options)
|
42
|
+
base_url = if development_mode
|
43
|
+
'https://uat-api.synapsefi.com/v3.1'
|
44
|
+
else
|
45
|
+
'https://api.synapsefi.com/v3.1'
|
46
|
+
end
|
47
|
+
@client_id = client_id
|
48
|
+
@client_secret = client_secret
|
49
|
+
@http_client = HTTPClient.new(base_url: base_url,
|
50
|
+
client_id: client_id,
|
51
|
+
client_secret: client_secret,
|
52
|
+
fingerprint: fingerprint,
|
53
|
+
ip_address: ip_address,
|
54
|
+
raise_for_202: raise_for_202,
|
55
|
+
**options)
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
# Queries Synapse API to create a new user
|
60
|
+
# @param payload [Hash]
|
61
|
+
# @param idempotency_key [String] (optional)
|
62
|
+
# @return[Synapse::User]
|
63
|
+
# @see https://docs.synapsepay.com/docs/create-a-user payload structure
|
64
|
+
def create_user(payload:, **options)
|
65
|
+
raise ArgumentError, 'client must be a Synapse::Client' unless self.is_a?(Client)
|
66
|
+
response = client.post(user_path,payload, options)
|
67
|
+
|
68
|
+
|
69
|
+
user = User.new(
|
70
|
+
user_id: response['_id'],
|
71
|
+
refresh_token: response['refresh_token'],
|
72
|
+
client: client,
|
73
|
+
full_dehydrate: "no",
|
74
|
+
payload: response
|
75
|
+
)
|
76
|
+
user
|
77
|
+
end
|
78
|
+
|
79
|
+
# Update headers in HTTPClient class
|
80
|
+
# for API request headers
|
81
|
+
# @param fingerprint [Hash]
|
82
|
+
# @param idemopotency_key [Hash]
|
83
|
+
# @param ip_address [Hash]
|
84
|
+
def update_headers(fingerprint:nil, idemopotency_key:nil, ip_address:nil)
|
85
|
+
client.update_headers(fingerprint: fingerprint, idemopotency_key: idemopotency_key, ip_address: ip_address)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Queries Synapse API for a user by user_id
|
89
|
+
# @param user_id [String] id of the user to find
|
90
|
+
# @param full_dehydrate [String] (optional) if true, returns all KYC on user
|
91
|
+
# @see https://docs.synapsefi.com/docs/get-user
|
92
|
+
# @return [Synapse::User]
|
93
|
+
def get_user(user_id:, **options)
|
94
|
+
raise ArgumentError, 'client must be a Synapse::Client' unless self.is_a?(Client)
|
95
|
+
raise ArgumentError, 'user_id must be a String' unless user_id.is_a?(String)
|
96
|
+
|
97
|
+
options[:full_dehydrate] = "yes" if options[:full_dehydrate] == true
|
98
|
+
options[:full_dehydrate] = "no" if options[:full_dehydrate] == false
|
99
|
+
|
100
|
+
path = user_path(user_id: user_id, full_dehydrate: options[:full_dehydrate])
|
101
|
+
response = client.get(path)
|
102
|
+
|
103
|
+
user = User.new(
|
104
|
+
user_id: response['_id'],
|
105
|
+
refresh_token: response['refresh_token'],
|
106
|
+
client: client,
|
107
|
+
full_dehydrate: options[:full_dehydrate] == "yes" ? true : false,
|
108
|
+
payload: response
|
109
|
+
)
|
110
|
+
user
|
111
|
+
end
|
112
|
+
|
113
|
+
# Queries Synapse API for platform users
|
114
|
+
# @param query [String] (optional) response will be filtered to
|
115
|
+
# users with matching name/email
|
116
|
+
# @param page [Integer] (optional) response will default to 1
|
117
|
+
# @param per_page [Integer] (optional) response will default to 20
|
118
|
+
# @note users created this way are not automatically OAuthed
|
119
|
+
# @return [Array<Synapse::Users>]
|
120
|
+
def get_users(**options)
|
121
|
+
path = user_path(options)
|
122
|
+
response = client.get(path)
|
123
|
+
return [] if response["users"].empty?
|
124
|
+
users = response["users"].map { |user_data| User.new(user_id: user_data['_id'], refresh_token: user_data['refresh_token'], client: client, full_dehydrate: "no", payload: user_data)}
|
125
|
+
users = Users.new(limit: response["limit"], page: response["page"], page_count: response["page_count"], user_count: response["user_count"], payload: users, http_client: client)
|
126
|
+
|
127
|
+
users
|
128
|
+
end
|
129
|
+
|
130
|
+
# Queries Synapse for all transactions on platform
|
131
|
+
# @param page [Integer] (optional) response will default to 1
|
132
|
+
# @param per_page [Integer] (optional) response will default to 20
|
133
|
+
# @return [Array<Synapse::Transactions>]
|
134
|
+
def get_all_transaction(**options)
|
135
|
+
path = '/trans'
|
136
|
+
|
137
|
+
params = VALID_QUERY_PARAMS.map do |p|
|
138
|
+
options[p] ? "#{p}=#{options[p]}" : nil
|
139
|
+
end.compact
|
140
|
+
|
141
|
+
path += '?' + params.join('&') if params.any?
|
142
|
+
|
143
|
+
trans = client.get(path)
|
144
|
+
|
145
|
+
return [] if trans["trans"].empty?
|
146
|
+
response = trans["trans"].map { |trans_data| Transaction.new(trans_id: trans_data['_id'], payload: trans_data)}
|
147
|
+
trans = Transactions.new(limit: trans["limit"], page: trans["page"], page_count: trans["page_count"], trans_count: trans["trans_count"], payload: response)
|
148
|
+
trans
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
# Queries Synapse API for all nodes belonging to platform
|
153
|
+
# @param page [Integer] (optional) response will default to 1
|
154
|
+
# @param per_page [Integer] (optional) response will default to 20
|
155
|
+
# @return [Array<Synapse::Nodes>]
|
156
|
+
def get_all_nodes(**options)
|
157
|
+
[options[:page], options[:per_page]].each do |arg|
|
158
|
+
if arg && (!arg.is_a?(Integer) || arg < 1)
|
159
|
+
raise ArgumentError, "#{arg} must be nil or an Integer >= 1"
|
160
|
+
end
|
161
|
+
end
|
162
|
+
path = nodes_path(options: options)
|
163
|
+
nodes = client.get(path)
|
164
|
+
|
165
|
+
return [] if nodes["nodes"].empty?
|
166
|
+
response = nodes["nodes"].map { |node_data| Node.new(node_id: node_data['_id'], user_id: node_data['user_id'], payload: node_data, full_dehydrate: "no")}
|
167
|
+
nodes = Nodes.new(limit: nodes["limit"], page: nodes["page"], page_count: nodes["page_count"], nodes_count: nodes["node_count"], payload: response)
|
168
|
+
end
|
169
|
+
|
170
|
+
# Queries Synapse API for all institutions available for bank logins
|
171
|
+
# @param page [Integer] (optional) response will default to 1
|
172
|
+
# @param per_page [Integer] (optional) response will default to 20
|
173
|
+
# @return API response [Hash]
|
174
|
+
def get_all_institutions(**options)
|
175
|
+
client.get(institutions_path(options))
|
176
|
+
end
|
177
|
+
|
178
|
+
# Queries Synapse API to create a webhook subscriptions for platform
|
179
|
+
# @param scope [Array<String>]
|
180
|
+
# @param idempotency_key [String] (optional)
|
181
|
+
# @param url [String]
|
182
|
+
# @see https://docs.synapsefi.com/docs/create-subscription
|
183
|
+
# @return [Synapse::Subscription]
|
184
|
+
def create_subscriptions(scope:, url:, **options)
|
185
|
+
payload = {
|
186
|
+
'scope' => scope,
|
187
|
+
'url' => url,
|
188
|
+
}
|
189
|
+
|
190
|
+
response = client.post(subscriptions_path , payload, options)
|
191
|
+
|
192
|
+
subscriptions = Subscription.new(subscription_id: response["_id"], url: response["url"], payload: response)
|
193
|
+
end
|
194
|
+
|
195
|
+
# Queries Synapse API for all platform subscriptions
|
196
|
+
# @param page [Integer] (optional) response will default to 1
|
197
|
+
# @param per_page [Integer] (optional) response will default to 20
|
198
|
+
# @return [Array<Synapse::Subscriptions>]
|
199
|
+
def get_all_subscriptions(**options)
|
200
|
+
subscriptions = client.get(subscriptions_path(options))
|
201
|
+
|
202
|
+
return [] if subscriptions["subscriptions"].empty?
|
203
|
+
response = subscriptions["subscriptions"].map { |subscription_data| Subscription.new(subscription_id: subscription_data["_id"], url: subscription_data["url"], payload: subscription_data)}
|
204
|
+
subscriptions = Subscriptions.new(limit: subscriptions["limit"], page: subscriptions["page"], page_count: subscriptions["page_count"], subscriptions_count: subscriptions["subscription_count"], payload: response)
|
205
|
+
end
|
206
|
+
|
207
|
+
|
208
|
+
# Queries Synapse API for a subscription by subscription_id
|
209
|
+
# @param subscription_id [String]
|
210
|
+
# @return [Synapse::Subscription]
|
211
|
+
def get_subscription(subscription_id:)
|
212
|
+
path = subscriptions_path + "/#{subscription_id}"
|
213
|
+
response = client.get(path)
|
214
|
+
subscription = Subscription.new(subscription_id: response["_id"], url: response["url"], payload: response)
|
215
|
+
end
|
216
|
+
|
217
|
+
# updates subscription platform subscription
|
218
|
+
# @param subscription_id [String]
|
219
|
+
# @param is_active [boolean]
|
220
|
+
# @param url [String]
|
221
|
+
# @param scope [Array<String>]
|
222
|
+
# see https://docs.synapsefi.com/docs/update-subscription
|
223
|
+
# @return [Synapse::Subscription]
|
224
|
+
def update_subscriptions(subscription_id:, url:nil, scope:nil, is_active:nil)
|
225
|
+
path = subscriptions_path + "/#{subscription_id}"
|
226
|
+
|
227
|
+
payload = {}
|
228
|
+
|
229
|
+
payload["url"] = url if url
|
230
|
+
payload["scope"] = scope if scope
|
231
|
+
payload["is_active"] = is_active if is_active
|
232
|
+
|
233
|
+
response = client.patch(path, payload)
|
234
|
+
subscriptions = Subscription.new(subscription_id: response["_id"], url: response["url"], payload: response)
|
235
|
+
end
|
236
|
+
|
237
|
+
|
238
|
+
# Issues public key for client
|
239
|
+
# @param client [Synapse::Client]
|
240
|
+
# @param scope [String]
|
241
|
+
# @see https://docs.synapsefi.com/docs/issuing-public-key
|
242
|
+
# @note valid scope "OAUTH|POST,USERS|POST,USERS|GET,USER|GET,USER|PATCH,SUBSCRIPTIONS|GET,SUBSCRIPTIONS|POST,SUBSCRIPTION|GET,SUBSCRIPTION|PATCH,CLIENT|REPORTS,CLIENT|CONTROLS"
|
243
|
+
def issue_public_key(scope:)
|
244
|
+
raise ArgumentError, 'scope must be a string' unless scope.is_a?(String)
|
245
|
+
path = '/client?issue_public_key=YES'
|
246
|
+
path += "&scope=#{scope}"
|
247
|
+
response = client.get(path)
|
248
|
+
response[ "public_key_obj"]
|
249
|
+
end
|
250
|
+
|
251
|
+
# Queries Synapse API for ATMS nearby
|
252
|
+
# @param zip [String]
|
253
|
+
# @param radius [String]
|
254
|
+
# @param lat [String]
|
255
|
+
# @param lon [String]
|
256
|
+
# @see https://docs.synapsefi.com/docs/locate-atms
|
257
|
+
# @return [Hash]
|
258
|
+
def locate_atm(**options)
|
259
|
+
params = VALID_QUERY_PARAMS.map do |p|
|
260
|
+
options[p] ? "#{p}=#{options[p]}" : nil
|
261
|
+
end.compact
|
262
|
+
|
263
|
+
path = "/nodes/atms?"
|
264
|
+
path += params.join('&') if params.any?
|
265
|
+
atms = client.get(path)
|
266
|
+
atms
|
267
|
+
end
|
268
|
+
|
269
|
+
# Queries Synapse API for Crypto Currencies Quotes
|
270
|
+
# @return API response [Hash]
|
271
|
+
def get_crypto_quotes()
|
272
|
+
path = '/nodes/crypto-quotes'
|
273
|
+
params = VALID_QUERY_PARAMS.map do |p|
|
274
|
+
options[p] ? "#{p}=#{options[p]}" : nil
|
275
|
+
end.compact
|
276
|
+
|
277
|
+
path += '?' + params.join('&') if params.any?
|
278
|
+
quotes = client.get(path)
|
279
|
+
quotes
|
280
|
+
end
|
281
|
+
|
282
|
+
# Queries Synapse API for Crypto Currencies Market data
|
283
|
+
# @param limit [Integer]
|
284
|
+
# @param currency [String]
|
285
|
+
# @return API response [Hash]
|
286
|
+
def get_crypto_market_data(**options)
|
287
|
+
path = '/nodes/crypto-market-watch'
|
288
|
+
|
289
|
+
params = VALID_QUERY_PARAMS.map do |p|
|
290
|
+
options[p] ? "#{p}=#{options[p]}" : nil
|
291
|
+
end.compact
|
292
|
+
|
293
|
+
path += '?' + params.join('&') if params.any?
|
294
|
+
|
295
|
+
data = client.get(path)
|
296
|
+
data
|
297
|
+
end
|
298
|
+
|
299
|
+
|
300
|
+
private
|
301
|
+
|
302
|
+
def user_path(user_id: nil, **options)
|
303
|
+
path = "/users"
|
304
|
+
path += "/#{user_id}" if user_id
|
305
|
+
|
306
|
+
params = VALID_QUERY_PARAMS.map do |p|
|
307
|
+
options[p] ? "#{p}=#{options[p]}" : nil
|
308
|
+
end.compact
|
309
|
+
|
310
|
+
path += '?' + params.join('&') if params.any?
|
311
|
+
path
|
312
|
+
end
|
313
|
+
|
314
|
+
def transactions_path(user_id: nil, node_id: nil, **options)
|
315
|
+
path = "/users/#{user_id}/trans"
|
316
|
+
params = VALID_QUERY_PARAMS.map do |p|
|
317
|
+
options[p] ? "#{p}=#{options[p]}" : nil
|
318
|
+
end.compact
|
319
|
+
|
320
|
+
path += '?' + params.join('&') if params.any?
|
321
|
+
path
|
322
|
+
end
|
323
|
+
|
324
|
+
def nodes_path(**options)
|
325
|
+
path = "/nodes"
|
326
|
+
params = VALID_QUERY_PARAMS.map do |p|
|
327
|
+
options[p] ? "#{p}=#{options[p]}" : nil
|
328
|
+
end.compact
|
329
|
+
|
330
|
+
path += '?' + params.join('&') if params.any?
|
331
|
+
path
|
332
|
+
end
|
333
|
+
|
334
|
+
def institutions_path(**options)
|
335
|
+
path = "/institutions"
|
336
|
+
params = VALID_QUERY_PARAMS.map do |p|
|
337
|
+
options[p] ? "#{p}=#{options[p]}" : nil
|
338
|
+
end.compact
|
339
|
+
|
340
|
+
path += '?' + params.join('&') if params.any?
|
341
|
+
path
|
342
|
+
end
|
343
|
+
|
344
|
+
def subscriptions_path(**options)
|
345
|
+
path = "/subscriptions"
|
346
|
+
params = VALID_QUERY_PARAMS.map do |p|
|
347
|
+
options[p] ? "#{p}=#{options[p]}" : nil
|
348
|
+
end.compact
|
349
|
+
|
350
|
+
path += '?' + params.join('&') if params.any?
|
351
|
+
path
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
@@ -0,0 +1,138 @@
|
|
1
|
+
module Synapse
|
2
|
+
# Custom class for handling HTTP and API errors.
|
3
|
+
class Error < StandardError
|
4
|
+
# Raised on a 4xx HTTP status code
|
5
|
+
ClientError = Class.new(self)
|
6
|
+
|
7
|
+
# Raised on the HTTP status code 202
|
8
|
+
Accepted = Class.new(ClientError)
|
9
|
+
|
10
|
+
# Raised on the HTTP status code 400
|
11
|
+
BadRequest = Class.new(ClientError)
|
12
|
+
|
13
|
+
# Raised on the HTTP status code 401
|
14
|
+
Unauthorized = Class.new(ClientError)
|
15
|
+
|
16
|
+
# Raised on the HTTP status code 402
|
17
|
+
RequestDeclined = Class.new(ClientError)
|
18
|
+
|
19
|
+
# Raised on the HTTP status code 403
|
20
|
+
# Forbidden = Class.new(ClientError)
|
21
|
+
# '403' => Synapse::Error::Forbidden,
|
22
|
+
|
23
|
+
# Raised on the HTTP status code 404
|
24
|
+
NotFound = Class.new(ClientError)
|
25
|
+
|
26
|
+
# Raised on the HTTP status code 406
|
27
|
+
# NotAcceptable = Class.new(ClientError)
|
28
|
+
# '406' => Synapse::Error::NotAcceptable,
|
29
|
+
|
30
|
+
# Raised on the HTTP status code 409
|
31
|
+
Conflict = Class.new(ClientError)
|
32
|
+
|
33
|
+
# Raised on the HTTP status code 415
|
34
|
+
# UnsupportedMediaType = Class.new(ClientError)
|
35
|
+
# '415' => Synapse::Error::UnsupportedMediaType,
|
36
|
+
|
37
|
+
# Raised on the HTTP status code 422
|
38
|
+
# UnprocessableEntity = Class.new(ClientError)
|
39
|
+
# '422' => Synapse::Error::UnprocessableEntity,
|
40
|
+
|
41
|
+
# Raised on the HTTP status code 429
|
42
|
+
TooManyRequests = Class.new(ClientError)
|
43
|
+
|
44
|
+
# Raised on a 5xx HTTP status code
|
45
|
+
ServerError = Class.new(self)
|
46
|
+
|
47
|
+
# Raised on the HTTP status code 500
|
48
|
+
InternalServerError = Class.new(ServerError)
|
49
|
+
|
50
|
+
# Raised on the HTTP status code 502
|
51
|
+
# BadGateway = Class.new(ServerError)
|
52
|
+
# '502' => Synapse::Error::BadGateway,
|
53
|
+
|
54
|
+
# Raised on the HTTP status code 503
|
55
|
+
ServiceUnavailable = Class.new(ServerError)
|
56
|
+
|
57
|
+
# Raised on the HTTP status code 504
|
58
|
+
# GatewayTimeout = Class.new(ServerError)
|
59
|
+
# '504' => Synapse::Error::GatewayTimeout
|
60
|
+
|
61
|
+
# HTTP status code to Error subclass mapping
|
62
|
+
#
|
63
|
+
# @todo doesn't do well when there's an html response from nginx for bad gateway/timeout
|
64
|
+
|
65
|
+
ERRORS = {
|
66
|
+
'202' => Synapse::Error::Accepted,
|
67
|
+
'400' => Synapse::Error::BadRequest,
|
68
|
+
'401' => Synapse::Error::Unauthorized,
|
69
|
+
'402' => Synapse::Error::RequestDeclined,
|
70
|
+
'404' => Synapse::Error::NotFound,
|
71
|
+
'409' => Synapse::Error::Conflict,
|
72
|
+
'429' => Synapse::Error::TooManyRequests,
|
73
|
+
'500' => Synapse::Error::InternalServerError,
|
74
|
+
'503' => Synapse::Error::ServiceUnavailable,
|
75
|
+
}.freeze
|
76
|
+
|
77
|
+
# The SynapsePay API Error Code
|
78
|
+
#
|
79
|
+
# @return [Integer]
|
80
|
+
attr_reader :code, :http_code
|
81
|
+
|
82
|
+
# The JSON HTTP response in Hash form
|
83
|
+
# @return [Hash]
|
84
|
+
attr_reader :response, :message
|
85
|
+
|
86
|
+
class << self
|
87
|
+
# Create a new error from an HTTP response
|
88
|
+
# @param body [String]
|
89
|
+
# @param code [Integer]
|
90
|
+
# @param http_code [Integer]
|
91
|
+
# @return [Synapse::Error]
|
92
|
+
def from_response(body)
|
93
|
+
message, error_code, http_code = parse_error(body)
|
94
|
+
http_code = http_code.to_s
|
95
|
+
klass = ERRORS[http_code] || Synapse::Error
|
96
|
+
klass.new(message: message, code: error_code, response: body, http_code: http_code)
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def parse_error(body)
|
102
|
+
|
103
|
+
if body.nil? || body.empty?
|
104
|
+
['', nil, nil]
|
105
|
+
|
106
|
+
elsif body['mfa'] && body.is_a?(Hash)
|
107
|
+
["#{body['mfa']["message"] } acces_token: #{body['mfa']["access_token"]}", body['error_code'], body['http_code']]
|
108
|
+
elsif body[:mfa] && body.is_a?(Hash)
|
109
|
+
["#{body[:mfa][:message] } acces_token: #{body[:mfa][:access_token]}", body[:error_code], body[:http_code]]
|
110
|
+
|
111
|
+
elsif body['message'] && body.is_a?(Hash)
|
112
|
+
[body["message"]["en"], body['error_code'], body['http_code']]
|
113
|
+
elsif body[:message] && body.is_a?(Hash)
|
114
|
+
[body[:message][:en], body[:error_code], body[:http_code]]
|
115
|
+
|
116
|
+
elsif body.is_a?(Hash) && body['error'].is_a?(Hash)
|
117
|
+
[body['error']['en'], body['error_code'], body['http_code']]
|
118
|
+
elsif body.is_a?(Hash) && body[:error].is_a?(Hash)
|
119
|
+
[body[:error][:en], body[:error_code], body[:http_code]]
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Initializes a new Error object
|
126
|
+
# @param message [Exception, String]
|
127
|
+
# @param code [Integer]
|
128
|
+
# @param response [Hash]
|
129
|
+
# @return [Synapse::Error]
|
130
|
+
def initialize(message: '', code: nil, response: {}, http_code:)
|
131
|
+
super(message)
|
132
|
+
@code = code
|
133
|
+
@response = response
|
134
|
+
@message = message
|
135
|
+
@http_code = http_code
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|