synapse_pay_rest 0.0.15 → 2.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 +4 -4
- data/.gitignore +7 -2
- data/Gemfile.lock +10 -6
- data/LICENSE +20 -0
- data/README.md +80 -22
- data/lib/synapse_pay_rest.rb +65 -21
- data/lib/synapse_pay_rest/api/nodes.rb +93 -19
- data/lib/synapse_pay_rest/api/transactions.rb +103 -0
- data/lib/synapse_pay_rest/api/users.rb +101 -41
- data/lib/synapse_pay_rest/client.rb +49 -0
- data/lib/synapse_pay_rest/error.rb +8 -2
- data/lib/synapse_pay_rest/http_client.rb +94 -27
- data/lib/synapse_pay_rest/models/node/ach_us_node.rb +111 -0
- data/lib/synapse_pay_rest/models/node/base_node.rb +192 -0
- data/lib/synapse_pay_rest/models/node/eft_ind_node.rb +19 -0
- data/lib/synapse_pay_rest/models/node/eft_node.rb +27 -0
- data/lib/synapse_pay_rest/models/node/eft_np_node.rb +19 -0
- data/lib/synapse_pay_rest/models/node/iou_node.rb +27 -0
- data/lib/synapse_pay_rest/models/node/node.rb +99 -0
- data/lib/synapse_pay_rest/models/node/reserve_us_node.rb +23 -0
- data/lib/synapse_pay_rest/models/node/synapse_ind_node.rb +22 -0
- data/lib/synapse_pay_rest/models/node/synapse_node.rb +25 -0
- data/lib/synapse_pay_rest/models/node/synapse_np_node.rb +22 -0
- data/lib/synapse_pay_rest/models/node/synapse_us_node.rb +23 -0
- data/lib/synapse_pay_rest/models/node/unverified_node.rb +73 -0
- data/lib/synapse_pay_rest/models/node/wire_int_node.rb +23 -0
- data/lib/synapse_pay_rest/models/node/wire_node.rb +38 -0
- data/lib/synapse_pay_rest/models/node/wire_us_node.rb +23 -0
- data/lib/synapse_pay_rest/models/transaction/transaction.rb +212 -0
- data/lib/synapse_pay_rest/models/user/base_document.rb +346 -0
- data/lib/synapse_pay_rest/models/user/document.rb +71 -0
- data/lib/synapse_pay_rest/models/user/physical_document.rb +29 -0
- data/lib/synapse_pay_rest/models/user/question.rb +45 -0
- data/lib/synapse_pay_rest/models/user/social_document.rb +7 -0
- data/lib/synapse_pay_rest/models/user/user.rb +593 -0
- data/lib/synapse_pay_rest/models/user/virtual_document.rb +77 -0
- data/lib/synapse_pay_rest/version.rb +2 -1
- data/samples.md +391 -219
- data/synapse_pay_rest.gemspec +13 -12
- metadata +78 -24
- data/lib/synapse_pay_rest/api/trans.rb +0 -38
@@ -0,0 +1,77 @@
|
|
1
|
+
module SynapsePayRest
|
2
|
+
# Represents virtual documents that can be added to a base document.
|
3
|
+
#
|
4
|
+
# @see https://docs.synapsepay.com/docs/user-resources#section-virtual-document-types
|
5
|
+
# virtual document types
|
6
|
+
class VirtualDocument < Document
|
7
|
+
# @!attribute [r] question_set
|
8
|
+
# @return [SynapsePayRest::Array<SynapsePayRest::Question>] questions/answer choices returned when document status is MFA|PENDING
|
9
|
+
attr_reader :question_set
|
10
|
+
|
11
|
+
class << self
|
12
|
+
# @note Do not call this method directly.
|
13
|
+
def create_from_response(data)
|
14
|
+
virtual_doc = super(data)
|
15
|
+
require 'pry';
|
16
|
+
virtual_doc.add_question_set(data['meta']['question_set']) if data['meta']
|
17
|
+
virtual_doc
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# @note It should not be necessary to call this method directly.
|
22
|
+
def initialize(**options)
|
23
|
+
super(**options)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Submits the question/answer selections to the API to attempt to verify
|
27
|
+
# the virtual document.
|
28
|
+
#
|
29
|
+
# @return [SynapsePayRest::VirtualDocument] (self)
|
30
|
+
#
|
31
|
+
# @todo should raise error if any questions aren't answered yet.
|
32
|
+
def submit_kba
|
33
|
+
user = base_document.user
|
34
|
+
response = user.client.users.update(payload: payload_for_kba)
|
35
|
+
user = User.create_from_response(user.client, response)
|
36
|
+
base_doc = user.base_documents.find { |doc| doc.id == base_document.id }
|
37
|
+
ssn_doc = base_doc.virtual_documents.find { |doc| doc.id == id }
|
38
|
+
end
|
39
|
+
|
40
|
+
# Maps question set from response to Question objects.
|
41
|
+
def add_question_set(question_set_data)
|
42
|
+
questions = question_set_data['questions'].map do |question_info|
|
43
|
+
# re-map question/answer hash structure
|
44
|
+
answers = {}
|
45
|
+
question_info['answers'].each do |answer_hash|
|
46
|
+
answers[answer_hash['id']] = answer_hash['answer']
|
47
|
+
end
|
48
|
+
|
49
|
+
Question.new(
|
50
|
+
id: question_info['id'],
|
51
|
+
question: question_info['question'],
|
52
|
+
answers: answers
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
@question_set = questions
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def payload_for_kba
|
62
|
+
{
|
63
|
+
'documents' => [{
|
64
|
+
'id' => base_document.id,
|
65
|
+
'virtual_docs' => [{
|
66
|
+
'id' => id,
|
67
|
+
'meta' => {
|
68
|
+
'question_set' => {
|
69
|
+
'answers' => question_set.map(&:to_hash)
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}]
|
73
|
+
}]
|
74
|
+
}
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/samples.md
CHANGED
@@ -3,303 +3,475 @@
|
|
3
3
|
```ruby
|
4
4
|
require 'synapse_pay_rest'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
'
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
'
|
6
|
+
args = {
|
7
|
+
# synapse client_id
|
8
|
+
client_id: ENV.fetch('CLIENT_ID'),
|
9
|
+
# synapse client_secret
|
10
|
+
client_secret: ENV.fetch('CLIENT_SECRET'),
|
11
|
+
# a hashed value, either unique to user or static for app
|
12
|
+
fingerprint: ENV.fetch('FINGERPRINT'),
|
13
|
+
# the user's IP
|
14
|
+
ip_address: '127.0.0.1',
|
15
|
+
# (optional) requests go to sandbox endpoints if true
|
16
|
+
development_mode: true,
|
17
|
+
# (optional) if true logs requests to stdout
|
18
|
+
logging: true,
|
19
|
+
# (optional) file path to write logs to
|
20
|
+
log_to: nil
|
13
21
|
}
|
14
22
|
|
15
|
-
|
23
|
+
client = SynapsePayRest::Client.new(args)
|
24
|
+
# => #<SynapsePayRest::Client>
|
16
25
|
|
17
|
-
|
26
|
+
```
|
27
|
+
|
28
|
+
## User Methods
|
29
|
+
|
30
|
+
#### All Users
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
|
34
|
+
args = {
|
35
|
+
client: client,
|
36
|
+
# (optional) uses API default unless specified
|
37
|
+
page: 1,
|
38
|
+
# (optional) uses API default of 20 unless specified, larger values take longer
|
39
|
+
per_page: 50,
|
40
|
+
# (optional) filters by name/email match
|
41
|
+
query: nil,
|
42
|
+
}
|
43
|
+
|
44
|
+
users = SynapsePayRest::User.all(args)
|
45
|
+
# => [#<SynapsePayRest::User>, #<SynapsePayRest::User>, ...]
|
18
46
|
|
19
47
|
```
|
20
48
|
|
21
|
-
|
49
|
+
#### Find a User by User ID
|
22
50
|
|
23
51
|
```ruby
|
24
52
|
|
53
|
+
user = SynapsePayRest::User.find(client: client, id: '57e97ab786c2737f4ccd4dc1')
|
54
|
+
# => #<SynapsePayRest::User>
|
25
55
|
|
26
|
-
|
27
|
-
|
28
|
-
users_response = client.users.get
|
29
|
-
|
30
|
-
|
31
|
-
# Create User
|
32
|
-
|
33
|
-
create_payload = {
|
34
|
-
"logins" => [
|
35
|
-
{
|
36
|
-
"email" => "rubyTest@synapsepay.com",
|
37
|
-
"password" => "test1234",
|
38
|
-
"read_only" => false
|
39
|
-
}
|
40
|
-
],
|
41
|
-
"phone_numbers" => [
|
42
|
-
"901.111.1111"
|
43
|
-
],
|
44
|
-
"legal_names" => [
|
45
|
-
"RUBY TEST USER"
|
46
|
-
],
|
47
|
-
"extra" => {
|
48
|
-
"note" => "Interesting user",
|
49
|
-
"supp_id" => "122eddfgbeafrfvbbb",
|
50
|
-
"is_business" => false
|
51
|
-
}
|
52
|
-
}
|
56
|
+
```
|
53
57
|
|
54
|
-
|
58
|
+
#### Search for a User by Name/Email
|
55
59
|
|
60
|
+
```ruby
|
61
|
+
|
62
|
+
users = SynapsePayRest::User.search(client: client, query: 'Steven')
|
63
|
+
# => [#<SynapsePayRest::User>, #<SynapsePayRest::User>, ...]
|
64
|
+
|
65
|
+
```
|
66
|
+
|
67
|
+
#### Create User
|
56
68
|
|
57
|
-
|
69
|
+
```ruby
|
58
70
|
|
59
|
-
|
71
|
+
user_create_settings = {
|
72
|
+
client: client,
|
73
|
+
logins: [{email: 'steven@synapsepay.com'}],
|
74
|
+
phone_numbers: ['555-555-5555'],
|
75
|
+
legal_names: ['Steven Broderick']
|
76
|
+
}
|
60
77
|
|
78
|
+
user = SynapsePayRest::User.create(user_create_settings)
|
79
|
+
# => #<SynapsePayRest::User>
|
61
80
|
|
81
|
+
```
|
62
82
|
|
63
|
-
|
83
|
+
#### Update a User's Personal Info
|
64
84
|
|
65
|
-
|
66
|
-
|
85
|
+
Note: this returns a new instance, so remember to reassign the user variable to the method output.
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
|
89
|
+
user_update_settings = {
|
90
|
+
login: {email: 'newemail@gmail.com'}, # add a login email
|
91
|
+
phone_number: '415-555-5555', # add a phone number
|
92
|
+
legal_name: 'Big Bird', # add a legal name
|
93
|
+
remove_phone_number: '555-555-5555', # remove a phone number
|
94
|
+
remove_login: nil # remove a login email
|
67
95
|
}
|
68
96
|
|
69
|
-
|
97
|
+
# reassign user to the output because it returns a new instance
|
98
|
+
user = user.update(args)
|
99
|
+
# => #<SynapsePayRest::User>
|
100
|
+
|
101
|
+
```
|
70
102
|
|
103
|
+
#### Add CIP Base Document to a User
|
71
104
|
|
72
|
-
|
105
|
+
##### a) User#create_base_document
|
106
|
+
|
107
|
+
```ruby
|
73
108
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
109
|
+
args = {
|
110
|
+
email: 'steven@synapsepay.com',
|
111
|
+
phone_number: '415-555-5555',
|
112
|
+
ip: '127.0.0.1',
|
113
|
+
name: 'Steven Broderick',
|
114
|
+
aka: 'Steven Broderick',
|
115
|
+
entity_type: 'NOT_KNOWN',
|
116
|
+
entity_scope: 'Doctor',
|
117
|
+
birth_day: 3,
|
118
|
+
birth_month: 19,
|
119
|
+
birth_year: 1912,
|
120
|
+
address_street: '123 Synapse St',
|
121
|
+
address_city: 'San Francisco',
|
122
|
+
address_subdivision: 'CA',
|
123
|
+
address_postal_code: '94114',
|
124
|
+
address_country_code: 'US'
|
85
125
|
}
|
86
126
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
'document_value' => '111-111-3333',
|
115
|
-
'document_type' => 'SSN'
|
116
|
-
}],
|
117
|
-
'physical_docs' => [{
|
118
|
-
'document_value' => govt_id_attachment,
|
119
|
-
'document_type' => 'GOVT_ID'
|
120
|
-
},
|
121
|
-
{
|
122
|
-
'document_value' => selfie_attachment,
|
123
|
-
'document_type' => 'SELFIE'
|
124
|
-
}],
|
125
|
-
'social_docs' => [{
|
126
|
-
'document_value' => 'https://www.facebook.com/sankaet',
|
127
|
-
'document_type' => 'FACEBOOK'
|
128
|
-
}]
|
129
|
-
}]
|
127
|
+
# reassign user to the output because it returns a new instance
|
128
|
+
base_document = user.create_base_document(args)
|
129
|
+
# => #<SynapsePayRest::BaseDocument>
|
130
|
+
|
131
|
+
```
|
132
|
+
|
133
|
+
##### b) BaseDocument#create
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
|
137
|
+
args = {
|
138
|
+
user: user,
|
139
|
+
email: 'steven@synapsepay.com',
|
140
|
+
phone_number: '415-555-5555',
|
141
|
+
ip: '127.0.0.1',
|
142
|
+
name: 'Steven Broderick',
|
143
|
+
aka: 'Steven Broderick',
|
144
|
+
entity_type: 'NOT_KNOWN',
|
145
|
+
entity_scope: 'Doctor',
|
146
|
+
birth_day: 3,
|
147
|
+
birth_month: 19,
|
148
|
+
birth_year: 1912,
|
149
|
+
address_street: '123 Synapse St',
|
150
|
+
address_city: 'San Francisco',
|
151
|
+
address_subdivision: 'CA',
|
152
|
+
address_postal_code: '94114',
|
153
|
+
address_country_code: 'US'
|
130
154
|
}
|
131
155
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
'answers' => [
|
149
|
-
{ 'question_id' => 1, 'answer_id' => 1 },
|
150
|
-
{ 'question_id' => 2, 'answer_id' => 1 },
|
151
|
-
{ 'question_id' => 3, 'answer_id' => 1 },
|
152
|
-
{ 'question_id' => 4, 'answer_id' => 1 },
|
153
|
-
{ 'question_id' => 5, 'answer_id' => 1 }
|
154
|
-
]
|
155
|
-
}
|
156
|
-
}
|
157
|
-
}]
|
158
|
-
}]
|
156
|
+
# reassign base_doc to the output because it returns a new instance
|
157
|
+
base_doc = SynapsePayRest::BaseDocument.create(args)
|
158
|
+
# => #<SynapsePayRest::BaseDocument>
|
159
|
+
|
160
|
+
# reassign user to this if you need the updated user
|
161
|
+
user = base_doc.user
|
162
|
+
|
163
|
+
```
|
164
|
+
|
165
|
+
#### Update User's Existing Base Document
|
166
|
+
|
167
|
+
```ruby
|
168
|
+
|
169
|
+
things_to_update = {
|
170
|
+
entity_scope: 'Lawyer',
|
171
|
+
birth_day: 22
|
159
172
|
}
|
160
173
|
|
161
|
-
|
174
|
+
base_doc = base_doc.update(things_to_update)
|
175
|
+
# => #<SynapsePayRest::BaseDocument>
|
162
176
|
|
177
|
+
```
|
163
178
|
|
164
|
-
|
179
|
+
#### Add a Physical Document to a CIP Base Document
|
165
180
|
|
166
181
|
```ruby
|
167
182
|
|
183
|
+
physical_doc = SynapsePayRest::PhysicalDocument.create(
|
184
|
+
type: 'GOVT_ID',
|
185
|
+
value: '/path/to/file.png'
|
186
|
+
)
|
168
187
|
|
169
|
-
#
|
188
|
+
# reassign base_doc to the output because it returns a new instance
|
189
|
+
base_doc = base_doc.add_physical_documents([physical_doc])
|
190
|
+
# => #<SynapsePayRest::BaseDocument>
|
170
191
|
|
171
|
-
|
192
|
+
```
|
172
193
|
|
194
|
+
#### Add a Social Document to a CIP Base Document
|
173
195
|
|
174
|
-
|
196
|
+
```ruby
|
175
197
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
},
|
181
|
-
"extra" => {
|
182
|
-
"supp_id" => "123sa"
|
183
|
-
}
|
184
|
-
}
|
198
|
+
social_doc = SynapsePayRest::SocialDocument.create(
|
199
|
+
type: 'FACEBOOK',
|
200
|
+
value: 'facebook.com/sankaet'
|
201
|
+
)
|
185
202
|
|
186
|
-
|
203
|
+
# reassign base_doc to the output because it returns a new instance
|
204
|
+
base_doc = base_doc.add_social_documents([social_doc])
|
205
|
+
# => #<SynapsePayRest::BaseDocument>
|
187
206
|
|
207
|
+
```
|
188
208
|
|
189
|
-
|
209
|
+
#### Add a Virtual Document to a CIP Base Document
|
190
210
|
|
191
|
-
|
192
|
-
"type" => "ACH-US",
|
193
|
-
"info" => {
|
194
|
-
"bank_id" => "synapse_good",
|
195
|
-
"bank_pw" => "test1234",
|
196
|
-
"bank_name" => "fake"
|
197
|
-
}
|
198
|
-
}
|
211
|
+
```ruby
|
199
212
|
|
200
|
-
|
213
|
+
virtual_doc = SynapsePayRest::VirtualDocument.create(
|
214
|
+
type: 'SSN',
|
215
|
+
value: '3333'
|
216
|
+
)
|
201
217
|
|
218
|
+
# reassign base_doc to the output because it returns a new instance
|
219
|
+
base_doc = base_doc.add_virtual_documents([virtual_doc])
|
220
|
+
# => #<SynapsePayRest::BaseDocument>
|
202
221
|
|
203
|
-
|
222
|
+
```
|
204
223
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
224
|
+
##### Answer KBA Questions for Virtual Document
|
225
|
+
|
226
|
+
If a Virtual Document is returned with status **MFA|PENDING**, you will need to have the user answer some questions:
|
227
|
+
|
228
|
+
```ruby
|
229
|
+
|
230
|
+
# check for any virtual docs with SUBMITTED|MFA_PENDING status
|
231
|
+
virtual_doc = base_doc.virtual_documents.find do |doc|
|
232
|
+
doc.status == 'SUBMITTED|MFA_PENDING'
|
233
|
+
end
|
234
|
+
|
235
|
+
question_set = virtual_doc.question_set
|
236
|
+
# => [#<SynapsePayRest::Question>, #<SynapsePayRest::Question>, ...]
|
237
|
+
|
238
|
+
# follow this flow for each question in question_set
|
239
|
+
question = question_set.first
|
240
|
+
|
241
|
+
question_text = question.question
|
242
|
+
# => "Which one of the following zip codes is associated with you?"
|
243
|
+
|
244
|
+
question.answers
|
245
|
+
# => {1=>"49230", 2=>"49209", 3=>"49268", 4=>"49532", 5=>"None Of The Above"}
|
246
|
+
|
247
|
+
question.choice = 1
|
248
|
+
|
249
|
+
# when finished answering all questions in question_set
|
250
|
+
virtual_doc = virtual_doc.submit_kba
|
251
|
+
|
252
|
+
# reassign this if you need the updated base doc
|
253
|
+
base_doc = virtual_doc.base_document
|
254
|
+
|
255
|
+
```
|
256
|
+
|
257
|
+
|
258
|
+
## Node Methods
|
259
|
+
|
260
|
+
#### All Nodes for a User
|
261
|
+
|
262
|
+
##### a) User#nodes
|
263
|
+
|
264
|
+
```ruby
|
265
|
+
|
266
|
+
nodes = user.nodes(page: 2, per_page: 5, type: 'ACH-US')
|
267
|
+
# => [#<SynapsePayRest::AchUsNode>, #<SynapsePayRest::AchUsNode>, ...]
|
268
|
+
|
269
|
+
```
|
270
|
+
|
271
|
+
##### b) Node#all
|
272
|
+
|
273
|
+
```ruby
|
274
|
+
|
275
|
+
nodes = SynapsePayRest::Node.all(user: user, page: 2, per_page: 5)
|
276
|
+
# => [#<SynapsePayRest::AchUsNode>, #<SynapsePayRest::SynapseUsNode>, ...]
|
277
|
+
|
278
|
+
```
|
279
|
+
|
280
|
+
#### Find a User's Node by Node ID
|
281
|
+
|
282
|
+
##### a) User#find_node
|
209
283
|
|
210
|
-
|
284
|
+
```ruby
|
285
|
+
|
286
|
+
node = user.find_node(id: '1a3efa1231as2f')
|
287
|
+
# => #<SynapsePayRest::EftNpNode>
|
288
|
+
|
289
|
+
```
|
290
|
+
|
291
|
+
##### b) Node#find
|
292
|
+
|
293
|
+
```ruby
|
294
|
+
|
295
|
+
node = SynapsePayRest::Node.find(user: user, id: '1a3efa1231as2f')
|
296
|
+
# => #<SynapsePayRest::EftNpNode>
|
297
|
+
|
298
|
+
```
|
211
299
|
|
300
|
+
#### Create ACH-US Node(s) via Bank Login
|
212
301
|
|
213
|
-
|
302
|
+
Returns a collection of `AchUsNode`s associated with the account unless bank requires MFA. Can also use `AchUsNode.create_via_bank_login` with the addition of a `user` argument.
|
214
303
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
"routing_num" => "051000017",
|
222
|
-
"type" => "PERSONAL",
|
223
|
-
"class" => "CHECKING"
|
224
|
-
},
|
225
|
-
"extra" => {
|
226
|
-
"supp_id" => "123sa"
|
227
|
-
}
|
304
|
+
```ruby
|
305
|
+
|
306
|
+
login_info = {
|
307
|
+
bank_name: 'bofa',
|
308
|
+
username: 'synapse_good',
|
309
|
+
password: 'test1234'
|
228
310
|
}
|
229
311
|
|
230
|
-
|
312
|
+
nodes = user.create_ach_us_nodes_via_bank_login(login_info)
|
313
|
+
# => [#<SynapsePayRest::AchUsNode>, ...] if no MFA
|
314
|
+
# => SynapsePayRest::UnverifiedNode if MFA
|
315
|
+
|
316
|
+
```
|
317
|
+
|
318
|
+
##### Verify Bank Login MFA
|
319
|
+
|
320
|
+
If the bank requires MFA, you will need to resolve the MFA question(s):
|
321
|
+
|
322
|
+
```ruby
|
323
|
+
|
324
|
+
nodes.mfa_verified
|
325
|
+
# => false
|
326
|
+
|
327
|
+
nodes.mfa_message
|
328
|
+
# => "Enter the code we texted to your phone number."
|
231
329
|
|
330
|
+
nodes = nodes.answer_mfa('test_answer')
|
331
|
+
# => [#<SynapsePayRest::AchUsNode>, ...] if successful
|
332
|
+
# => SynapsePayRest::UnverifiedNode if additional MFA question (check node.mfa_message)
|
333
|
+
# => raises SynapsePayRest::Error if incorrect answer
|
232
334
|
|
233
|
-
|
335
|
+
nodes.mfa_verified
|
336
|
+
# => true
|
234
337
|
|
235
|
-
|
236
|
-
|
338
|
+
```
|
339
|
+
|
340
|
+
#### Create ACH-US Node via Account/Routing Number
|
341
|
+
|
342
|
+
Can also use `AchUsNode.create` with the addition of a `user` argument.
|
343
|
+
|
344
|
+
```ruby
|
345
|
+
|
346
|
+
account_info = {
|
347
|
+
nickname: 'Primary Joint Checking',
|
348
|
+
account_number: '2222222222',
|
349
|
+
routing_number: '051000017',
|
350
|
+
account_type: 'PERSONAL',
|
351
|
+
account_class: 'CHECKING'
|
237
352
|
}
|
238
353
|
|
239
|
-
|
354
|
+
node = user.create_ach_us_node(account_info)
|
355
|
+
# => #<SynapsePayRest::AchUsNode>
|
356
|
+
|
357
|
+
```
|
240
358
|
|
241
|
-
|
359
|
+
##### Verify Microdeposits
|
242
360
|
|
243
|
-
|
361
|
+
`ACH-US Node`s added by account/routing must be verified with microdeposits:
|
362
|
+
|
363
|
+
```ruby
|
364
|
+
|
365
|
+
node = node.verify_microdeposits(amount1: 0.1, amount2: 0.1)
|
366
|
+
# => #<SynapsePayRest::AchUsNode>
|
244
367
|
|
245
368
|
```
|
246
369
|
|
247
|
-
|
370
|
+
#### Deactivate a Node
|
371
|
+
|
372
|
+
This deactivates the node. It does not automatically cancel any transactions already underway.
|
248
373
|
|
249
374
|
```ruby
|
250
375
|
|
376
|
+
node.deactivate
|
377
|
+
# => :success
|
251
378
|
|
252
|
-
|
253
|
-
|
254
|
-
transactions_response = client.trans.get(node_id: NODE_ID)
|
255
|
-
|
256
|
-
|
257
|
-
#Create a Transaction
|
258
|
-
|
259
|
-
trans_payload = {
|
260
|
-
"to" => {
|
261
|
-
"type" => "SYNAPSE-US",
|
262
|
-
"id" => "560adb4e86c27331bb5ac86e"
|
263
|
-
},
|
264
|
-
"amount" => {
|
265
|
-
"amount" => 1.10,
|
266
|
-
"currency" => "USD"
|
267
|
-
},
|
268
|
-
"extra" => {
|
269
|
-
"supp_id" => "1283764wqwsdd34wd13212",
|
270
|
-
"note" => "Deposit to bank account",
|
271
|
-
"webhook" => "http => //requestb.in/q94kxtq9",
|
272
|
-
"process_on" => 1,
|
273
|
-
"ip" => "192.168.0.1"
|
274
|
-
},
|
275
|
-
"fees" => [{
|
276
|
-
"fee" => 1.00,
|
277
|
-
"note" => "Facilitator Fee",
|
278
|
-
"to" => {
|
279
|
-
"id" => "55d9287486c27365fe3776fb"
|
280
|
-
}
|
281
|
-
}]
|
282
|
-
}
|
379
|
+
```
|
283
380
|
|
284
|
-
create_response = client.trans.create(node_id: NODE_ID, payload: trans_payload)
|
285
381
|
|
382
|
+
## Transaction Methods
|
286
383
|
|
287
|
-
|
384
|
+
#### All Transactions from a Node
|
288
385
|
|
289
|
-
|
386
|
+
##### a) Node#transactions
|
290
387
|
|
388
|
+
```ruby
|
291
389
|
|
292
|
-
|
390
|
+
transactions = node.transactions(page: 1, per_page: 15)
|
391
|
+
# => [#<SynapsePayRest::Transaction>, #<SynapsePayRest::Transaction>, ...]
|
293
392
|
|
294
|
-
|
295
|
-
|
393
|
+
```
|
394
|
+
|
395
|
+
##### b) Transaction#all
|
396
|
+
|
397
|
+
```ruby
|
398
|
+
|
399
|
+
transactions = SynapsePayRest::Transaction.all(node: node, page: 1, per_page: 15)
|
400
|
+
# => [#<SynapsePayRest::Transaction>, #<SynapsePayRest::Transaction>, ...]
|
401
|
+
|
402
|
+
```
|
403
|
+
|
404
|
+
#### Find a Node's Transaction by ID
|
405
|
+
|
406
|
+
##### a) Node#find_transaction
|
407
|
+
|
408
|
+
```ruby
|
409
|
+
|
410
|
+
transaction = node.find_transaction(id: '167e11516')
|
411
|
+
# => #<SynapsePayRest::Transaction>
|
412
|
+
|
413
|
+
```
|
414
|
+
|
415
|
+
##### b) Transaction#find
|
416
|
+
|
417
|
+
```ruby
|
418
|
+
|
419
|
+
transaction = SynapsePayRest::Transaction.find(node: node, id: '57fab7d186c2733525dd7eac')
|
420
|
+
# => #<SynapsePayRest::Transaction>
|
421
|
+
|
422
|
+
```
|
423
|
+
|
424
|
+
#### Create a Transaction
|
425
|
+
|
426
|
+
##### a) Node#create_transaction
|
427
|
+
|
428
|
+
```ruby
|
429
|
+
|
430
|
+
transaction_settings = {
|
431
|
+
to_type: 'ACH-US',
|
432
|
+
to_id: '57fab4b286c2732210c73486',
|
433
|
+
amount: 50.0,
|
434
|
+
currency: 'USD',
|
435
|
+
ip: '127.0.0.1'
|
296
436
|
}
|
297
437
|
|
298
|
-
|
438
|
+
transaction = node.create_transaction(transaction_settings)
|
439
|
+
# => #<SynapsePayRest::Transaction>
|
440
|
+
|
441
|
+
```
|
442
|
+
|
443
|
+
##### b) Transaction#create
|
299
444
|
|
445
|
+
```ruby
|
446
|
+
|
447
|
+
transaction_settings = {
|
448
|
+
node: node,
|
449
|
+
to_type: 'ACH-US',
|
450
|
+
to_id: '57fab4b286c2732210c73486',
|
451
|
+
amount: 50.0,
|
452
|
+
currency: 'USD',
|
453
|
+
ip: '127.0.0.1'
|
454
|
+
}
|
300
455
|
|
301
|
-
|
456
|
+
transaction = SynapsePayRest::Transaction.create(transaction_settings)
|
457
|
+
# => #<SynapsePayRest::Transaction>
|
458
|
+
|
459
|
+
```
|
460
|
+
|
461
|
+
#### Add a Comment to a Transaction's Status
|
462
|
+
|
463
|
+
```ruby
|
464
|
+
|
465
|
+
transaction = transaction.add_comment('this is my favorite transaction')
|
466
|
+
# => #<SynapsePayRest::Transaction>
|
467
|
+
|
468
|
+
```
|
469
|
+
|
470
|
+
#### Cancel a Transaction
|
471
|
+
|
472
|
+
```ruby
|
302
473
|
|
303
|
-
|
474
|
+
transaction = transaction.cancel
|
475
|
+
# => #<SynapsePayRest::Transaction>
|
304
476
|
|
305
477
|
```
|