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.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +69 -0
- data/Rakefile +10 -0
- data/finicity.gemspec +31 -0
- data/lib/finicity.rb +42 -0
- data/lib/finicity/client.rb +350 -0
- data/lib/finicity/configuration.rb +13 -0
- data/lib/finicity/errors.rb +62 -0
- data/lib/finicity/logger.rb +19 -0
- data/lib/finicity/railtie.rb +22 -0
- data/lib/finicity/v1.rb +29 -0
- data/lib/finicity/v1/request/activate_accounts.rb +73 -0
- data/lib/finicity/v1/request/activate_accounts_with_mfa.rb +88 -0
- data/lib/finicity/v1/request/add_customer.rb +54 -0
- data/lib/finicity/v1/request/delete_customer.rb +45 -0
- data/lib/finicity/v1/request/discover_accounts.rb +71 -0
- data/lib/finicity/v1/request/discover_accounts_with_mfa.rb +87 -0
- data/lib/finicity/v1/request/get_accounts.rb +50 -0
- data/lib/finicity/v1/request/get_customers.rb +43 -0
- data/lib/finicity/v1/request/get_customers_by_username.rb +52 -0
- data/lib/finicity/v1/request/get_institution.rb +45 -0
- data/lib/finicity/v1/request/get_institutions.rb +45 -0
- data/lib/finicity/v1/request/get_login_form.rb +47 -0
- data/lib/finicity/v1/request/get_transactions.rb +60 -0
- data/lib/finicity/v1/request/interactive_refresh_account.rb +51 -0
- data/lib/finicity/v1/request/interactive_refresh_account_with_mfa.rb +74 -0
- data/lib/finicity/v1/request/refresh_accounts.rb +47 -0
- data/lib/finicity/v1/response/accounts.rb +75 -0
- data/lib/finicity/v1/response/customers.rb +36 -0
- data/lib/finicity/v1/response/error.rb +13 -0
- data/lib/finicity/v1/response/institutions.rb +38 -0
- data/lib/finicity/v1/response/login_form.rb +29 -0
- data/lib/finicity/v1/response/mfa.rb +22 -0
- data/lib/finicity/v1/response/transactions.rb +28 -0
- data/lib/finicity/v2.rb +7 -0
- data/lib/finicity/v2/request/partner_authentication.rb +39 -0
- data/lib/finicity/v2/response/partner_authentication.rb +12 -0
- data/lib/finicity/version.rb +3 -0
- data/spec/finicity/client_spec.rb +527 -0
- data/spec/finicity/v1/request/activate_accounts_spec.rb +49 -0
- data/spec/finicity/v1/request/activate_accounts_with_mfa_spec.rb +64 -0
- data/spec/finicity/v1/request/add_customer_spec.rb +37 -0
- data/spec/finicity/v1/request/delete_customer_spec.rb +18 -0
- data/spec/finicity/v1/request/discover_accounts_spec.rb +42 -0
- data/spec/finicity/v1/request/discover_accounts_with_mfa_spec.rb +59 -0
- data/spec/finicity/v1/request/get_accounts_spec.rb +18 -0
- data/spec/finicity/v1/request/get_customers_by_username_spec.rb +18 -0
- data/spec/finicity/v1/request/get_customers_spec.rb +18 -0
- data/spec/finicity/v1/request/get_institution_spec.rb +18 -0
- data/spec/finicity/v1/request/get_institutions_spec.rb +18 -0
- data/spec/finicity/v1/request/get_login_form_spec.rb +18 -0
- data/spec/finicity/v1/request/get_transactions_spec.rb +19 -0
- data/spec/finicity/v1/request/interactive_refresh_account_spec.rb +19 -0
- data/spec/finicity/v1/request/interactive_refresh_account_with_mfa_spec.rb +38 -0
- data/spec/finicity/v1/request/refresh_accounts_spec.rb +18 -0
- data/spec/finicity/v1/response/accounts_spec.rb +39 -0
- data/spec/finicity/v1/response/customers_spec.rb +19 -0
- data/spec/finicity/v1/response/error_spec.rb +19 -0
- data/spec/finicity/v1/response/institutions_spec.rb +19 -0
- data/spec/finicity/v1/response/login_form_spec.rb +31 -0
- data/spec/finicity/v1/response/mfa_spec.rb +23 -0
- data/spec/finicity/v1/response/transactions_spec.rb +47 -0
- data/spec/finicity/v2/request/partner_authentication_spec.rb +21 -0
- data/spec/finicity/v2/response/partner_authentication_spec.rb +15 -0
- data/spec/spec_helper.rb +36 -0
- metadata +265 -0
checksums.yaml
ADDED
@@ -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
|
data/.gitignore
ADDED
@@ -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
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -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
|
data/Rakefile
ADDED
data/finicity.gemspec
ADDED
@@ -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
|
data/lib/finicity.rb
ADDED
@@ -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
|