synapse_pay_rest 0.0.11 → 0.0.13
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/.gitignore +39 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +45 -0
- data/README.md +35 -0
- data/Rakefile +10 -0
- data/lib/synapse_pay_rest.rb +20 -25
- data/lib/synapse_pay_rest/api/nodes.rb +46 -0
- data/lib/synapse_pay_rest/api/trans.rb +38 -0
- data/lib/synapse_pay_rest/api/users.rb +97 -0
- data/lib/synapse_pay_rest/error.rb +114 -0
- data/lib/synapse_pay_rest/http_client.rb +109 -98
- data/lib/synapse_pay_rest/version.rb +3 -0
- data/samples.md +276 -0
- data/synapse_pay_rest.gemspec +27 -0
- metadata +74 -8
- data/lib/synapse_pay_rest/api/Nodes.rb +0 -55
- data/lib/synapse_pay_rest/api/Trans.rb +0 -51
- data/lib/synapse_pay_rest/api/Users.rb +0 -103
@@ -1,101 +1,112 @@
|
|
1
1
|
require 'rest-client'
|
2
|
+
require 'json'
|
2
3
|
|
3
4
|
module SynapsePayRest
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
5
|
+
class HTTPClient
|
6
|
+
|
7
|
+
attr_accessor :base_url, :config, :headers, :user_id
|
8
|
+
|
9
|
+
def initialize(config, base_url, user_id: nil)
|
10
|
+
@config = config
|
11
|
+
@base_url = base_url
|
12
|
+
# RestClient.log = 'stdout'
|
13
|
+
@user_id = user_id
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_headers
|
17
|
+
user = "#{config['oauth_key']}|#{config['fingerprint']}"
|
18
|
+
gateway = "#{config['client_id']}|#{config['client_secret']}"
|
19
|
+
headers = {
|
20
|
+
:content_type => :json,
|
21
|
+
:accept => :json,
|
22
|
+
'X-SP-GATEWAY' => gateway,
|
23
|
+
'X-SP-USER' => user,
|
24
|
+
'X-SP-USER-IP' => config['ip_address']
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def update_headers(user_id: nil, oauth_key: nil, fingerprint: nil, client_id: nil, client_secret: nil, ip_address: nil)
|
29
|
+
self.user_id = user_id if user_id
|
30
|
+
config['fingerprint'] = fingerprint if fingerprint
|
31
|
+
config['oauth_key'] = oauth_key if oauth_key
|
32
|
+
config['client_id'] = client_id if client_id
|
33
|
+
config['client_secret'] = client_secret if client_secret
|
34
|
+
config['ip_address'] = ip_address if ip_address
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def post(path, payload)
|
39
|
+
response = with_error_handling { RestClient.post(full_url(path), payload.to_json, get_headers) }
|
40
|
+
JSON.parse(response)
|
41
|
+
end
|
42
|
+
|
43
|
+
def patch(path, payload)
|
44
|
+
response = with_error_handling { RestClient.patch(full_url(path), payload.to_json, get_headers) }
|
45
|
+
JSON.parse(response)
|
46
|
+
end
|
47
|
+
|
48
|
+
def get(path)
|
49
|
+
response = with_error_handling { RestClient.get(full_url(path), get_headers) }
|
50
|
+
JSON.parse(response)
|
51
|
+
end
|
52
|
+
|
53
|
+
def delete(path)
|
54
|
+
response = with_error_handling { RestClient.delete(full_url(path), get_headers) }
|
55
|
+
JSON.parse(response)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def full_url(path)
|
61
|
+
"#{base_url}#{path}"
|
62
|
+
end
|
63
|
+
|
64
|
+
def with_error_handling
|
65
|
+
yield
|
66
|
+
rescue => e
|
67
|
+
# By the way, this is a really bad idea.
|
68
|
+
# See: https://www.relishapp.com/womply/ruby-style-guide/docs/exceptions
|
69
|
+
# The exceptions should be enumerated. Not all exceptions are going
|
70
|
+
# to be parsable by JSON. The only one that should be captured are the
|
71
|
+
# are the HTTP Client responses.
|
72
|
+
case e.response.code
|
73
|
+
when 400
|
74
|
+
return e.response
|
75
|
+
when 401
|
76
|
+
return e.response
|
77
|
+
when 409
|
78
|
+
return e.response
|
79
|
+
when 500
|
80
|
+
return e.response
|
81
|
+
when 405
|
82
|
+
return handle_method_not_allowed
|
83
|
+
when 502
|
84
|
+
#Raise a gateway error
|
85
|
+
return handle_gateway_error
|
86
|
+
when 504
|
87
|
+
#Raise a timeout error
|
88
|
+
return handle_timeout_error
|
89
|
+
else
|
90
|
+
#Raise a generic error
|
91
|
+
return handle_unknown_error
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def handle_method_not_allowed
|
96
|
+
return {'success' => false, 'reason' => 'The method is not allowed. Check your id parameters.'}.to_json
|
97
|
+
end
|
98
|
+
|
99
|
+
def handle_gateway_error
|
100
|
+
return {'success' => false, 'reason' => 'The gateway appears to be down. Check synapsepay.com or try again later.'}.to_json
|
101
|
+
end
|
102
|
+
|
103
|
+
def handle_timeout_error
|
104
|
+
return {'success' => false, 'reason' => 'A timeout has occurred.'}.to_json
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
def handle_unknown_error
|
109
|
+
return {'success' => false, 'reason' => 'Unknown error in library. Contact synapsepay.'}.to_json
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
data/samples.md
ADDED
@@ -0,0 +1,276 @@
|
|
1
|
+
|
2
|
+
## Initialization
|
3
|
+
|
4
|
+
```ruby
|
5
|
+
require 'synapse_pay_rest'
|
6
|
+
|
7
|
+
options = {
|
8
|
+
'oauth_key' => USER_OAUTH KEY, # Optional
|
9
|
+
'fingerprint' => USER_FINGERPRINT,
|
10
|
+
'client_id' => YOUR_CLIENT_ID,
|
11
|
+
'client_secret' => YOUR_CLIENT_SECRET,
|
12
|
+
'ip_address' => USER_IP_ADDRESS,
|
13
|
+
'development_mode' => true #true will ping sandbox.synapsepay.com while false will ping synapsepay.com
|
14
|
+
}
|
15
|
+
|
16
|
+
USER_ID = ID_OF_USER # Optional
|
17
|
+
|
18
|
+
client = SynapsePayRest::Client.new options: options, user_id: USER_ID
|
19
|
+
|
20
|
+
```
|
21
|
+
|
22
|
+
## User API Calls
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
|
26
|
+
|
27
|
+
# Get All Users
|
28
|
+
|
29
|
+
users_response = client.users.get
|
30
|
+
|
31
|
+
|
32
|
+
# Create User
|
33
|
+
|
34
|
+
create_payload = {
|
35
|
+
"logins" => [
|
36
|
+
{
|
37
|
+
"email" => "rubyTest@synapsepay.com",
|
38
|
+
"password" => "test1234",
|
39
|
+
"read_only" => false
|
40
|
+
}
|
41
|
+
],
|
42
|
+
"phone_numbers" => [
|
43
|
+
"901.111.1111"
|
44
|
+
],
|
45
|
+
"legal_names" => [
|
46
|
+
"RUBY TEST USER"
|
47
|
+
],
|
48
|
+
"extra" => {
|
49
|
+
"note" => "Interesting user",
|
50
|
+
"supp_id" => "122eddfgbeafrfvbbb",
|
51
|
+
"is_business" => false
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
create_response = client.users.create(payload: create_payload)
|
56
|
+
|
57
|
+
|
58
|
+
# Get User
|
59
|
+
|
60
|
+
user_response = client.users.get(user_id: USER_ID)
|
61
|
+
|
62
|
+
|
63
|
+
# Update a User
|
64
|
+
|
65
|
+
update_payload = {
|
66
|
+
"refresh_token" => "REFRESH_TOKEN",
|
67
|
+
"update":{
|
68
|
+
"login" => {
|
69
|
+
"email" => "test2ruby@email.com",
|
70
|
+
"password" => "test1234",
|
71
|
+
"read_only" => true
|
72
|
+
},
|
73
|
+
"phone_number" => "9019411111",
|
74
|
+
"legal_name" => "Some new name"
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
client.users.update(payload: update_payload)
|
79
|
+
|
80
|
+
|
81
|
+
# Add Document
|
82
|
+
|
83
|
+
ssn_payload = {
|
84
|
+
"doc" => {
|
85
|
+
"birth_day" => 4,
|
86
|
+
"birth_month" => 2,
|
87
|
+
"birth_year" => 1940,
|
88
|
+
"name_first" => "John",
|
89
|
+
"name_last" => "doe",
|
90
|
+
"address_street1" => "1 Infinite Loop",
|
91
|
+
"address_postal_code" => "95014",
|
92
|
+
"address_country_code" => "US",
|
93
|
+
"document_value" => "3333",
|
94
|
+
"document_type" => "SSN"
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
ssn_response = client.users.add_doc(payload: ssn_payload)
|
99
|
+
|
100
|
+
|
101
|
+
# Answer KBA Questions
|
102
|
+
|
103
|
+
kba_payload = {
|
104
|
+
"doc" => {
|
105
|
+
"question_set_id" => "557520ad343463000300005a",
|
106
|
+
"answers" => [
|
107
|
+
{ "question_id" => 1, "answer_id" => 1 },
|
108
|
+
{ "question_id" => 2, "answer_id" => 1 },
|
109
|
+
{ "question_id" => 3, "answer_id" => 1 },
|
110
|
+
{ "question_id" => 4, "answer_id" => 1 },
|
111
|
+
{ "question_id" => 5, "answer_id" => 1 }
|
112
|
+
]
|
113
|
+
}
|
114
|
+
}
|
115
|
+
|
116
|
+
kba_response = client.users.answer_kba(payload: kba_payload)
|
117
|
+
|
118
|
+
|
119
|
+
# Attach a file
|
120
|
+
|
121
|
+
file_response = client.users.attach_file(file_path: 'PATH_TO_FILE')
|
122
|
+
|
123
|
+
|
124
|
+
# Refresh User
|
125
|
+
|
126
|
+
oauth_payload = {
|
127
|
+
"refresh_token" => USER_REFRESH_TOKEN
|
128
|
+
}
|
129
|
+
|
130
|
+
oauth_response = client.users.refresh(payload: oauth_payload)
|
131
|
+
|
132
|
+
```
|
133
|
+
|
134
|
+
|
135
|
+
## Node API Calls
|
136
|
+
|
137
|
+
```ruby
|
138
|
+
|
139
|
+
|
140
|
+
# Get All Nodes
|
141
|
+
|
142
|
+
nodes_response = client.nodes.get
|
143
|
+
|
144
|
+
|
145
|
+
# Add SYNAPSE-US Node
|
146
|
+
|
147
|
+
synapse_node_payload = {
|
148
|
+
"type" => "SYNAPSE-US",
|
149
|
+
"info" => {
|
150
|
+
"nickname" => "My Synapse Wallet"
|
151
|
+
},
|
152
|
+
"extra" => {
|
153
|
+
"supp_id" => "123sa"
|
154
|
+
}
|
155
|
+
}
|
156
|
+
|
157
|
+
synapse_node_response = client.nodes.add(payload: synapse_node_payload)
|
158
|
+
|
159
|
+
|
160
|
+
# Add ACH-US node through account login
|
161
|
+
|
162
|
+
login_payload = {
|
163
|
+
"type" => "ACH-US",
|
164
|
+
"info" => {
|
165
|
+
"bank_id" => "synapse_good",
|
166
|
+
"bank_pw" => "test1234",
|
167
|
+
"bank_name" => "fake"
|
168
|
+
}
|
169
|
+
}
|
170
|
+
|
171
|
+
login_response = client.nodes.add(payload: login_payload)
|
172
|
+
|
173
|
+
|
174
|
+
# Verify ACH-US Node via MFA
|
175
|
+
|
176
|
+
mfa_payload = {
|
177
|
+
"access_token" => ACCESS_TOKEN_IN_LOGIN_RESPONSE,
|
178
|
+
"mfa_answer" => "test_answer"
|
179
|
+
}
|
180
|
+
|
181
|
+
mfa_response = client.nodes.verify(payload: mfa_payload)
|
182
|
+
|
183
|
+
|
184
|
+
# Add ACH-US Node through Account and Routing Number Details
|
185
|
+
|
186
|
+
acct_rout_payload = {
|
187
|
+
"type" => "ACH-US",
|
188
|
+
"info" => {
|
189
|
+
"nickname" => "Ruby Library Savings Account",
|
190
|
+
"name_on_account" => "Ruby Library",
|
191
|
+
"account_num" => "72347235423",
|
192
|
+
"routing_num" => "051000017",
|
193
|
+
"type" => "PERSONAL",
|
194
|
+
"class" => "CHECKING"
|
195
|
+
},
|
196
|
+
"extra" => {
|
197
|
+
"supp_id" => "123sa"
|
198
|
+
}
|
199
|
+
}
|
200
|
+
|
201
|
+
acct_rout_response = client.nodes.add(payload: acct_rout_payload)
|
202
|
+
|
203
|
+
|
204
|
+
# Verify ACH-US Node via Micro-Deposits
|
205
|
+
|
206
|
+
micro_payload = {
|
207
|
+
"micro" => [0.1,0.1]
|
208
|
+
}
|
209
|
+
|
210
|
+
micro_response = client.nodes.verify(node_id: NODE_ID, payload: micro_payload)
|
211
|
+
|
212
|
+
# Delete a Node
|
213
|
+
|
214
|
+
delete_response = client.nodes.delete(node_id: NODE_ID)
|
215
|
+
|
216
|
+
```
|
217
|
+
|
218
|
+
## Transaction API Calls
|
219
|
+
|
220
|
+
```ruby
|
221
|
+
|
222
|
+
|
223
|
+
# Get All Transactions
|
224
|
+
|
225
|
+
transactions_response = client.trans.get(node_id: NODE_ID)
|
226
|
+
|
227
|
+
|
228
|
+
#Create a Transaction
|
229
|
+
|
230
|
+
trans_payload = {
|
231
|
+
"to" => {
|
232
|
+
"type" => "SYNAPSE-US",
|
233
|
+
"id" => "560adb4e86c27331bb5ac86e"
|
234
|
+
},
|
235
|
+
"amount" => {
|
236
|
+
"amount" => 1.10,
|
237
|
+
"currency" => "USD"
|
238
|
+
},
|
239
|
+
"extra" => {
|
240
|
+
"supp_id" => "1283764wqwsdd34wd13212",
|
241
|
+
"note" => "Deposit to bank account",
|
242
|
+
"webhook" => "http => //requestb.in/q94kxtq9",
|
243
|
+
"process_on" => 1,
|
244
|
+
"ip" => "192.168.0.1"
|
245
|
+
},
|
246
|
+
"fees" => [{
|
247
|
+
"fee" => 1.00,
|
248
|
+
"note" => "Facilitator Fee",
|
249
|
+
"to" => {
|
250
|
+
"id" => "55d9287486c27365fe3776fb"
|
251
|
+
}
|
252
|
+
}]
|
253
|
+
}
|
254
|
+
|
255
|
+
create_response = client.trans.create(node_id: NODE_ID, payload: trans_payload)
|
256
|
+
|
257
|
+
|
258
|
+
# Get a Transaction
|
259
|
+
|
260
|
+
transaction_response = client.trans.get(node_id: NODE_ID, trans_id: TRANS_ID)
|
261
|
+
|
262
|
+
|
263
|
+
# Update Transaction
|
264
|
+
|
265
|
+
update_payload = {
|
266
|
+
"comment" => "hi"
|
267
|
+
}
|
268
|
+
|
269
|
+
update_response = client.trans.update(node_id: NODE_ID, trans_id: TRANS_ID, payload: update_payload)
|
270
|
+
|
271
|
+
|
272
|
+
# Delete Transaction
|
273
|
+
|
274
|
+
delete_trans_response = client.trans.delete(node_id: NODE_ID, trans_id: TRANS_ID)
|
275
|
+
|
276
|
+
```
|