plaid-legacy 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,37 @@
1
+ module Plaid
2
+ # Public: Exception to throw when there are configuration problems
3
+ class NotConfiguredError < StandardError; end
4
+
5
+ # Internal: Base class for Plaid errors
6
+ class PlaidError < StandardError
7
+ attr_reader :code, :resolve
8
+
9
+ # Internal: Initialize a error with proper attributes.
10
+ #
11
+ # code - The Integer code (e.g. 1501).
12
+ # message - The String message, describing the error.
13
+ # resolve - The String description how to fix the error.
14
+ def initialize(code, message, resolve)
15
+ @code = code
16
+ @resolve = resolve
17
+
18
+ super "Code #{@code}: #{message}. #{resolve}"
19
+ end
20
+ end
21
+
22
+ # Public: Exception which is thrown when Plaid API returns a 400 response.
23
+ class BadRequestError < PlaidError; end
24
+
25
+ # Public: Exception which is thrown when Plaid API returns a 401 response.
26
+ class UnauthorizedError < PlaidError; end
27
+
28
+ # Public: Exception which is thrown when Plaid API returns a 402 response.
29
+ class RequestFailedError < PlaidError; end
30
+
31
+ # Public: Exception which is thrown when Plaid API returns a 404 response.
32
+ class NotFoundError < PlaidError; end
33
+
34
+ # Public: Exception which is thrown when Plaid API returns a response which
35
+ # is neither 2xx, nor 4xx. Presumably 5xx.
36
+ class ServerError < PlaidError; end
37
+ end
@@ -0,0 +1,106 @@
1
+ module Plaid
2
+ # Public: Representation of Income data.
3
+ class Income
4
+ # Public: The class encapsulating an income stream.
5
+ class Stream
6
+ # Public: The Float monthly income associated with the income stream.
7
+ # E.g. 5700.
8
+ attr_reader :monthly_income
9
+
10
+ # Public: The Float representation of Plaid's confidence in the income
11
+ # data associated with this particular income stream, with 0 being
12
+ # the lowest confidence and 1 being the highest. E.g. 0.9.
13
+ attr_reader :confidence
14
+
15
+ # Public: The Integer extent of data found for this income stream.
16
+ # E.g. 314.
17
+ attr_reader :days
18
+
19
+ # Public: The String name of the entity associated with this income
20
+ # stream. E.g. "APPLE INC".
21
+ attr_reader :name
22
+
23
+ # Internal: Initialize a Stream.
24
+ #
25
+ # fields - The Hash with fields (keys are Strings).
26
+ def initialize(fields)
27
+ @monthly_income = fields['monthly_income']
28
+ @confidence = fields['confidence']
29
+ @days = fields['days']
30
+ @name = fields['name']
31
+ end
32
+
33
+ # Public: Get a String representation of the Stream.
34
+ #
35
+ # Returns a String.
36
+ def inspect
37
+ "#<Plaid::Income::Stream name=#{name.inspect}, " \
38
+ "monthly_income=#{monthly_income.inspect}, " \
39
+ "confidence=#{confidence.inspect}, " \
40
+ "days=#{days.inspect}>"
41
+ end
42
+
43
+ # Public: Get a String representation of the Stream.
44
+ #
45
+ # Returns a String.
46
+ alias to_s inspect
47
+ end
48
+
49
+ # Public: The Array of Stream.
50
+ attr_reader :income_streams
51
+
52
+ # Public: The Numeric sum of user's income over the past 365 days. If Plaid
53
+ # has less than 365 days of data this will be less than a full year income.
54
+ # E.g. 67000.
55
+ attr_reader :last_year_income
56
+
57
+ # Public: The last_year_income interpolated to value before taxes. This is
58
+ # the minimum pre-tax salary that assumes a filing status of single with
59
+ # zero dependents. E.g. 73700.
60
+ attr_reader :last_year_income_before_tax
61
+
62
+ # Public: The Numeric user's income extrapolated over a year based on
63
+ # current, active income streams. Income streams become inactive if they
64
+ # have not recurred for more than two cycles. For example, if a weekly
65
+ # paycheck hasn't been seen for the past two weeks, it is no longer active.
66
+ # E.g. 69800.
67
+ attr_reader :projected_yearly_income
68
+
69
+ # Public: The projected_yearly_income interpolated to value before taxes.
70
+ # This is the minimum pre-tax salary that assumes a filing status of single
71
+ # with zero dependents. E.g. 75600.
72
+ attr_reader :projected_yearly_income_before_tax
73
+
74
+ # Public: The Integer max number of income streams present at the same time
75
+ # over the past 365 days. E.g. 314.
76
+ attr_reader :max_number_of_overlapping_income_streams
77
+
78
+ # Public: The Integer total number of distinct income streams received over
79
+ # the past 365 days. E.g. 2.
80
+ attr_reader :number_of_income_streams
81
+
82
+ def initialize(fields)
83
+ @income_streams = fields['income_streams'].map { |is| Stream.new(is) }
84
+
85
+ %w(last_year_income last_year_income_before_tax projected_yearly_income
86
+ projected_yearly_income_before_tax number_of_income_streams
87
+ max_number_of_overlapping_income_streams).each do |field|
88
+ instance_variable_set "@#{field}", fields[field]
89
+ end
90
+ end
91
+
92
+ # Public: Get a String representation of Income.
93
+ #
94
+ # Returns a String.
95
+ def inspect
96
+ "#<Plaid::Income last_year_income=#{last_year_income.inspect}, " \
97
+ "projected_yearly_income=#{projected_yearly_income.inspect}, " \
98
+ "number_of_income_streams=#{number_of_income_streams.inspect}, ...>"
99
+ end
100
+
101
+ # Public: Get a String representation of Income.
102
+ #
103
+ # Returns a String.
104
+ alias to_s inspect
105
+ end
106
+ end
@@ -0,0 +1,65 @@
1
+ module Plaid
2
+ # Public: Representation of user information.
3
+ class Info
4
+ # Public: The Array of String user names.
5
+ #
6
+ # E.g. ["Frodo Baggins", "Samwise Gamgee"].
7
+ attr_reader :names
8
+
9
+ # Public: The Array of Hash user emails information.
10
+ #
11
+ # E.g. [{data: "frodo.baggins@plaid.com", type: :primary}, ...]
12
+ attr_reader :emails
13
+
14
+ # Public: The Array of Hash user phone number information.
15
+ #
16
+ # E.g. [{data: "111-222-3456", type: :work, primary: false},
17
+ # {data: "123-456-7891", type: :mobile, primary: true}]
18
+ attr_reader :phone_numbers
19
+
20
+ # Public: The Array of Hash user address information.
21
+ #
22
+ # E.g. [{ primary: true, data: {
23
+ # "street" => "1 Hobbit Way",
24
+ # "city" => "The Shire",
25
+ # "state" => "CA",
26
+ # "zip" => "94108"}}]
27
+ attr_reader :addresses
28
+
29
+ # Internal: Construct the Info object.
30
+ def initialize(fields)
31
+ @names = fields['names']
32
+ @emails = fields['emails'].map do |h|
33
+ symbolize_values Plaid.symbolize_hash(h), :type
34
+ end
35
+
36
+ @phone_numbers = fields['phone_numbers'].map do |h|
37
+ symbolize_values Plaid.symbolize_hash(h), :type
38
+ end
39
+
40
+ @addresses = fields['addresses'].map do |h|
41
+ Plaid.symbolize_hash(h)
42
+ end
43
+ end
44
+
45
+ # Public: Get a String representation of Info object.
46
+ #
47
+ # Returns a String.
48
+ def inspect
49
+ "#<Plaid::Info names=#{names.inspect}, ...>"
50
+ end
51
+
52
+ # Public: Get a String representation of Info object.
53
+ #
54
+ # Returns a String.
55
+ alias to_s inspect
56
+
57
+ private
58
+
59
+ def symbolize_values(hash, *keys)
60
+ hash.each do |k, v|
61
+ hash[k] = v.to_sym if keys.include?(k)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,253 @@
1
+ module Plaid
2
+ # Public: A class encapsulating information about a Financial Institution
3
+ # supported by Plaid.
4
+ class Institution
5
+ # Public: The String institution ID. E.g. "5301a93ac140de84910000e0".
6
+ attr_reader :id
7
+
8
+ # Public: The String institution name. E.g. "Bank of America".
9
+ attr_reader :name
10
+
11
+ # Public: The String institution shortname, or "type" per Plaid API docs.
12
+ # E.g. "bofa".
13
+ attr_reader :type
14
+
15
+ # Public: The Boolean flag telling if the institution requires MFA.
16
+ attr_reader :has_mfa
17
+
18
+ # Public: Returns true if the institution requires MFA.
19
+ alias has_mfa? has_mfa
20
+
21
+ # Public: The Hash with MFA options available. E.g. ["code", "list",
22
+ # "questions(3)"]. In this case you are allowed to request a list of
23
+ # possible MFA options, use code-based MFA and questions MFA (there are 3
24
+ # questions).
25
+ attr_reader :mfa
26
+
27
+ # Public: The Hash with credential labels, how they are exactly named by
28
+ # the institution. E.g. {"username": "Online ID", "password": "Password"}.
29
+ attr_reader :credentials
30
+
31
+ # Public: An Array with Symbol product names supported by the institution.
32
+ # E.g. [:connect, :auth, :balance, :info, :income, :risk]. See
33
+ # Plaid::PRODUCTS.
34
+ attr_reader :products
35
+
36
+ # Internal: Initialize an Institution with given fields.
37
+ def initialize(fields)
38
+ @id = fields['id']
39
+ @name = fields['name']
40
+ @type = fields['type']
41
+ @has_mfa = fields['has_mfa']
42
+ @mfa = fields['mfa']
43
+ @credentials = fields['credentials']
44
+ @products = fields['products'].map(&:to_sym)
45
+ end
46
+
47
+ # Public: Get a String representation of the institution.
48
+ #
49
+ # Returns a String.
50
+ def inspect
51
+ "#<Plaid::Institution id=#{id.inspect}, type=#{type.inspect}, " \
52
+ "name=#{name.inspect}>"
53
+ end
54
+
55
+ # Public: Get a String representation of the institution.
56
+ #
57
+ # Returns a String.
58
+ alias to_s inspect
59
+
60
+ # Public: Get information about the Financial Institutions currently
61
+ # supported by Plaid.
62
+ #
63
+ # Does a POST /institutions/all call. The result is paginated (count,
64
+ # offset params) and filtered by products. If the products param is
65
+ # specified, only institutions which support all of the products mentioned
66
+ # will be returned.
67
+ #
68
+ # count - The Integer number of results to retrieve (default: 50).
69
+ # offset - The Integer number of results to skip forward from the
70
+ # beginning of the list (default: 0).
71
+ # products - The Array of product Symbols (see Plaid::PRODUCTS) or nil.
72
+ # E.g. [:connect, :auth]. Default: nil.
73
+ # client - The Plaid::Client instance used to connect
74
+ # (default: Plaid.client).
75
+ #
76
+ # Returns an Array of Institution instances.
77
+ def self.all(count: 50, offset: 0, products: nil, client: nil)
78
+ conn = Connector.new(:institutions, :all, auth: true, client: client)
79
+ payload = {
80
+ count: count,
81
+ offset: offset
82
+ }
83
+
84
+ if products
85
+ payload[:products] = MultiJson.encode(Array(products))
86
+ end
87
+
88
+ resp = conn.post(payload)
89
+
90
+ Page.new(resp['total_count'],
91
+ resp['results'].map { |item| new(item) })
92
+ end
93
+
94
+ # Public: Get information about a given Financial Institution.
95
+ #
96
+ # Does a GET /institutions/all/:id call.
97
+ #
98
+ # id - the String institution ID (e.g. "5301a93ac140de84910000e0", or
99
+ # "ins_109263").
100
+ # client - The Plaid::Client instance used to connect
101
+ # (default: Plaid.client).
102
+ #
103
+ # Returns an Institution instance or raises Plaid::NotFoundError if
104
+ # institution with given id is not found.
105
+ def self.get(id, client: nil)
106
+ new Connector.new('institutions/all', id, client: client).get
107
+ end
108
+
109
+ # Public: Search Financial Institutions.
110
+ #
111
+ # query - The String search query to match against the full list of
112
+ # institutions. Partial matches are returned making this useful
113
+ # for autocompletion purposes.
114
+ # product - The Symbol product name to filter by, one of Plaid::PRODUCTS
115
+ # (e.g. :info, :connect, etc.). Only valid when query is
116
+ # specified. If nil, results are not filtered by product
117
+ # (default: nil).
118
+ # client - The Plaid::Client instance used to connect
119
+ # (default: Plaid.client).
120
+ #
121
+ # Returns an Array of SearchResultInstitution.
122
+ def self.search(query: nil, product: nil, client: nil)
123
+ raise ArgumentError, 'query must be specified' \
124
+ unless query.is_a?(String) && !query.empty?
125
+
126
+ payload = { q: query }
127
+ payload[:p] = product.to_s if product
128
+
129
+ resp = Connector.new('institutions/all', :search, client: client).get(payload)
130
+ resp.map { |inst| SearchResultInstitution.new(inst) }
131
+ end
132
+
133
+ # Public: Lookup a Financial Institution by ID.
134
+ #
135
+ # Does a GET /institutions/all/search call with id param.
136
+ #
137
+ # id - the String institution ID (e.g. 'bofa').
138
+ # client - The Plaid::Client instance used to connect
139
+ # (default: Plaid.client).
140
+ #
141
+ # Returns an SearchResultInstitution instance or nil if institution with
142
+ # given id is not found.
143
+ def self.search_by_id(id, client: nil)
144
+ client ||= Plaid.client
145
+
146
+ # If client_id is set, use it, no authentication otherwise
147
+ auth = client && !client.client_id.nil?
148
+ conn = Connector.new('institutions/all', :search, auth: auth, client: client)
149
+ resp = conn.get(id: id)
150
+
151
+ case resp
152
+ when Hash
153
+ SearchResultInstitution.new resp
154
+ when Array
155
+ raise 'Non-empty array returned by /institutions/all/search with id' \
156
+ unless resp.empty?
157
+
158
+ nil
159
+ else
160
+ raise 'Unexpected result returned by /institutions/all/search with id: ' \
161
+ "#{resp.inspect}"
162
+ end
163
+ end
164
+ end
165
+
166
+ # Public: A page of results.
167
+ class Page < Array
168
+ # Public: The total number of institutions in all pages
169
+ attr_reader :total_count
170
+
171
+ def initialize(total_count, records)
172
+ @total_count = total_count
173
+ super records
174
+ end
175
+ end
176
+
177
+ # Public: A class encapsulating information about a Financial Institution
178
+ # supported by Plaid.
179
+ class SearchResultInstitution
180
+ # Public: The String ID of the institution. Same as type. E.g. "bofa".
181
+ attr_reader :id
182
+
183
+ # Public: The String short name ("type") of the institution. E.g. "bofa".
184
+ attr_reader :type
185
+
186
+ # Public: The String institution name. E.g. "Bank of America".
187
+ attr_reader :name
188
+
189
+ # Public: The Hash with supported products as keys and booleans as values.
190
+ #
191
+ # E.g. { auth: true, balance: true, connect: true, info: true }.
192
+ attr_reader :products
193
+
194
+ # Public: The String "forgotten password" URL.
195
+ attr_reader :forgotten_password_url
196
+
197
+ # Public: The String "account locked" URL.
198
+ attr_reader :account_locked_url
199
+
200
+ # Public: The String "account setup" URL.
201
+ attr_reader :account_setup_url
202
+
203
+ # Public: The String video (???).
204
+ attr_reader :video
205
+
206
+ # Public: The Array of Hashes with login fields information.
207
+ #
208
+ # E.g. [{ name: 'username', label: 'Online ID', type: 'text' },
209
+ # { name: 'password', label: 'Password', type: 'password' }].
210
+ attr_reader :fields
211
+
212
+ # Public: The Hash with color information for the institution.
213
+ #
214
+ # E.g. { primary: 'rgba(220,20,48,1)',
215
+ # darker: 'rgba(180,11,35,1)',
216
+ # gradient: ['rgba(250,20,51,1)', 'rgba(227,24,55,1)'] }.
217
+ attr_reader :colors
218
+
219
+ # Public: The String with base64 encoded logo.
220
+ attr_reader :logo
221
+
222
+ # Public: ???.
223
+ attr_reader :name_break
224
+
225
+ # Internal: Initialize the SearchResultInstitution instance.
226
+ def initialize(hash)
227
+ %w(id type name video logo).each do |f|
228
+ instance_variable_set "@#{f}", hash[f]
229
+ end
230
+
231
+ @products = Plaid.symbolize_hash(hash['products'])
232
+ @forgotten_password_url = hash['forgottenPassword']
233
+ @account_locked_url = hash['accountLocked']
234
+ @account_setup_url = hash['accountSetup']
235
+ @fields = hash['fields'].map { |fld| Plaid.symbolize_hash(fld) }
236
+ @colors = Plaid.symbolize_hash(hash['colors'])
237
+ @name_break = hash['nameBreak']
238
+ end
239
+
240
+ # Public: Get a String representation of the institution.
241
+ #
242
+ # Returns a String.
243
+ def inspect
244
+ "#<Plaid::SearchResultInstitution id=#{id.inspect}, name=#{name.inspect}, " \
245
+ '...>'
246
+ end
247
+
248
+ # Public: Get a String representation of the institution.
249
+ #
250
+ # Returns a String.
251
+ alias to_s inspect
252
+ end
253
+ end