synapseruby 1.0.8 → 1.0.9
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/lib/synapse_api/client.rb +348 -327
- data/lib/synapse_api/http_request.rb +134 -134
- data/lib/synapse_api/user.rb +675 -671
- data/lib/synapse_api/version.rb +1 -1
- metadata +2 -3
- data/pkg/synapseruby-1.0.7.gem +0 -0
@@ -10,20 +10,20 @@ module Synapse
|
|
10
10
|
# @return [String] the base url of the API (production or sandbox)
|
11
11
|
# @!attribute [rw] config
|
12
12
|
# @return [Hash] various settings related to request headers
|
13
|
-
|
14
|
-
|
13
|
+
# @!attribute [rw] raise_for_202
|
14
|
+
# @return [Boolean] relating to how to handle 202 exception
|
15
15
|
attr_accessor :base_url, :config, :raise_for_202
|
16
16
|
|
17
17
|
# @param base_url [String] the base url of the API (production or sandbox)
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
# @param client_id [String]
|
19
|
+
# @param client_secret [String]
|
20
|
+
# @param fingerprint [String]
|
21
|
+
# @param ip_address [String]
|
22
|
+
# @param raise_for_202 [String]
|
23
|
+
# @param logging [Boolean] (optional) logs to stdout when true
|
24
|
+
# @param log_to [String] (optional) file path to log to file (logging must be true)
|
25
25
|
def initialize(base_url:, client_id:, client_secret:, fingerprint:, ip_address:, raise_for_202:false, **options)
|
26
|
-
|
26
|
+
@raise_for_202 = raise_for_202
|
27
27
|
log_to = options[:log_to] || 'stdout'
|
28
28
|
RestClient.log = log_to if options[:logging]
|
29
29
|
@logging = options[:logging]
|
@@ -39,7 +39,7 @@ module Synapse
|
|
39
39
|
end
|
40
40
|
|
41
41
|
# Returns headers for HTTP requests.
|
42
|
-
|
42
|
+
# @return [Hash]
|
43
43
|
def headers
|
44
44
|
user = "#{config[:oauth_key]}|#{config[:fingerprint]}"
|
45
45
|
gateway = "#{config[:client_id]}|#{config[:client_secret]}"
|
@@ -50,30 +50,30 @@ module Synapse
|
|
50
50
|
'X-SP-USER' => user,
|
51
51
|
'X-SP-USER-IP' => config[:ip_address],
|
52
52
|
}
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
53
|
+
if config[:idemopotency_key]
|
54
|
+
headers['X-SP-IDEMPOTENCY-KEY'] = config[:idemopotency_key]
|
55
|
+
end
|
56
|
+
headers
|
57
57
|
end
|
58
58
|
|
59
59
|
# Alias for headers (copy of current headers)
|
60
60
|
alias_method :get_headers, :headers
|
61
61
|
|
62
62
|
# Updates current HTPP headers
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
63
|
+
# @param fingerprint [String]
|
64
|
+
# @param oauth_key [String]
|
65
|
+
# @param fingerprint [String]
|
66
|
+
# @param client_id [String]
|
67
|
+
# @param client_secret [String]
|
68
|
+
# @param ip_address [String]
|
69
|
+
# @param idemopotency_key [String]
|
70
70
|
def update_headers(oauth_key: nil, fingerprint: nil, client_id: nil, client_secret: nil, ip_address: nil, idemopotency_key: nil)
|
71
71
|
config[:fingerprint] = fingerprint if fingerprint
|
72
72
|
config[:oauth_key] = oauth_key if oauth_key
|
73
73
|
config[:client_id] = client_id if client_id
|
74
74
|
config[:client_secret] = client_secret if client_secret
|
75
75
|
config[:ip_address] = ip_address if ip_address
|
76
|
-
|
76
|
+
config[:idemopotency_key] = idemopotency_key if idemopotency_key
|
77
77
|
nil
|
78
78
|
end
|
79
79
|
|
@@ -81,36 +81,36 @@ module Synapse
|
|
81
81
|
# @param path [String]
|
82
82
|
# @param payload [HASH]
|
83
83
|
# @param **options payload = idempotency_key [String] (optional) avoid accidentally performing the same operation twice
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
84
|
+
# @return [Hash] API response
|
85
|
+
# @raise [Synapse::Error] subclass depends on HTTP response
|
86
|
+
def post(path, payload, **options)
|
87
|
+
#copy of current headers
|
88
|
+
headers = get_headers
|
89
|
+
|
90
|
+
# update the headers with idempotency_key
|
91
|
+
if options[:idempotency_key]
|
92
|
+
headers = headers.merge({'X-SP-IDEMPOTENCY-KEY' => options[:idempotency_key]})
|
93
|
+
end
|
94
|
+
|
95
|
+
response = with_error_handling { RestClient::Request.execute(:method => :post,
|
96
96
|
:url => full_url(path),
|
97
97
|
:payload => payload.to_json,
|
98
98
|
:headers => headers,
|
99
99
|
:timeout => 300
|
100
100
|
) }
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
101
|
+
puts 'RESPONSE:', JSON.parse(response) if @logging
|
102
|
+
response = JSON.parse(response)
|
103
|
+
|
104
|
+
if raise_for_202 && response["http_code"] == "202"
|
105
|
+
raise Error.from_response(response)
|
106
|
+
elsif response["error"]
|
107
|
+
raise Error.from_response(response)
|
108
|
+
else
|
109
|
+
response
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Sends a GET request to the given path with the given payload.
|
114
114
|
# @param path [String]
|
115
115
|
# @return [Hash] API response
|
116
116
|
# @raise [Synapse::Error] subclass depends on HTTP response
|
@@ -119,38 +119,38 @@ module Synapse
|
|
119
119
|
puts 'RESPONSE:', JSON.parse(response) if @logging
|
120
120
|
response = JSON.parse(response)
|
121
121
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
122
|
+
if raise_for_202 && response["http_code"] == "202"
|
123
|
+
raise Error.from_response(response)
|
124
|
+
elsif response["error"]
|
125
|
+
raise Error.from_response(response)
|
126
|
+
else
|
127
|
+
response
|
128
|
+
end
|
129
129
|
end
|
130
130
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
131
|
+
# Sends a DELETE request to the given path
|
132
|
+
# @param path [String]
|
133
|
+
# @return [Hash] API response
|
134
|
+
# @raise [Synapse::Error] subclass depends on HTTP response
|
135
|
+
def delete(path)
|
136
|
+
response = with_error_handling {RestClient.delete(full_url(path), headers)}
|
137
|
+
puts 'RESPONSE:', JSON.parse(response) if @logging
|
138
|
+
response = JSON.parse(response)
|
139
|
+
|
140
|
+
if raise_for_202 && response["http_code"] == "202"
|
141
|
+
raise Error.from_response(response)
|
142
|
+
elsif response["error"]
|
143
|
+
raise Error.from_response(response)
|
144
|
+
else
|
145
|
+
response
|
146
|
+
end
|
147
|
+
end
|
148
148
|
|
149
149
|
# Sends a PATCH request to the given path with the given payload.
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
150
|
+
# @param path [String]
|
151
|
+
# @param payload [Hash]
|
152
|
+
# @return [Hash] API response
|
153
|
+
# @raise [Synapse::Error] subclass depends on HTTP response
|
154
154
|
def patch(path, payload)
|
155
155
|
response = with_error_handling {RestClient::Request.execute(:method => :patch,
|
156
156
|
:url => full_url(path),
|
@@ -161,75 +161,75 @@ module Synapse
|
|
161
161
|
p 'RESPONSE:', JSON.parse(response) if @logging
|
162
162
|
response = JSON.parse(response)
|
163
163
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
164
|
+
if raise_for_202 && response["http_code"] == "202"
|
165
|
+
raise Error.from_response(response)
|
166
|
+
elsif response["error"]
|
167
|
+
raise Error.from_response(response)
|
168
|
+
else
|
169
|
+
response
|
170
|
+
end
|
171
171
|
end
|
172
172
|
|
173
|
-
|
174
|
-
|
175
|
-
|
173
|
+
def oauthenticate(user_id:)
|
174
|
+
refresh_token = refresh_token(user_id: user_id)
|
175
|
+
end
|
176
176
|
|
177
177
|
private
|
178
178
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
179
|
+
# get user
|
180
|
+
# get refresh_token
|
181
|
+
# send refresh_token to oauth path
|
182
|
+
# grabs the refresh token and formats a refresh token payload
|
183
|
+
def refresh_token(user_id:)
|
184
|
+
path = "/users/#{user_id}"
|
185
|
+
response = get(path)
|
186
|
+
refresh_token = response["refresh_token"]
|
187
|
+
|
188
|
+
refresh_token = {"refresh_token" => refresh_token}
|
189
|
+
oauth_path = oauth_path(user_id)
|
190
|
+
authenticate(refresh_token, oauth_path)
|
191
|
+
end
|
192
|
+
|
193
|
+
# options payload to change scope of oauth
|
194
|
+
def authenticate(refresh_token, oauth_path)
|
195
|
+
oauth_key = post(oauth_path, refresh_token)
|
196
|
+
oauth_key = oauth_key['oauth_key']
|
197
|
+
update_headers(oauth_key: oauth_key)
|
198
|
+
nil
|
199
|
+
end
|
200
|
+
|
201
|
+
def oauth_path(user_id)
|
202
|
+
"/oauth/#{user_id}"
|
203
|
+
end
|
204
204
|
|
205
205
|
def full_url(path)
|
206
|
-
|
206
|
+
"#{base_url}#{path}"
|
207
207
|
end
|
208
208
|
|
209
|
-
|
210
|
-
|
209
|
+
# raising an exception based on http_request
|
210
|
+
# yeilds if http_request raises an exception
|
211
211
|
def with_error_handling
|
212
212
|
yield
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
213
|
+
rescue RestClient::Exceptions::Timeout
|
214
|
+
body = {
|
215
|
+
error: {
|
216
|
+
en: "Request Timeout"
|
217
|
+
},
|
218
|
+
http_code: 504
|
219
|
+
}
|
220
|
+
raise Error.from_response(body)
|
221
|
+
rescue RestClient::Exception => e
|
222
|
+
if e.response.headers[:content_type] == 'application/json'
|
223
|
+
body = JSON.parse(e.response.body)
|
224
|
+
else
|
225
|
+
body = {
|
226
|
+
error: {
|
227
|
+
en: e.response.body
|
228
|
+
},
|
229
|
+
http_code: e.response.code
|
230
|
+
}
|
231
|
+
end
|
232
|
+
raise Error.from_response(body)
|
233
233
|
end
|
234
234
|
end
|
235
235
|
end
|
data/lib/synapse_api/user.rb
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
module Synapse
|
2
|
-
|
2
|
+
# Wrapper class for /users endpoints
|
3
3
|
class User
|
4
4
|
|
5
5
|
# Valid optional args for #get
|
6
|
-
|
7
|
-
:subnetid, :foreign_transaction
|
6
|
+
VALID_QUERY_PARAMS = [:query, :page, :per_page, :type, :full_dehydrate, :ship, :force_refresh, :is_credit,
|
7
|
+
:subnetid, :foreign_transaction,:amount].freeze
|
8
8
|
|
9
9
|
attr_accessor :client, :user_id,:refresh_token, :oauth_key, :expires_in, :payload, :full_dehydrate
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
# @param user_id [String]
|
12
|
+
# @param refresh_token [String]
|
13
|
+
# @param client [Synapse::HTTPClient]
|
14
|
+
# @param payload [Hash]
|
15
|
+
# @param full_dehydrate [Boolean]
|
16
16
|
def initialize(user_id:,refresh_token:, client:,payload:, full_dehydrate:)
|
17
|
-
|
17
|
+
@user_id = user_id
|
18
18
|
@client = client
|
19
19
|
@refresh_token = refresh_token
|
20
20
|
@payload =payload
|
@@ -23,63 +23,62 @@ module Synapse
|
|
23
23
|
|
24
24
|
# Updates users documents
|
25
25
|
# @see https://docs.synapsefi.com/docs/updating-existing-document
|
26
|
-
|
27
|
-
|
26
|
+
# @param payload [Hash]
|
27
|
+
# @return [Synapse::User]
|
28
28
|
def user_update(payload:)
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
29
|
+
path = get_user_path(user_id: self.user_id)
|
30
|
+
begin
|
31
|
+
response = client.patch(path, payload)
|
32
|
+
rescue Synapse::Error::Unauthorized
|
33
|
+
self.authenticate()
|
34
|
+
response =client.patch(path, payload)
|
35
|
+
end
|
36
|
+
User.new(user_id: response['_id'],
|
37
|
+
refresh_token: response['refresh_token'],
|
38
|
+
client: client,
|
39
|
+
full_dehydrate: false,
|
40
|
+
payload: response
|
41
|
+
)
|
42
42
|
end
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
44
|
+
# Queries the API for a node belonging to user
|
45
|
+
# @param node_id [String]
|
46
|
+
# @param full_dehydrate [String] (optional)
|
47
|
+
# if true, returns all trans data on node
|
48
|
+
# @param force_refresh [String] (optional) if true, force refresh
|
49
|
+
# will attempt updating the account balance and transactions on node
|
50
|
+
# @return [Synapse::Node]
|
51
|
+
def get_user_node(node_id:, **options)
|
52
|
+
options[:full_dehydrate] = "yes" if options[:full_dehydrate] == true
|
53
|
+
options[:full_dehydrate] = "no" if options[:full_dehydrate] == false
|
54
|
+
options[:force_refresh] = "yes" if options[:force_refresh] == true
|
55
|
+
options[:force_refresh] = "no" if options[:force_refresh] == false
|
56
|
+
|
57
|
+
path = node(node_id: node_id,
|
58
58
|
full_dehydrate: options[:full_dehydrate],
|
59
59
|
force_refresh: options[:force_refresh] )
|
60
60
|
|
61
|
-
|
62
|
-
|
63
|
-
|
61
|
+
begin
|
62
|
+
node = client.get(path)
|
63
|
+
rescue Synapse::Error::Unauthorized
|
64
|
+
self.authenticate()
|
65
|
+
node = client.get(path)
|
66
|
+
end
|
64
67
|
|
65
|
-
|
66
|
-
node = client.get(path)
|
67
|
-
end
|
68
|
-
|
69
|
-
node = Node.new(node_id: node['_id'],
|
68
|
+
node = Node.new(node_id: node['_id'],
|
70
69
|
user_id: self.user_id,
|
71
70
|
payload: node,
|
72
71
|
full_dehydrate: options[:full_dehydrate] == "yes" ? true : false,
|
73
72
|
type: node["type"]
|
74
73
|
)
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
74
|
+
end
|
75
|
+
|
76
|
+
# Queries Synapse API for all nodes belonging to user
|
77
|
+
# @param page [String,Integer] (optional) response will default to 1
|
78
|
+
# @param per_page [String,Integer] (optional) response will default to 20
|
79
|
+
# @param type [String] (optional)
|
80
|
+
# @see https://docs.synapsepay.com/docs/node-resources node types
|
81
|
+
# @return [Array<Synapse::Nodes>]
|
83
82
|
def get_all_user_nodes(**options)
|
84
83
|
[options[:page], options[:per_page]].each do |arg|
|
85
84
|
if arg && (!arg.is_a?(Integer) || arg < 1)
|
@@ -88,19 +87,19 @@ module Synapse
|
|
88
87
|
end
|
89
88
|
path = get_user_path(user_id: self.user_id) + nodes_path(options)
|
90
89
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
90
|
+
begin
|
91
|
+
nodes = client.get(path)
|
92
|
+
rescue Synapse::Error::Unauthorized
|
93
|
+
self.authenticate()
|
94
|
+
nodes = client.get(path)
|
95
|
+
end
|
97
96
|
|
98
97
|
return [] if nodes["nodes"].empty?
|
99
98
|
response = nodes["nodes"].map { |node_data| Node.new(node_id: node_data['_id'],
|
100
99
|
user_id: node_data['user_id'],
|
101
100
|
payload: node_data, full_dehydrate: "no",
|
102
101
|
type: node_data["type"])}
|
103
|
-
|
102
|
+
nodes = Nodes.new(limit: nodes["limit"],
|
104
103
|
page: nodes["page"],
|
105
104
|
page_count: nodes["page_count"],
|
106
105
|
nodes_count: nodes["node_count"],
|
@@ -109,636 +108,641 @@ module Synapse
|
|
109
108
|
|
110
109
|
# Quaries Synapse oauth API for uto authenitcate user
|
111
110
|
# @params scope [Array<Strings>] (optional)
|
112
|
-
|
113
|
-
|
111
|
+
# @param idempotency_key [String] (optional)
|
112
|
+
# @see https://docs.synapsefi.com/docs/get-oauth_key-refresh-token
|
114
113
|
def authenticate(**options)
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
114
|
+
payload = {
|
115
|
+
"refresh_token" => self.refresh_token
|
116
|
+
}
|
117
|
+
payload["scope"] = options[:scope] if options[:scope]
|
119
118
|
|
120
|
-
|
119
|
+
path = oauth_path()
|
121
120
|
|
122
121
|
oauth_response = client.post(path, payload,options)
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
122
|
+
oauth_key = oauth_response['oauth_key']
|
123
|
+
oauth_expires = oauth_response['expires_in']
|
124
|
+
self.oauth_key = oauth_key
|
125
|
+
self.expires_in = oauth_expires
|
126
|
+
client.update_headers(oauth_key: oauth_key)
|
128
127
|
|
129
|
-
|
128
|
+
oauth_response
|
130
129
|
end
|
131
130
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
131
|
+
# For registering new fingerprint
|
132
|
+
# Supply 2FA device which pin should be sent to
|
133
|
+
# @param device [String]
|
134
|
+
# @param idempotency_key [String] (optional)
|
135
|
+
# @see https://docs.synapsefi.com/docs/get-oauth_key-refresh-token
|
136
|
+
# @return API response [Hash]
|
137
|
+
def select_2fa_device(device:, **options)
|
138
|
+
payload = {
|
140
139
|
"refresh_token": self.refresh_token,
|
141
140
|
"phone_number": device
|
142
141
|
}
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
# Supply pin for 2FA confirmation
|
149
|
-
# @param pin [String]
|
150
|
-
# @param idempotency_key [String] (optional)
|
151
|
-
# @param scope [Array] (optional)
|
152
|
-
# @see https://docs.synapsefi.com/docs/get-oauth_key-refresh-token
|
153
|
-
# @return API response [Hash]
|
154
|
-
def confirm_2fa_pin(pin:, **options)
|
155
|
-
payload = {
|
156
|
-
"refresh_token": self.refresh_token,
|
157
|
-
"validation_pin": pin
|
158
|
-
}
|
142
|
+
path = oauth_path()
|
143
|
+
device_response = client.post(path, payload, options)
|
144
|
+
device_response
|
145
|
+
end
|
159
146
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
147
|
+
# Supply pin for 2FA confirmation
|
148
|
+
# @param pin [String]
|
149
|
+
# @param idempotency_key [String] (optional)
|
150
|
+
# @param scope [Array] (optional)
|
151
|
+
# @see https://docs.synapsefi.com/docs/get-oauth_key-refresh-token
|
152
|
+
# @return API response [Hash]
|
153
|
+
def confirm_2fa_pin(pin:, **options)
|
154
|
+
payload = {
|
155
|
+
"refresh_token": self.refresh_token,
|
156
|
+
"validation_pin": pin
|
157
|
+
}
|
158
|
+
|
159
|
+
payload["scope"] = options[:scope] if options[:scope]
|
160
|
+
|
161
|
+
path = oauth_path()
|
162
|
+
|
163
|
+
pin_response = client.post(path, payload, options)
|
164
|
+
oauth_key = pin_response['oauth_key']
|
165
|
+
oauth_expires = pin_response['expires_in']
|
166
|
+
self.oauth_key = oauth_key
|
167
|
+
self.expires_in = oauth_expires
|
168
|
+
client.update_headers(oauth_key: oauth_key)
|
169
|
+
|
170
|
+
pin_response
|
171
|
+
end
|
172
|
+
|
173
|
+
# Queries the Synapse API to get all transactions belonging to a user
|
174
|
+
# @return [Array<Synapse::Transactions>]
|
175
|
+
# @param page [Integer] (optional) response will default to 1
|
176
|
+
# @param per_page [Integer] (optional) response will default to 20
|
177
|
+
def get_user_transactions(**options)
|
178
|
+
[options[:page], options[:per_page]].each do |arg|
|
179
|
+
if arg && (!arg.is_a?(Integer) || arg < 1)
|
180
|
+
raise ArgumentError, "#{arg} must be nil or an Integer >= 1"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
path = transactions_path(user_id: self.user_id, options: options)
|
185
|
+
|
186
|
+
begin
|
187
|
+
trans = client.get(path)
|
188
|
+
rescue Synapse::Error::Unauthorized
|
189
|
+
self.authenticate()
|
190
|
+
trans = client.get(path)
|
191
|
+
end
|
192
|
+
|
193
|
+
|
194
|
+
response = trans["trans"].map { |trans_data| Transaction.new(trans_id: trans_data['_id'],
|
195
|
+
payload: trans_data
|
196
|
+
)}
|
197
|
+
trans = Transactions.new(limit: trans["limit"],
|
198
|
+
page: trans["page"],
|
199
|
+
page_count: trans["page_count"],
|
200
|
+
trans_count: trans["trans_count"],
|
201
|
+
payload: response
|
202
|
+
)
|
203
|
+
|
204
|
+
trans
|
205
|
+
end
|
206
|
+
|
207
|
+
# Creates Synapse node
|
208
|
+
# @note Types of nodes [Card, IB/Deposit-US, Check/Wire Instructions]
|
209
|
+
# @param payload [Hash]
|
210
|
+
# @param idempotency_key [String] (optional)
|
211
|
+
# @see https://docs.synapsefi.com/docs/node-resources
|
212
|
+
# @return [Synapse::Node] or [Hash]
|
214
213
|
def create_node(payload:, **options)
|
215
214
|
path = get_user_path(user_id: self.user_id)
|
216
215
|
path = path + nodes_path
|
217
216
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
217
|
+
begin
|
218
|
+
response = client.post(path,payload, options)
|
219
|
+
rescue Synapse::Error::Unauthorized
|
220
|
+
self.authenticate()
|
221
|
+
response = client.post(path,payload, options)
|
222
|
+
end
|
224
223
|
|
225
|
-
|
226
|
-
|
224
|
+
if response["nodes"]
|
225
|
+
nodes = response["nodes"].map { |nodes_data| Node.new(user_id: self.user_id,
|
227
226
|
node_id: nodes_data["_id"],
|
228
227
|
full_dehydrate: false,
|
229
228
|
payload: response,
|
230
229
|
type: nodes_data["type"]
|
231
230
|
)}
|
232
|
-
|
231
|
+
nodes = Nodes.new(page: response["page"],
|
233
232
|
limit: response["limit"],
|
234
233
|
page_count: response["page_count"],
|
235
234
|
nodes_count: response["node_count"],
|
236
235
|
payload: nodes
|
237
236
|
)
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
237
|
+
else
|
238
|
+
access_token = response
|
239
|
+
end
|
240
|
+
access_token ? access_token : nodes
|
242
241
|
end
|
243
242
|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
Node.new(user_id: self.user_id,
|
243
|
+
# Submit answer to a MFA question using access token from bank login attempt
|
244
|
+
# @return [Synapse::Node] or [Hash]
|
245
|
+
# @param payload [Hash]
|
246
|
+
# @param idempotency_key [String] (optional)
|
247
|
+
# @see https://docs.synapsefi.com/docs/add-ach-us-node-via-bank-logins-mfa
|
248
|
+
# Please be sure to call ach_mfa again if you have more security questions
|
249
|
+
def ach_mfa(payload:, **options)
|
250
|
+
path = get_user_path(user_id: self.user_id)
|
251
|
+
path = path + nodes_path
|
252
|
+
|
253
|
+
begin
|
254
|
+
response = client.post(path,payload, options)
|
255
|
+
rescue Synapse::Error::Unauthorized
|
256
|
+
self.authenticate()
|
257
|
+
response = client.post(path,payload, options)
|
258
|
+
end
|
259
|
+
|
260
|
+
if response["nodes"]
|
261
|
+
nodes = response["nodes"].map { |nodes_data| Node.new(user_id: self.user_id,
|
262
|
+
node_id: nodes_data["_id"],
|
263
|
+
full_dehydrate: false,
|
264
|
+
payload: response,
|
265
|
+
type: nodes_data["type"]
|
266
|
+
)}
|
267
|
+
nodes = Nodes.new(page: response["page"],
|
268
|
+
limit: response["limit"],
|
269
|
+
page_count: response["page_count"],
|
270
|
+
nodes_count: response["node_count"],
|
271
|
+
payload: nodes
|
272
|
+
)
|
273
|
+
else
|
274
|
+
access_token = response
|
275
|
+
end
|
276
|
+
access_token ? access_token : nodes
|
277
|
+
end
|
278
|
+
|
279
|
+
# Allows you to upload an Ultimate Beneficial Ownership document
|
280
|
+
# @param payload [Hash]
|
281
|
+
# @see https://docs.synapsefi.com/docs/generate-ubo-form
|
282
|
+
# @return API response
|
283
|
+
def create_ubo(payload:)
|
284
|
+
path = get_user_path(user_id: self.user_id)
|
285
|
+
path = path + nodes_path + "/ubo"
|
286
|
+
|
287
|
+
begin
|
288
|
+
response = client.patch(path,payload)
|
289
|
+
rescue Synapse::Error::Unauthorized
|
290
|
+
self.authenticate()
|
291
|
+
response = client.patch(path,payload)
|
292
|
+
end
|
293
|
+
response
|
294
|
+
end
|
295
|
+
|
296
|
+
# Gets user statement
|
297
|
+
# @param page [Integer]
|
298
|
+
# @param per_page [Integer]
|
299
|
+
# @see https://docs.synapsefi.com/docs/statements-by-user
|
300
|
+
# @return API response
|
301
|
+
def get_user_statement(**options)
|
302
|
+
path = get_user_path(user_id: self.user_id) + "/statements"
|
303
|
+
params = VALID_QUERY_PARAMS.map do |p|
|
304
|
+
options[p] ? "#{p}=#{options[p]}" : nil
|
305
|
+
end.compact
|
306
|
+
|
307
|
+
path += '?' + params.join('&') if params.any?
|
308
|
+
|
309
|
+
begin
|
310
|
+
statements = client.get(path)
|
311
|
+
rescue Synapse::Error::Unauthorized
|
312
|
+
self.authenticate()
|
313
|
+
statements = client.get(path)
|
314
|
+
end
|
315
|
+
statements
|
316
|
+
end
|
317
|
+
|
318
|
+
# Request to ship CARD-US
|
319
|
+
# @note Deprecated
|
320
|
+
# @param node_id [String]
|
321
|
+
# @param payload [Hash]
|
322
|
+
# @return [Synapse::Node] or [Hash]
|
323
|
+
def ship_card_node(node_id:, payload:)
|
324
|
+
path = node(user_id: self.user_id, node_id: node_id) + "?ship=YES"
|
325
|
+
begin
|
326
|
+
response = client.patch(path,payload)
|
327
|
+
rescue Synapse::Error::Unauthorized
|
328
|
+
self.authenticate()
|
329
|
+
response = client.patch(path,payload)
|
330
|
+
end
|
331
|
+
Node.new(user_id: self.user_id,
|
334
332
|
node_id: response["_id"],
|
335
333
|
full_dehydrate: false,
|
336
334
|
payload: response,
|
337
335
|
type: response["type"])
|
338
|
-
end
|
339
|
-
|
340
|
-
# Request to ship user debit card [Subnet]
|
341
|
-
# @param node_id [String]
|
342
|
-
# @param payload [Hash]
|
343
|
-
# @param subnet_id [String]
|
344
|
-
# @return [Synapse::Node] or [Hash]
|
345
|
-
def ship_card(node_id:, payload:, subnet_id:)
|
346
|
-
|
347
|
-
path = node(user_id: self.user_id, node_id: node_id) + "/subnets/#{subnet_id}/ship"
|
348
|
-
|
349
|
-
begin
|
350
|
-
response = client.patch(path,payload)
|
351
|
-
rescue Synapse::Error::Unauthorized
|
352
|
-
self.authenticate()
|
353
|
-
response = client.patch(path,payload)
|
354
|
-
end
|
355
|
-
Subnet.new(subnet_id: response["subnet_id"], payload: response, node_id: response["node_id"])
|
356
|
-
|
357
|
-
end
|
358
|
-
|
359
|
-
# Resets debit card number, cvv, and expiration date
|
360
|
-
# @note Deprecated
|
361
|
-
# @see https://docs.synapsefi.com/docs/reset-debit-card
|
362
|
-
# @param node_id [String]
|
363
|
-
# @return [Synapse::Node] or [Hash]
|
364
|
-
def reset_card_node(node_id:)
|
365
|
-
path = node(user_id: self.user_id, node_id: node_id) + "?reset=YES"
|
366
|
-
payload = {}
|
367
|
-
begin
|
368
|
-
response = client.patch(path,payload)
|
369
|
-
rescue Synapse::Error::Unauthorized
|
370
|
-
self.authenticate()
|
371
|
-
response = client.patch(path,payload)
|
372
|
-
end
|
373
|
-
Node.new(user_id: self.user_id,
|
374
|
-
node_id:response["_id"],
|
375
|
-
full_dehydrate: false,
|
376
|
-
payload: response,
|
377
|
-
type: response["type"]
|
378
|
-
)
|
379
|
-
end
|
380
|
-
|
381
|
-
# Creates a new transaction in the API belonging to the provided node
|
382
|
-
# @param node_id [String]
|
383
|
-
# @param payload [Hash]
|
384
|
-
# @param idempotency_key [String] (optional)
|
385
|
-
# @return [Synapse::Transaction]
|
386
|
-
def create_transaction(node_id: ,payload:, **options)
|
387
|
-
path = trans_path(user_id: self.user_id, node_id: node_id)
|
388
|
-
|
389
|
-
begin
|
390
|
-
transaction = client.post(path,payload, options)
|
391
|
-
rescue Synapse::Error::Unauthorized
|
392
|
-
self.authenticate()
|
393
|
-
transaction = client.post(path,payload, options)
|
394
|
-
end
|
395
|
-
transaction = Transaction.new(trans_id: transaction['_id'],
|
396
|
-
payload: transaction,
|
397
|
-
node_id: node_id
|
398
|
-
)
|
399
|
-
end
|
400
|
-
|
401
|
-
# Queries the API for a transaction belonging to the supplied node by transaction id
|
402
|
-
# @param node_id [String]
|
403
|
-
# @param trans_id [String] id of the transaction to find
|
404
|
-
# @return [Synapse::Transaction]
|
405
|
-
def get_node_transaction(node_id:, trans_id:)
|
406
|
-
path = node(user_id: self.user_id, node_id: node_id) + "/trans/#{trans_id}"
|
407
|
-
|
408
|
-
begin
|
409
|
-
trans = client.get(path)
|
410
|
-
rescue Synapse::Error::Unauthorized
|
411
|
-
self.authenticate()
|
412
|
-
trans = client.get(path)
|
413
|
-
end
|
414
|
-
Transaction.new(trans_id: trans['_id'],
|
415
|
-
payload: trans,
|
416
|
-
node_id: node_id
|
417
|
-
)
|
418
|
-
end
|
419
|
-
|
420
|
-
|
421
|
-
# Queries the API for all transactions belonging to the supplied node
|
422
|
-
# @param node_id [String] node to which the transaction belongs
|
423
|
-
# @param page [Integer] (optional) response will default to 1
|
424
|
-
# @param per_page [Integer] (optional) response will default to 20
|
425
|
-
# @return [Array<Synapse::Transaction>]
|
426
|
-
def get_all_node_transaction(node_id:, **options)
|
427
|
-
[options[:page], options[:per_page]].each do |arg|
|
428
|
-
if arg && (!arg.is_a?(Integer) || arg < 1)
|
429
|
-
raise ArgumentError, "#{arg} must be nil or an Integer >= 1"
|
430
336
|
end
|
431
|
-
end
|
432
337
|
|
433
|
-
|
338
|
+
# Request to ship user debit card [Subnet]
|
339
|
+
# @param node_id [String]
|
340
|
+
# @param payload [Hash]
|
341
|
+
# @param subnet_id [String]
|
342
|
+
# @return [Synapse::Node] or [Hash]
|
343
|
+
def ship_card(node_id:, payload:, subnet_id:)
|
344
|
+
path = node(user_id: self.user_id, node_id: node_id) + "/subnets/#{subnet_id}/ship"
|
345
|
+
|
346
|
+
begin
|
347
|
+
response = client.patch(path,payload)
|
348
|
+
rescue Synapse::Error::Unauthorized
|
349
|
+
self.authenticate()
|
350
|
+
response = client.patch(path,payload)
|
351
|
+
end
|
352
|
+
Subnet.new(subnet_id: response["subnet_id"], payload: response, node_id: response["node_id"])
|
353
|
+
end
|
434
354
|
|
435
|
-
|
436
|
-
|
437
|
-
|
355
|
+
# Resets debit card number, cvv, and expiration date
|
356
|
+
# @note Deprecated
|
357
|
+
# @see https://docs.synapsefi.com/docs/reset-debit-card
|
358
|
+
# @param node_id [String]
|
359
|
+
# @return [Synapse::Node] or [Hash]
|
360
|
+
def reset_card_node(node_id:)
|
361
|
+
path = node(user_id: self.user_id, node_id: node_id) + "?reset=YES"
|
362
|
+
payload = {}
|
363
|
+
begin
|
364
|
+
response = client.patch(path,payload)
|
365
|
+
rescue Synapse::Error::Unauthorized
|
366
|
+
self.authenticate()
|
367
|
+
response = client.patch(path,payload)
|
368
|
+
end
|
369
|
+
Node.new(user_id: self.user_id,
|
370
|
+
node_id:response["_id"],
|
371
|
+
full_dehydrate: false,
|
372
|
+
payload: response,
|
373
|
+
type: response["type"]
|
374
|
+
)
|
375
|
+
end
|
438
376
|
|
439
|
-
|
377
|
+
# Creates a new transaction in the API belonging to the provided node
|
378
|
+
# @param node_id [String]
|
379
|
+
# @param payload [Hash]
|
380
|
+
# @param idempotency_key [String] (optional)
|
381
|
+
# @return [Synapse::Transaction]
|
382
|
+
def create_transaction(node_id: ,payload:, **options)
|
383
|
+
path = trans_path(user_id: self.user_id, node_id: node_id)
|
384
|
+
begin
|
385
|
+
transaction = client.post(path,payload, options)
|
386
|
+
rescue Synapse::Error::Unauthorized
|
387
|
+
self.authenticate()
|
388
|
+
transaction = client.post(path,payload, options)
|
389
|
+
end
|
390
|
+
transaction = Transaction.new(trans_id: transaction['_id'],
|
391
|
+
payload: transaction,
|
392
|
+
node_id: node_id
|
393
|
+
)
|
394
|
+
end
|
440
395
|
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
396
|
+
# Queries the API for a transaction belonging to the supplied node by transaction id
|
397
|
+
# @param node_id [String]
|
398
|
+
# @param trans_id [String] id of the transaction to find
|
399
|
+
# @return [Synapse::Transaction]
|
400
|
+
def get_node_transaction(node_id:, trans_id:)
|
401
|
+
path = node(user_id: self.user_id, node_id: node_id) + "/trans/#{trans_id}"
|
402
|
+
|
403
|
+
begin
|
404
|
+
trans = client.get(path)
|
405
|
+
rescue Synapse::Error::Unauthorized
|
406
|
+
self.authenticate()
|
407
|
+
trans = client.get(path)
|
408
|
+
end
|
409
|
+
Transaction.new(trans_id: trans['_id'],
|
410
|
+
payload: trans,
|
411
|
+
node_id: node_id
|
412
|
+
)
|
413
|
+
end
|
447
414
|
|
448
415
|
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
416
|
+
# Queries the API for all transactions belonging to the supplied node
|
417
|
+
# @param node_id [String] node to which the transaction belongs
|
418
|
+
# @param page [Integer] (optional) response will default to 1
|
419
|
+
# @param per_page [Integer] (optional) response will default to 20
|
420
|
+
# @return [Array<Synapse::Transaction>]
|
421
|
+
def get_all_node_transaction(node_id:, **options)
|
422
|
+
[options[:page], options[:per_page]].each do |arg|
|
423
|
+
if arg && (!arg.is_a?(Integer) || arg < 1)
|
424
|
+
raise ArgumentError, "#{arg} must be nil or an Integer >= 1"
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
path = node(user_id: self.user_id, node_id: node_id) + "/trans"
|
429
|
+
|
430
|
+
params = VALID_QUERY_PARAMS.map do |p|
|
431
|
+
options[p] ? "#{p}=#{options[p]}" : nil
|
432
|
+
end.compact
|
433
|
+
|
434
|
+
path += '?' + params.join('&') if params.any?
|
435
|
+
|
436
|
+
begin
|
437
|
+
trans = client.get(path)
|
438
|
+
rescue Synapse::Error::Unauthorized
|
439
|
+
self.authenticate()
|
440
|
+
trans = client.get(path)
|
441
|
+
end
|
442
|
+
response = trans["trans"].map { |trans_data| Transaction.new(trans_id: trans_data['_id'],
|
443
|
+
payload: trans_data,
|
444
|
+
node_id: node_id
|
445
|
+
)}
|
446
|
+
Transactions.new(limit: trans["limit"],
|
447
|
+
page: trans["page"],
|
448
|
+
page_count: trans["page_count"],
|
449
|
+
trans_count: trans["trans_count"],
|
450
|
+
payload: response
|
451
|
+
)
|
452
|
+
end
|
453
|
+
|
454
|
+
# Verifies microdeposits for a node
|
455
|
+
# @param node_id [String]
|
456
|
+
# @param payload [Hash]
|
457
|
+
def verify_micro_deposit(node_id:,payload:)
|
458
|
+
path = node(user_id: self.user_id, node_id: node_id)
|
459
|
+
begin
|
460
|
+
response = client.patch(path, payload)
|
461
|
+
rescue Synapse::Error::Unauthorized
|
462
|
+
self.authenticate()
|
463
|
+
response = client.patch(path, payload)
|
464
|
+
end
|
465
|
+
Node.new(user_id: self.user_id,
|
466
|
+
node_id: response["_id"],
|
467
|
+
full_dehydrate: false,
|
468
|
+
payload: response,
|
469
|
+
type: response["type"]
|
470
|
+
)
|
471
|
+
end
|
472
|
+
|
473
|
+
# Reinitiate microdeposits on a node
|
474
|
+
# @param node_id [String]
|
475
|
+
def reinitiate_micro_deposit(node_id:)
|
476
|
+
payload = {}
|
477
|
+
path = node(user_id: self.user_id, node_id: node_id) + "?resend_micro=YES"
|
478
|
+
begin
|
479
|
+
response = client.patch(path, payload)
|
480
|
+
rescue Synapse::Error::Unauthorized
|
481
|
+
self.authenticate()
|
482
|
+
response = client.patch(path, payload)
|
483
|
+
end
|
484
|
+
Node.new(user_id: self.user_id,
|
485
|
+
node_id: response["_id"],
|
486
|
+
full_dehydrate: false,
|
487
|
+
payload: response,
|
488
|
+
type: response["type"])
|
489
|
+
end
|
490
|
+
|
491
|
+
# Generate tokenized info for Apple Wallet
|
492
|
+
# @param node_id [String]
|
493
|
+
# @param payload [Hash]
|
494
|
+
# @see https://docs.synapsefi.com/docs/generate-applepay-token
|
495
|
+
def generate_apple_pay_token(node_id:,payload:)
|
496
|
+
path = node(user_id: self.user_id, node_id: node_id) + "/applepay"
|
497
|
+
begin
|
498
|
+
response = client.patch(path, payload)
|
499
|
+
rescue Synapse::Error::Unauthorized
|
500
|
+
self.authenticate()
|
501
|
+
response = client.patch(path, payload)
|
502
|
+
end
|
503
|
+
response
|
504
|
+
end
|
505
|
+
|
506
|
+
# Update supp_id, nickname, etc. for a node
|
507
|
+
# @param node_id [String]
|
508
|
+
# @param payload [Hash]
|
509
|
+
# @see https://docs.synapsefi.com/docs/update-info
|
510
|
+
# @return [Synapse::Node]
|
511
|
+
def update_node(node_id:, payload:)
|
512
|
+
path = node(user_id: self.user_id, node_id: node_id)
|
513
|
+
|
514
|
+
begin
|
515
|
+
update = client.patch(path, payload)
|
516
|
+
rescue Synapse::Error::Unauthorized
|
517
|
+
self.authenticate()
|
518
|
+
update = client.patch(path, payload)
|
519
|
+
end
|
520
|
+
Node.new(node_id: node_id,
|
521
|
+
user_id: self.user_id,
|
522
|
+
payload: update,
|
523
|
+
full_dehydrate: false,
|
524
|
+
type: update["type"]
|
525
|
+
)
|
526
|
+
end
|
527
|
+
|
528
|
+
# @param node_id [String]
|
529
|
+
def delete_node(node_id:)
|
530
|
+
path = node(user_id: self.user_id, node_id: node_id)
|
531
|
+
|
532
|
+
begin
|
533
|
+
delete = client.delete(path)
|
534
|
+
rescue Synapse::Error::Unauthorized
|
535
|
+
self.authenticate()
|
536
|
+
delete = client.delete(path)
|
537
|
+
end
|
538
|
+
delete
|
539
|
+
end
|
540
|
+
|
541
|
+
# Initiates dummy transactions to a node
|
542
|
+
# @param node_id [String]
|
543
|
+
# @param is_credit [String]
|
544
|
+
# @param foreign_transaction [String]
|
545
|
+
# @param subnetid [String]
|
546
|
+
# @param type [String]
|
547
|
+
# @see https://docs.synapsefi.com/docs/trigger-dummy-transactions
|
548
|
+
def dummy_transactions(node_id:, **options)
|
549
|
+
path = node(user_id: self.user_id, node_id: node_id) + "/dummy-tran"
|
550
|
+
params = VALID_QUERY_PARAMS.map do |p|
|
551
|
+
options[p] ? "#{p}=#{options[p]}" : nil
|
552
|
+
end.compact
|
553
|
+
path += '?' + params.join('&') if params.any?
|
554
|
+
|
555
|
+
begin
|
556
|
+
response = client.get(path)
|
557
|
+
rescue Synapse::Error::Unauthorized
|
558
|
+
self.authenticate()
|
559
|
+
response = client.get(path)
|
560
|
+
end
|
561
|
+
response
|
562
|
+
end
|
563
|
+
|
564
|
+
# Adds comment to the transactions
|
565
|
+
# @param node_id [String]
|
566
|
+
# @param trans_id [String]
|
567
|
+
# @param payload [Hash]
|
568
|
+
# @return [Synapse::Transaction]
|
569
|
+
def comment_transaction(node_id:,trans_id:,payload:)
|
570
|
+
path = trans_path(user_id: self.user_id, node_id: node_id) + "/#{trans_id}"
|
571
|
+
|
572
|
+
begin
|
573
|
+
trans = client.patch(path, payload)
|
574
|
+
rescue Synapse::Error::Unauthorized
|
575
|
+
self.authenticate()
|
576
|
+
trans = client.patch(path, payload)
|
577
|
+
end
|
578
|
+
Transaction.new(trans_id: trans['_id'], payload: trans)
|
579
|
+
end
|
580
|
+
|
581
|
+
# Cancels transaction if it has not already settled
|
582
|
+
# @param node_id
|
583
|
+
# @param trans_id
|
584
|
+
# @return API response [Hash]
|
585
|
+
def cancel_transaction(node_id:, trans_id:)
|
586
|
+
path = trans_path(user_id: self.user_id, node_id: node_id) + "/#{trans_id}"
|
587
|
+
begin
|
588
|
+
response = client.delete(path)
|
589
|
+
rescue Synapse::Error::Unauthorized
|
590
|
+
self.authenticate()
|
591
|
+
response = client.delete(path)
|
592
|
+
end
|
593
|
+
response
|
594
|
+
end
|
595
|
+
|
596
|
+
# Dispute a transaction for a user
|
597
|
+
# @param node_id
|
598
|
+
# @param trans_id
|
599
|
+
# @see https://docs.synapsefi.com/docs/dispute-card-transaction
|
600
|
+
# @return API response [Hash]
|
601
|
+
def dispute_card_transactions(node_id:, trans_id:, payload:)
|
602
|
+
path = trans_path(user_id: user_id, node_id: node_id) + "/#{trans_id}"
|
603
|
+
path += "/dispute"
|
604
|
+
begin
|
605
|
+
dispute = client.patch(path, payload)
|
606
|
+
rescue Synapse::Error::Unauthorized
|
607
|
+
self.authenticate()
|
608
|
+
dispute = client.patch(path, payload)
|
609
|
+
end
|
610
|
+
dispute
|
611
|
+
end
|
612
|
+
|
613
|
+
# Creates subnet for a node debit card or act/rt number
|
614
|
+
# @param node_id [String]
|
615
|
+
# @param payload [Hash]
|
616
|
+
# @param idempotency_key [String] (optional)
|
617
|
+
# @return [Synapse::Subnet]
|
618
|
+
def create_subnet(node_id:,payload:, **options)
|
619
|
+
path = subnet_path(user_id: self.user_id, node_id: node_id)
|
620
|
+
begin
|
621
|
+
subnet = client.post(path,payload, options)
|
622
|
+
rescue Synapse::Error::Unauthorized
|
623
|
+
self.authenticate()
|
624
|
+
subnet = client.post(path,payload, options)
|
625
|
+
end
|
626
|
+
Subnet.new(subnet_id: subnet['_id'], payload: subnet, node_id: node_id)
|
627
|
+
end
|
628
|
+
|
629
|
+
# Updates subnet debit card and act/rt number
|
630
|
+
# @param node_id [String]
|
631
|
+
# @param payload [Hash]
|
632
|
+
# @param subnet_id [String]
|
633
|
+
# @return [Synapse::Subnet]
|
634
|
+
def update_subnet(node_id:, payload:, subnet_id:, **options)
|
635
|
+
path = subnet_path(user_id: self.user_id, node_id: node_id, subnet_id: subnet_id)
|
636
|
+
begin
|
637
|
+
subnet = client.patch(path,payload)
|
638
|
+
rescue Synapse::Error::Unauthorized
|
639
|
+
self.authenticate()
|
640
|
+
subnet = client.patch(path,payload)
|
641
|
+
end
|
642
|
+
Subnet.new(subnet_id: subnet['_id'], payload: subnet, node_id: node_id)
|
643
|
+
end
|
644
|
+
|
645
|
+
|
646
|
+
# Gets all node subnets
|
647
|
+
# @param node_id [String]
|
648
|
+
# @param page [Integer]
|
649
|
+
# @param per_page [Integer]
|
650
|
+
# @see https://docs.synapsefi.com/docs/all-node-subnets
|
651
|
+
def get_all_subnets(node_id:,**options)
|
652
|
+
[options[:page], options[:per_page]].each do |arg|
|
653
|
+
if arg && (!arg.is_a?(Integer) || arg < 1)
|
654
|
+
raise ArgumentError, "#{arg} must be nil or an Integer >= 1"
|
655
|
+
end
|
656
|
+
end
|
657
|
+
|
658
|
+
path = node(user_id: self.user_id, node_id: node_id) + "/subnets"
|
659
|
+
params = VALID_QUERY_PARAMS.map do |p|
|
660
|
+
options[p] ? "#{p}=#{options[p]}" : nil
|
661
|
+
end.compact
|
662
|
+
path += '?' + params.join('&') if params.any?
|
663
|
+
|
664
|
+
begin
|
665
|
+
subnets = client.get(path)
|
666
|
+
rescue Synapse::Error::Unauthorized
|
667
|
+
self.authenticate()
|
668
|
+
subnets = client.get(path)
|
669
|
+
end
|
670
|
+
|
671
|
+
response = subnets["subnets"].map { |subnets_data| Subnet.new(subnet_id: subnets_data['_id'],
|
672
|
+
payload: subnets,
|
673
|
+
node_id: node_id
|
674
|
+
)}
|
675
|
+
Subnets.new(limit: subnets["limit"],
|
676
|
+
page: subnets["page"],
|
677
|
+
page_count: subnets["page_count"],
|
678
|
+
subnets_count: subnets["subnets_count"],
|
679
|
+
payload: response,
|
680
|
+
node_id: node_id
|
681
|
+
)
|
668
682
|
end
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
subnet
|
713
|
-
end
|
714
|
-
|
715
|
-
# Gets statement by node
|
716
|
-
# @param page [Integer]
|
717
|
-
# @param per_page [Integer]
|
718
|
-
# @see https://docs.synapsefi.com/docs/statements-by-user
|
719
|
-
# @return API response [Hash]
|
720
|
-
def get_node_statements(node_id:,**options)
|
721
|
-
[options[:page], options[:per_page]].each do |arg|
|
722
|
-
if arg && (!arg.is_a?(Integer) || arg < 1)
|
723
|
-
raise ArgumentError, "#{arg} must be nil or an Integer >= 1"
|
683
|
+
|
684
|
+
# Queries a node for a specific subnet by subnet_id
|
685
|
+
# @param node_id [String] id of node
|
686
|
+
# @param subnet_id [String,void] (optional) id of a subnet to look up
|
687
|
+
# @return [Synapse::Subnet]
|
688
|
+
def get_subnet(node_id:,subnet_id:)
|
689
|
+
path = node(user_id: self.user_id, node_id: node_id) + "/subnets/#{subnet_id}"
|
690
|
+
begin
|
691
|
+
subnet = client.get(path)
|
692
|
+
rescue Synapse::Error::Unauthorized
|
693
|
+
self.authenticate()
|
694
|
+
subnet = client.get(path)
|
695
|
+
end
|
696
|
+
subnet = Subnet.new(subnet_id: subnet['_id'], payload: subnet, node_id: node_id)
|
697
|
+
subnet
|
698
|
+
end
|
699
|
+
|
700
|
+
# Gets statement by node
|
701
|
+
# @param page [Integer]
|
702
|
+
# @param per_page [Integer]
|
703
|
+
# @see https://docs.synapsefi.com/docs/statements-by-user
|
704
|
+
# @return API response [Hash]
|
705
|
+
def get_node_statements(node_id:,**options)
|
706
|
+
[options[:page], options[:per_page]].each do |arg|
|
707
|
+
if arg && (!arg.is_a?(Integer) || arg < 1)
|
708
|
+
raise ArgumentError, "#{arg} must be nil or an Integer >= 1"
|
709
|
+
end
|
710
|
+
end
|
711
|
+
|
712
|
+
path = node(user_id: self.user_id, node_id: node_id) + "/statements"
|
713
|
+
params = VALID_QUERY_PARAMS.map do |p|
|
714
|
+
options[p] ? "#{p}=#{options[p]}" : nil
|
715
|
+
end.compact
|
716
|
+
path += '?' + params.join('&') if params.any?
|
717
|
+
|
718
|
+
begin
|
719
|
+
statements = client.get(path)
|
720
|
+
rescue Synapse::Error::Unauthorized
|
721
|
+
self.authenticate()
|
722
|
+
statements = client.get(path)
|
723
|
+
end
|
724
|
+
|
725
|
+
statements
|
724
726
|
end
|
725
|
-
end
|
726
727
|
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
728
|
+
# Gets statement by node on demand
|
729
|
+
# @param payload [Hash]
|
730
|
+
# @see https://docs.synapsefi.com/reference#generate-node-statements
|
731
|
+
# @return API response [Hash]
|
732
|
+
def get_node_statements(node_id:,payload:)
|
732
733
|
|
733
|
-
|
734
|
-
statements = client.get(path)
|
735
|
-
rescue Synapse::Error::Unauthorized
|
736
|
-
self.authenticate()
|
737
|
-
statements = client.get(path)
|
738
|
-
end
|
734
|
+
path = node(user_id: self.user_id, node_id: node_id) + "/statements"
|
739
735
|
|
740
|
-
|
741
|
-
|
736
|
+
|
737
|
+
begin
|
738
|
+
statements = client.post(path,payload)
|
739
|
+
rescue Synapse::Error::Unauthorized
|
740
|
+
self.authenticate()
|
741
|
+
statements = client.post(path,payload)
|
742
|
+
end
|
743
|
+
|
744
|
+
statements
|
745
|
+
end
|
742
746
|
|
743
747
|
private
|
744
748
|
|
@@ -777,30 +781,30 @@ module Synapse
|
|
777
781
|
path
|
778
782
|
end
|
779
783
|
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
784
|
+
def node(node_id:, **options)
|
785
|
+
path = "/users/#{self.user_id}/nodes/#{node_id}"
|
786
|
+
params = VALID_QUERY_PARAMS.map do |p|
|
787
|
+
options[p] ? "#{p}=#{options[p]}" : nil
|
788
|
+
end.compact
|
789
|
+
|
790
|
+
path += '?' + params.join('&') if params.any?
|
791
|
+
|
792
|
+
path
|
793
|
+
end
|
794
|
+
|
795
|
+
def trans_path(user_id:, node_id:)
|
796
|
+
path = "/users/#{user_id}/nodes/#{node_id}/trans"
|
797
|
+
path
|
798
|
+
end
|
799
|
+
|
800
|
+
def subnet_path(user_id:, node_id:, subnet_id: nil)
|
801
|
+
if subnet_id
|
802
|
+
path = "/users/#{user_id}/nodes/#{node_id}/subnets/#{subnet_id}"
|
803
|
+
else
|
804
|
+
path = "/users/#{user_id}/nodes/#{node_id}/subnets"
|
805
|
+
end
|
806
|
+
path
|
807
|
+
end
|
804
808
|
end
|
805
809
|
end
|
806
810
|
|