finicity 0.1.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.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +69 -0
  7. data/Rakefile +10 -0
  8. data/finicity.gemspec +31 -0
  9. data/lib/finicity.rb +42 -0
  10. data/lib/finicity/client.rb +350 -0
  11. data/lib/finicity/configuration.rb +13 -0
  12. data/lib/finicity/errors.rb +62 -0
  13. data/lib/finicity/logger.rb +19 -0
  14. data/lib/finicity/railtie.rb +22 -0
  15. data/lib/finicity/v1.rb +29 -0
  16. data/lib/finicity/v1/request/activate_accounts.rb +73 -0
  17. data/lib/finicity/v1/request/activate_accounts_with_mfa.rb +88 -0
  18. data/lib/finicity/v1/request/add_customer.rb +54 -0
  19. data/lib/finicity/v1/request/delete_customer.rb +45 -0
  20. data/lib/finicity/v1/request/discover_accounts.rb +71 -0
  21. data/lib/finicity/v1/request/discover_accounts_with_mfa.rb +87 -0
  22. data/lib/finicity/v1/request/get_accounts.rb +50 -0
  23. data/lib/finicity/v1/request/get_customers.rb +43 -0
  24. data/lib/finicity/v1/request/get_customers_by_username.rb +52 -0
  25. data/lib/finicity/v1/request/get_institution.rb +45 -0
  26. data/lib/finicity/v1/request/get_institutions.rb +45 -0
  27. data/lib/finicity/v1/request/get_login_form.rb +47 -0
  28. data/lib/finicity/v1/request/get_transactions.rb +60 -0
  29. data/lib/finicity/v1/request/interactive_refresh_account.rb +51 -0
  30. data/lib/finicity/v1/request/interactive_refresh_account_with_mfa.rb +74 -0
  31. data/lib/finicity/v1/request/refresh_accounts.rb +47 -0
  32. data/lib/finicity/v1/response/accounts.rb +75 -0
  33. data/lib/finicity/v1/response/customers.rb +36 -0
  34. data/lib/finicity/v1/response/error.rb +13 -0
  35. data/lib/finicity/v1/response/institutions.rb +38 -0
  36. data/lib/finicity/v1/response/login_form.rb +29 -0
  37. data/lib/finicity/v1/response/mfa.rb +22 -0
  38. data/lib/finicity/v1/response/transactions.rb +28 -0
  39. data/lib/finicity/v2.rb +7 -0
  40. data/lib/finicity/v2/request/partner_authentication.rb +39 -0
  41. data/lib/finicity/v2/response/partner_authentication.rb +12 -0
  42. data/lib/finicity/version.rb +3 -0
  43. data/spec/finicity/client_spec.rb +527 -0
  44. data/spec/finicity/v1/request/activate_accounts_spec.rb +49 -0
  45. data/spec/finicity/v1/request/activate_accounts_with_mfa_spec.rb +64 -0
  46. data/spec/finicity/v1/request/add_customer_spec.rb +37 -0
  47. data/spec/finicity/v1/request/delete_customer_spec.rb +18 -0
  48. data/spec/finicity/v1/request/discover_accounts_spec.rb +42 -0
  49. data/spec/finicity/v1/request/discover_accounts_with_mfa_spec.rb +59 -0
  50. data/spec/finicity/v1/request/get_accounts_spec.rb +18 -0
  51. data/spec/finicity/v1/request/get_customers_by_username_spec.rb +18 -0
  52. data/spec/finicity/v1/request/get_customers_spec.rb +18 -0
  53. data/spec/finicity/v1/request/get_institution_spec.rb +18 -0
  54. data/spec/finicity/v1/request/get_institutions_spec.rb +18 -0
  55. data/spec/finicity/v1/request/get_login_form_spec.rb +18 -0
  56. data/spec/finicity/v1/request/get_transactions_spec.rb +19 -0
  57. data/spec/finicity/v1/request/interactive_refresh_account_spec.rb +19 -0
  58. data/spec/finicity/v1/request/interactive_refresh_account_with_mfa_spec.rb +38 -0
  59. data/spec/finicity/v1/request/refresh_accounts_spec.rb +18 -0
  60. data/spec/finicity/v1/response/accounts_spec.rb +39 -0
  61. data/spec/finicity/v1/response/customers_spec.rb +19 -0
  62. data/spec/finicity/v1/response/error_spec.rb +19 -0
  63. data/spec/finicity/v1/response/institutions_spec.rb +19 -0
  64. data/spec/finicity/v1/response/login_form_spec.rb +31 -0
  65. data/spec/finicity/v1/response/mfa_spec.rb +23 -0
  66. data/spec/finicity/v1/response/transactions_spec.rb +47 -0
  67. data/spec/finicity/v2/request/partner_authentication_spec.rb +21 -0
  68. data/spec/finicity/v2/response/partner_authentication_spec.rb +15 -0
  69. data/spec/spec_helper.rb +36 -0
  70. metadata +265 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 64b9a11eb9733de5c18f224d22ffc52cf2053921
4
+ data.tar.gz: 7c92ae39b471529d735eadf2acaab8b0f2b8d17a
5
+ SHA512:
6
+ metadata.gz: f01c8b5be48f0b3413126a3e4c8003e3d78dcb8c4652080ec3ffceb259f03f91e462f77e4cc99f79052dea9f8b6bae2f8c8bd3c177107691fde0abf3482eeddb
7
+ data.tar.gz: 358e584e41e566ca2877473391dc9f0a9874d3d8999ff3a44a5f3498aa9ef681ef72d6d99e6832e235fafc08c6abf27780d7507e5d00db82eac9b50edfe0c07a
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .ruby-*
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ *.bundle
20
+ *.so
21
+ *.o
22
+ *.a
23
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in finicity.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Brian Stien
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,69 @@
1
+ finicity
2
+ ========
3
+
4
+ A gem to communicate easily with Finicity's API
5
+
6
+ Installation
7
+ ============
8
+
9
+ gem install finicity
10
+
11
+ or
12
+
13
+ add ```gem 'finicity'``` to your project's Gemfile
14
+
15
+ Configuration
16
+ =============
17
+
18
+ You can configure the finicity gem with the following initializer
19
+
20
+ ```Ruby
21
+ Finicity::V1.configure do |config|
22
+ config.base_url = "https://finicity.com"
23
+ config.partner_key = "key"
24
+ config.username = "moneydesktop"
25
+ config.password = "password"
26
+ end
27
+ ```
28
+
29
+ or within a Rails project
30
+
31
+ add a file named ```config/finicity.yml```
32
+
33
+ with the keys of the same name, and this will be loaded automatically via railtie
34
+
35
+ Usage
36
+ =====
37
+
38
+ In order to connect with Finicity you must first create a session. This is
39
+ done by a partner_authentication POST request, and if successful the response
40
+ will contain a token that is valid for a limited time.
41
+
42
+ Creating a session can be done by making a new client and then authenticating
43
+
44
+ ```Ruby
45
+ client = Finicity::V1::Client.new
46
+ client.authenticate!
47
+ ```
48
+
49
+ If you have an existing session, you can re-open your existing session
50
+
51
+ ```Ruby
52
+ client = Finicity::V1::Client.new("token-123")
53
+ ```
54
+
55
+ If you have an existing session, and also need to re-open a mfa session,
56
+ you can pass both tokens into the client when you create it
57
+
58
+ ```Ruby
59
+ client = Finicity::V1::Client.new("token-123", "mfa_session-123")
60
+ ```
61
+
62
+ Once you have established a session, you can begin to issue commands to the API
63
+ using your finicity client
64
+
65
+ ```Ruby
66
+ client.get_institutions_by_name("Chase")
67
+ ```
68
+
69
+ TODO: link to docs to list all API commands we support
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'special_delivery/gem_tasks'
4
+ require "rspec/core/rake_task"
5
+
6
+ desc "Run specs"
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ desc "Run specs (default)"
10
+ task :default => :spec
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'finicity/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "finicity"
8
+ spec.version = Finicity::VERSION
9
+ spec.authors = ["Moneydesktop"]
10
+ spec.email = ["dev@moneydesktop.com"]
11
+ spec.summary = %q{A gem to communicate easily with Finicity's API}
12
+ spec.description = %q{A gem to communicate easily with Finicity's API}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency 'httpclient', '>= 2.4.0'
22
+ spec.add_dependency 'nokogiri', '>= 1.6.0' # needed so that sax-machine knows which xml parser to use
23
+ spec.add_dependency 'saxomattic', '>= 0.0.3'
24
+
25
+ spec.add_development_dependency 'bundler', '~> 1.6'
26
+ spec.add_development_dependency 'pry'
27
+ spec.add_development_dependency 'rake'
28
+ spec.add_development_dependency 'rspec', '>= 3.1.0'
29
+ spec.add_development_dependency 'simplecov'
30
+ spec.add_development_dependency 'special_delivery'
31
+ end
@@ -0,0 +1,42 @@
1
+ require 'httpclient'
2
+ require 'httpclient/include_client'
3
+ require 'logger'
4
+ require 'saxomattic'
5
+ require 'uri'
6
+
7
+ require 'finicity/version'
8
+
9
+ require 'finicity/client'
10
+ require 'finicity/configuration'
11
+ require 'finicity/errors'
12
+ require 'finicity/logger'
13
+
14
+ require 'finicity/v1'
15
+ require 'finicity/v2'
16
+
17
+ module Finicity
18
+ ##
19
+ # Class methods
20
+ #
21
+ def self.configure
22
+ yield(configuration)
23
+ end
24
+
25
+ def self.configuration
26
+ @config ||= ::Finicity::Configuration.new
27
+ end
28
+
29
+ def self.logger
30
+ configuration.logger
31
+ end
32
+
33
+ # Class aliases
34
+ class << self
35
+ alias_method :config, :configuration
36
+ end
37
+
38
+ # Initialize the config object
39
+ config
40
+ end
41
+
42
+ require "finicity/railtie" if defined?(Rails)
@@ -0,0 +1,350 @@
1
+ module Finicity
2
+ class Client
3
+ ##
4
+ # Attributes
5
+ #
6
+ attr_accessor :mfa_session, :token
7
+
8
+ ##
9
+ # Constructor
10
+ #
11
+ def initialize(token = nil, mfa_session = nil)
12
+ @token = token
13
+ @mfa_session = mfa_session
14
+ end
15
+
16
+ ##
17
+ # Instance Methods
18
+ #
19
+ # The accounts parameter is an array of Finicity::V1::Reponse::Account
20
+ def activate_accounts(customer_id, institution_id, accounts)
21
+ request = ::Finicity::V1::Request::ActivateAccounts.new(token, customer_id, institution_id, accounts)
22
+ request.log_request
23
+ response = request.activate_accounts
24
+ log_response(response)
25
+
26
+ if response.status_code == 200
27
+ @mfa_session = nil
28
+ parsed_response = ::Finicity::V1::Response::Accounts.parse(response.body)
29
+ return parsed_response.accounts
30
+ elsif response.status_code == 203
31
+ @mfa_session = response.headers["MFA-Session"]
32
+ parsed_response = ::Finicity::V1::Response::Mfa.parse(response.body)
33
+ return parsed_response.questions
34
+ else
35
+ raise_generic_error!(response)
36
+ end
37
+ end
38
+
39
+ # The accounts parameter is an array of Finicity::V1::Reponse::Account
40
+ # The mfa_credentials parameter is an array of hashes with keys :text, :answer
41
+ def activate_accounts_with_mfa(customer_id, institution_id, accounts, mfa_credentials)
42
+ request = ::Finicity::V1::Request::ActivateAccountsWithMfa.new(token, mfa_session, customer_id, institution_id, accounts, mfa_credentials)
43
+ request.log_request
44
+ response = request.activate_accounts_with_mfa
45
+ log_response(response)
46
+
47
+ if response.status_code == 200
48
+ @mfa_session = nil
49
+ parsed_response = ::Finicity::V1::Response::Accounts.parse(response.body)
50
+ return parsed_response.accounts
51
+ elsif response.status_code == 203
52
+ @mfa_session = response.headers["MFA-Session"]
53
+ parsed_response = ::Finicity::V1::Response::Mfa.parse(response.body)
54
+ return parsed_response.questions
55
+ else
56
+ raise_generic_error!(response)
57
+ end
58
+ end
59
+
60
+ def add_customer(user_guid)
61
+ request = ::Finicity::V1::Request::AddCustomer.new(token, user_guid)
62
+ request.log_request
63
+ response = request.add_customer
64
+ log_response(response)
65
+
66
+ if response.ok?
67
+ parsed_response = ::Finicity::V1::Response::Customer.parse(response.body)
68
+ return parsed_response
69
+ else
70
+ raise_generic_error!(response)
71
+ end
72
+ end
73
+
74
+ def authenticate!
75
+ request = ::Finicity::V2::Request::PartnerAuthentication.new
76
+ response = request.authenticate
77
+
78
+ if response.ok?
79
+ parsed_response = ::Finicity::V2::Response::PartnerAuthentication.parse(response.body)
80
+ @token = parsed_response.token
81
+ parsed_response
82
+ else
83
+ fail ::Finicity::AuthenticationError.new(response.body, response.status_code)
84
+ end
85
+ end
86
+
87
+ def delete_customer(customer_id)
88
+ request = ::Finicity::V1::Request::DeleteCustomer.new(token, customer_id)
89
+ response = request.delete_customer
90
+
91
+ if response.ok?
92
+ # No data to parse, so return a hash for consistent return type
93
+ return {}
94
+ else
95
+ raise_generic_error!(response)
96
+ end
97
+ end
98
+
99
+ # The login_credentials parameter is an array of hashes with the keys :id, :name, :value
100
+ def discover_accounts(customer_id, institution_id, login_credentials)
101
+ request = ::Finicity::V1::Request::DiscoverAccounts.new(token, customer_id, institution_id, login_credentials)
102
+ request.log_request
103
+ response = request.discover_accounts
104
+ log_response(response)
105
+
106
+ if response.status_code == 200
107
+ @mfa_session = nil
108
+ parsed_response = ::Finicity::V1::Response::Accounts.parse(response.body)
109
+ return parsed_response.accounts
110
+ elsif response.status_code == 203
111
+ @mfa_session = response.headers["MFA-Session"]
112
+ parsed_response = ::Finicity::V1::Response::Mfa.parse(response.body)
113
+ return parsed_response.questions
114
+ else
115
+ raise_generic_error!(response)
116
+ end
117
+ end
118
+
119
+ # The login_credentials parameter is an array of hashes with the keys :id, :name, :value
120
+ # The mfa_credentials parameter is an array of hashes with keys :text, :answer
121
+ def discover_accounts_with_mfa(customer_id, institution_id, login_credentials, mfa_credentials)
122
+ request = ::Finicity::V1::Request::DiscoverAccountsWithMfa.new(token, mfa_session, customer_id, institution_id, login_credentials, mfa_credentials)
123
+ request.log_request
124
+ response = request.discover_accounts_with_mfa
125
+ log_response(response)
126
+
127
+ if response.status_code == 200
128
+ @mfa_session = nil
129
+ parsed_response = ::Finicity::V1::Response::Accounts.parse(response.body)
130
+ return parsed_response.accounts
131
+ elsif response.status_code == 203
132
+ @mfa_session = response.headers["MFA-Session"]
133
+ parsed_response = ::Finicity::V1::Response::Mfa.parse(response.body)
134
+ return parsed_response.questions
135
+ else
136
+ raise_generic_error!(response)
137
+ end
138
+ end
139
+
140
+ def get_accounts(customer_id, institution_id)
141
+ request = ::Finicity::V1::Request::GetAccounts.new(token, customer_id, institution_id)
142
+ request.log_request
143
+ response = request.get_accounts
144
+ log_response(response)
145
+
146
+ if response.ok?
147
+ parsed_response = ::Finicity::V1::Response::Accounts.parse(response.body)
148
+ return parsed_response.accounts
149
+ else
150
+ raise_generic_error!(response)
151
+ end
152
+ end
153
+
154
+ def get_customer_by_username(username)
155
+ request = ::Finicity::V1::Request::GetCustomersByUsername.new(token, username, 1, 1)
156
+ request.log_request
157
+ response = request.get_customers_by_username
158
+ log_response(response)
159
+
160
+ if response.ok?
161
+ parsed_response = ::Finicity::V1::Response::Customers.parse(response.body)
162
+ if parsed_response.found && parsed_response.found > 1
163
+ raise ::Finicity::DuplicateCustomerError.new(username)
164
+ else
165
+ return parsed_response.customers.first
166
+ end
167
+ else
168
+ raise_generic_error!(response)
169
+ end
170
+ end
171
+
172
+ def get_customers_by_username(username, start, limit)
173
+ request = ::Finicity::V1::Request::GetCustomersByUsername.new(token, username, start, limit)
174
+ request.log_request
175
+ response = request.get_customers_by_username
176
+ log_response(response)
177
+
178
+ if response.ok?
179
+ parsed_response = ::Finicity::V1::Response::Customers.parse(response.body)
180
+ return parsed_response.customers
181
+ else
182
+ raise_generic_error!(response)
183
+ end
184
+ end
185
+
186
+ def get_customers
187
+ request = ::Finicity::V1::Request::GetCustomers.new(token)
188
+ start = 1
189
+ limit = 25
190
+ customers = []
191
+
192
+ loop do
193
+ response = request.get_customers(start, limit)
194
+
195
+ if response.ok?
196
+ parsed_response = ::Finicity::V1::Response::Customers.parse(response.body)
197
+ customers << parsed_response.customers
198
+
199
+ if parsed_response.more_available?
200
+ start += limit
201
+ else
202
+ return customers.flatten
203
+ end
204
+ else
205
+ raise_generic_error!(response)
206
+ end
207
+ end
208
+ end
209
+
210
+ def get_institution(institution_id)
211
+ request = ::Finicity::V1::Request::GetInstitution.new(token, institution_id)
212
+ response = request.get_institution
213
+
214
+ if response.ok?
215
+ parsed_response = ::Finicity::V1::Response::Institution.parse(response.body)
216
+ return parsed_response
217
+ else
218
+ raise_generic_error!(response)
219
+ end
220
+ end
221
+
222
+ def get_institutions(institution_name)
223
+ request = ::Finicity::V1::Request::GetInstitutions.new(token, institution_name)
224
+ start = 1
225
+ limit = 25
226
+ institutions = []
227
+
228
+ loop do
229
+ response = request.get_institutions(start, limit)
230
+
231
+ if response.ok?
232
+ parsed_response = ::Finicity::V1::Response::Institutions.parse(response.body)
233
+ institutions << parsed_response.institutions
234
+
235
+ if parsed_response.more_available?
236
+ start += limit
237
+ else
238
+ return institutions.flatten
239
+ end
240
+ else
241
+ raise_generic_error!(response)
242
+ end
243
+ end
244
+ end
245
+
246
+ def get_login_form(institution_id)
247
+ request = ::Finicity::V1::Request::GetLoginForm.new(token, institution_id)
248
+ response = request.get_login_form
249
+
250
+ if response.ok?
251
+ parsed_response = ::Finicity::V1::Response::LoginForm.parse(response.body)
252
+ return parsed_response.login_fields
253
+ else
254
+ raise_generic_error!(response)
255
+ end
256
+ end
257
+
258
+ def get_transactions(customer_id, account_id, from_date, to_date)
259
+ request = ::Finicity::V1::Request::GetTransactions.new(token, customer_id, account_id, from_date, to_date)
260
+ request.log_request
261
+ response = request.get_transactions
262
+ log_response(response)
263
+
264
+ if response.ok?
265
+ parsed_response = ::Finicity::V1::Response::Transactions.parse(response.body)
266
+ return parsed_response.transactions
267
+ else
268
+ raise_generic_error!(response)
269
+ end
270
+ end
271
+
272
+ def interactive_refresh_account(customer_id, account_id)
273
+ request = ::Finicity::V1::Request::InteractiveRefreshAccount.new(token, customer_id, account_id)
274
+ request.log_request
275
+ response = request.interactive_refresh_account
276
+ log_response(response)
277
+
278
+ if response.status_code == 200
279
+ @mfa_session = nil
280
+ parsed_response = ::Finicity::V1::Response::Accounts.parse(response.body)
281
+ return parsed_response.accounts
282
+ elsif response.status_code == 203
283
+ @mfa_session = response.headers["MFA-Session"]
284
+ parsed_response = ::Finicity::V1::Response::Mfa.parse(response.body)
285
+ return parsed_response.questions
286
+ else
287
+ raise_generic_error!(response)
288
+ end
289
+ end
290
+
291
+ # The mfa_credentials parameter is an array of hashes with keys :text, :answer
292
+ def interactive_refresh_account_with_mfa(customer_id, account_id, mfa_credentials)
293
+ request = ::Finicity::V1::Request::InteractiveRefreshAccountWithMfa.new(token, mfa_session, customer_id, account_id, mfa_credentials)
294
+ request.log_request
295
+ response = request.interactive_refresh_account_with_mfa
296
+ log_response(response)
297
+
298
+ if response.status_code == 200
299
+ @mfa_session = nil
300
+ parsed_response = ::Finicity::V1::Response::Accounts.parse(response.body)
301
+ return parsed_response.accounts
302
+ elsif response.status_code == 203
303
+ @mfa_session = response.headers["MFA-Session"]
304
+ parsed_response = ::Finicity::V1::Response::Mfa.parse(response.body)
305
+ return parsed_response.questions
306
+ else
307
+ raise_generic_error!(response)
308
+ end
309
+ end
310
+
311
+ def refresh_accounts(customer_id)
312
+ request = ::Finicity::V1::Request::RefreshAccounts.new(token, customer_id)
313
+ request.log_request
314
+ response = request.refresh_accounts
315
+ log_response(response)
316
+
317
+ if response.ok?
318
+ parsed_response = ::Finicity::V1::Response::Accounts.parse(response.body)
319
+ return parsed_response.accounts
320
+ else
321
+ raise_generic_error!(response)
322
+ end
323
+ end
324
+
325
+ private
326
+
327
+ def log_response(response)
328
+ ::Finicity.logger.debug do
329
+ log = "RESPONSE"
330
+ log << "\n STATUS CODE: #{response.status_code}"
331
+ log << "\n BODY: #{response.body}"
332
+ log
333
+ end
334
+ end
335
+
336
+ def raise_generic_error!(response)
337
+ if response.content_type =~ /application\/xml/i
338
+ error = ::Finicity::V1::Response::Error.parse(response.body)
339
+ error_message = error.message
340
+ error_code = error.code
341
+ else
342
+ error_message = response.body
343
+ error_code = nil
344
+ end
345
+
346
+ fail ::Finicity::GenericError.new(error_message, response.status_code, error_code)
347
+ end
348
+
349
+ end
350
+ end