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