plaid 1.7.1 → 2.0.0.alpha
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/CHANGELOG.md +3 -0
- data/CONTRIBUTING.md +15 -0
- data/LICENSE +20 -0
- data/README.md +215 -63
- data/Rakefile +50 -4
- data/UPGRADING.md +45 -0
- data/bin/console +13 -0
- data/bin/setup +8 -0
- data/lib/plaid.rb +51 -88
- data/lib/plaid/account.rb +144 -0
- data/lib/plaid/category.rb +62 -0
- data/lib/plaid/client.rb +67 -0
- data/lib/plaid/connector.rb +168 -0
- data/lib/plaid/errors.rb +24 -14
- data/lib/plaid/income.rb +106 -0
- data/lib/plaid/info.rb +65 -0
- data/lib/plaid/institution.rb +240 -0
- data/lib/plaid/risk.rb +34 -0
- data/lib/plaid/transaction.rb +123 -0
- data/lib/plaid/user.rb +430 -0
- data/lib/plaid/version.rb +1 -1
- data/plaid.gemspec +20 -12
- metadata +58 -62
- data/.gitignore +0 -15
- data/.rspec +0 -2
- data/.travis.yml +0 -5
- data/LICENSE.txt +0 -22
- data/PUBLISHING.md +0 -21
- data/lib/plaid/config.rb +0 -19
- data/lib/plaid/connection.rb +0 -109
- data/lib/plaid/models/account.rb +0 -24
- data/lib/plaid/models/category.rb +0 -17
- data/lib/plaid/models/exchange_token_response.rb +0 -11
- data/lib/plaid/models/info.rb +0 -12
- data/lib/plaid/models/institution.rb +0 -22
- data/lib/plaid/models/transaction.rb +0 -24
- data/lib/plaid/models/user.rb +0 -189
- data/spec/plaid/config_spec.rb +0 -67
- data/spec/plaid/connection_spec.rb +0 -191
- data/spec/plaid/error_spec.rb +0 -10
- data/spec/plaid/models/account_spec.rb +0 -37
- data/spec/plaid/models/category_spec.rb +0 -16
- data/spec/plaid/models/institution_spec.rb +0 -19
- data/spec/plaid/models/transaction_spec.rb +0 -28
- data/spec/plaid/models/user_spec.rb +0 -172
- data/spec/plaid_spec.rb +0 -263
- data/spec/spec_helper.rb +0 -14
data/lib/plaid/risk.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module Plaid
|
2
|
+
# Public: Representation of risk data (per account).
|
3
|
+
class Risk
|
4
|
+
# Public: The Float comprehensive risk score associated with the account,
|
5
|
+
# where 0 is the lowest risk and 1 is the highest. E.g. 0.5.
|
6
|
+
attr_reader :score
|
7
|
+
|
8
|
+
# Public: The Hash with Symbol reasons and associated Float subscores
|
9
|
+
# contributing to the overall risk score.
|
10
|
+
#
|
11
|
+
# E.g. { transaction_amounts: 0.78, foreign_fees: 0.96, ... }.
|
12
|
+
attr_reader :reason
|
13
|
+
|
14
|
+
# Internal: Construct a Risk object.
|
15
|
+
#
|
16
|
+
# fields - The Hash with fields.
|
17
|
+
def initialize(fields)
|
18
|
+
@score = fields['score']
|
19
|
+
@reason = Plaid.symbolize_hash(fields['reason'])
|
20
|
+
end
|
21
|
+
|
22
|
+
# Public: Get a String representation of Risk.
|
23
|
+
#
|
24
|
+
# Returns a String.
|
25
|
+
def inspect
|
26
|
+
"#<Plaid::Risk score=#{score.inspect}, ..."
|
27
|
+
end
|
28
|
+
|
29
|
+
# Public: Get a String representation of Risk.
|
30
|
+
#
|
31
|
+
# Returns a String.
|
32
|
+
alias to_s inspect
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
module Plaid
|
5
|
+
# Public: Representation of a transaction.
|
6
|
+
class Transaction
|
7
|
+
# Public: The String unique ID of the transaction. E.g.
|
8
|
+
# "0AZ0De04KqsreDgVwM1RSRYjyd8yXxSDQ8Zxn".
|
9
|
+
attr_reader :id
|
10
|
+
|
11
|
+
# Public: The String ID of the account in which this transaction occurred.
|
12
|
+
# E.g. "XARE85EJqKsjxLp6XR8ocg8VakrkXpTXmRdOo".
|
13
|
+
attr_reader :account_id
|
14
|
+
|
15
|
+
# Public: The Date that the transaction took place.
|
16
|
+
# E.g. #<Date: 2016-04-28 ...>
|
17
|
+
attr_reader :date
|
18
|
+
|
19
|
+
# Public: The settled dollar value as Float. Positive values when
|
20
|
+
# money moves out of the account; negative values when money moves
|
21
|
+
# in. E.g. 0.10 (10 cents).
|
22
|
+
attr_reader :amount
|
23
|
+
|
24
|
+
# Public: The String descriptive name of the transaction. E.g.
|
25
|
+
# "Golden Crepes".
|
26
|
+
attr_reader :name
|
27
|
+
|
28
|
+
# Public: The Hash with additional information regarding the
|
29
|
+
# transaction. The keys are Symbols. E.g.
|
30
|
+
# { location: { "city": "San Francisco", "state": "CA" } }
|
31
|
+
attr_reader :meta
|
32
|
+
|
33
|
+
# Public: The Hash with location information obtained from the
|
34
|
+
# meta field. The keys are Strings.
|
35
|
+
#
|
36
|
+
# E.g. {"address" => "262 W 15th St",
|
37
|
+
# "city" => "New York",
|
38
|
+
# "state" => "NY",
|
39
|
+
# "zip" => "10011",
|
40
|
+
# "coordinates" => {
|
41
|
+
# "lat" => 40.740352,
|
42
|
+
# "lon" => -74.001761
|
43
|
+
# }}
|
44
|
+
attr_reader :location
|
45
|
+
|
46
|
+
# Public: The Boolean flag which identifies the transaction as
|
47
|
+
# pending or unsettled.
|
48
|
+
attr_reader :pending
|
49
|
+
|
50
|
+
# Public: The Hash with numeric representation of Plaid confidence
|
51
|
+
# in the meta data attached to the transaction. In the case of a
|
52
|
+
# score <.9 Plaid will default to guaranteed and known
|
53
|
+
# information. E.g.
|
54
|
+
#
|
55
|
+
# {location: {
|
56
|
+
# "address" => 1,
|
57
|
+
# "city" => 1,
|
58
|
+
# "state" => 1
|
59
|
+
# }, name: 0.9}.
|
60
|
+
attr_reader :score
|
61
|
+
|
62
|
+
# Public: The Hash transaction type.
|
63
|
+
#
|
64
|
+
# E.g. {:primary => :place}.
|
65
|
+
attr_reader :type
|
66
|
+
|
67
|
+
# Public: The Array of String category hierarchy.
|
68
|
+
#
|
69
|
+
# E.g. ["Food and Drink", "Restaurants"].
|
70
|
+
attr_reader :category_hierarchy
|
71
|
+
|
72
|
+
# Public: The String Category ID.
|
73
|
+
#
|
74
|
+
# E.g. "13005000".
|
75
|
+
attr_reader :category_id
|
76
|
+
|
77
|
+
# Public: The String ID of a posted transaction's associated
|
78
|
+
# pending transaction - where applicable.
|
79
|
+
attr_reader :pending_transaction_id
|
80
|
+
|
81
|
+
# Public: Initialize a Transaction instance.
|
82
|
+
#
|
83
|
+
# fields - The Hash with fields.
|
84
|
+
def initialize(fields)
|
85
|
+
@id = fields['_id']
|
86
|
+
@account_id = fields['_account']
|
87
|
+
|
88
|
+
@date = fields['date'] && Date.parse(fields['date'])
|
89
|
+
@amount = fields['amount']
|
90
|
+
@name = fields['name']
|
91
|
+
@meta = Plaid.symbolize_hash(fields['meta'])
|
92
|
+
@location = (@meta && @meta[:location]) || {}
|
93
|
+
@pending = fields['pending']
|
94
|
+
@pending_transaction_id = fields['_pendingTransaction']
|
95
|
+
@score = Plaid.symbolize_hash(fields['score'])
|
96
|
+
|
97
|
+
@type = Plaid.symbolize_hash(fields['type'], values: true)
|
98
|
+
@category_hierarchy = fields['category']
|
99
|
+
@category_id = fields['category_id']
|
100
|
+
end
|
101
|
+
|
102
|
+
# Public: Detect if the transaction is pending or unsettled.
|
103
|
+
#
|
104
|
+
# Returns true if it is.
|
105
|
+
def pending?
|
106
|
+
pending
|
107
|
+
end
|
108
|
+
|
109
|
+
# Public: Get a String representation of the transaction.
|
110
|
+
#
|
111
|
+
# Returns a String.
|
112
|
+
def inspect
|
113
|
+
"#<Plaid::Transaction id=#{id.inspect}, account_id=#{id.inspect}, " \
|
114
|
+
"date=#{date}, amount=#{amount.inspect}, name=#{name.inspect}, " \
|
115
|
+
"pending=#{pending.inspect}>"
|
116
|
+
end
|
117
|
+
|
118
|
+
# Public: Get a String representation of the transaction.
|
119
|
+
#
|
120
|
+
# Returns a String.
|
121
|
+
alias to_s inspect
|
122
|
+
end
|
123
|
+
end
|
data/lib/plaid/user.rb
ADDED
@@ -0,0 +1,430 @@
|
|
1
|
+
require_relative 'account'
|
2
|
+
|
3
|
+
module Plaid
|
4
|
+
# Public: A class which encapsulates the authenticated user for all Plaid
|
5
|
+
# products.
|
6
|
+
class User
|
7
|
+
# Public: The access token for authenticated user.
|
8
|
+
attr_reader :access_token
|
9
|
+
|
10
|
+
# Public: The current product. Provides a context for #update and #delete
|
11
|
+
# calls. See Plaid::PRODUCTS.
|
12
|
+
attr_reader :product
|
13
|
+
|
14
|
+
# Public: The Array of Account instances providing accounts information
|
15
|
+
# for the user.
|
16
|
+
attr_reader :accounts
|
17
|
+
|
18
|
+
# Public: The Array of Transactions provided by initial call to User.create.
|
19
|
+
#
|
20
|
+
# If the :login_only option of User.create is set to false, the initial
|
21
|
+
# 30-day transactional data are returned during the API call. This attribute
|
22
|
+
# contains them.
|
23
|
+
attr_reader :initial_transactions
|
24
|
+
|
25
|
+
# Public: The Symbol MFA type to be used (or nil, if no MFA required).
|
26
|
+
#
|
27
|
+
# E.g. :questions, :list, or :device.
|
28
|
+
attr_reader :mfa_type
|
29
|
+
|
30
|
+
# Public: The MFA data (Hash or Array of Hash) or nil, if no MFA required.
|
31
|
+
#
|
32
|
+
# E.g. [{ question: "What was the name of your first pet?" }]
|
33
|
+
# or
|
34
|
+
# [{ mask: 't..t@plaid.com', type: 'email' },
|
35
|
+
# { mask: 'xxx-xxx-5309', type: 'phone' }]
|
36
|
+
# or
|
37
|
+
# { message: 'Code sent to xxx-xxx-5309' }
|
38
|
+
attr_reader :mfa
|
39
|
+
|
40
|
+
# Internal: The Plaid::Client instance used to make queries.
|
41
|
+
attr_reader :client
|
42
|
+
|
43
|
+
# Public: Create (add) a user.
|
44
|
+
#
|
45
|
+
# product - The Symbol product name you are adding the user to, one of
|
46
|
+
# Plaid::PRODUCTS (e.g. :info, :connect, etc.).
|
47
|
+
# institution - The String/Symbol financial institution type that you
|
48
|
+
# want to access (e.g. :wells).
|
49
|
+
# username - The String username associated with the financial
|
50
|
+
# institution.
|
51
|
+
# password - The String password associated with the financial
|
52
|
+
# institution.
|
53
|
+
# pin - The String PIN number associated with the financial
|
54
|
+
# institution (default: nil).
|
55
|
+
# options - the Hash options (default: {}):
|
56
|
+
# :list - The Boolean flag which would request the
|
57
|
+
# available send methods if the institution
|
58
|
+
# requires code-based MFA credential (default:
|
59
|
+
# false).
|
60
|
+
# :webhook - The String webhook URL. Used with :connect,
|
61
|
+
# :income, and :risk products (default: nil).
|
62
|
+
# :pending - The Boolean flag requesting to return
|
63
|
+
# pending transactions. Used with :connect
|
64
|
+
# product (default: false).
|
65
|
+
# :login_only - The Boolean option valid for initial
|
66
|
+
# authentication only. If set to false, the
|
67
|
+
# initial request will return transaction data
|
68
|
+
# based on the start_date and end_date.
|
69
|
+
# :start_date - The start Date from which to return
|
70
|
+
# transactions (default: 30 days ago).
|
71
|
+
# :end_date - The end Date to which transactions
|
72
|
+
# will be collected (default: today).
|
73
|
+
# client - The Plaid::Client instance used to connect to the API
|
74
|
+
# (default is to use global Plaid client - Plaid.client).
|
75
|
+
#
|
76
|
+
# Returns a Plaid::User instance.
|
77
|
+
def self.create(product, institution, username, password,
|
78
|
+
pin: nil, options: nil, client: nil)
|
79
|
+
check_product product
|
80
|
+
|
81
|
+
payload = { username: username, password: password,
|
82
|
+
type: institution.to_s }
|
83
|
+
payload[:pin] = pin if pin
|
84
|
+
payload[:options] = MultiJson.dump(options) if options
|
85
|
+
|
86
|
+
conn = Connector.new(product, auth: true, client: client)
|
87
|
+
resp = conn.post(payload)
|
88
|
+
|
89
|
+
new product, response: resp, mfa: conn.mfa?, client: client
|
90
|
+
end
|
91
|
+
|
92
|
+
# Public: Get User instance in case user access token is known.
|
93
|
+
#
|
94
|
+
# No requests are made, but the returned User instance is ready to be
|
95
|
+
# used.
|
96
|
+
#
|
97
|
+
# product - The Symbol product name you want to use, one of
|
98
|
+
# Plaid::PRODUCTS (e.g. :info, :connect, etc.).
|
99
|
+
# token - The String access token for the user.
|
100
|
+
# client - The Plaid::Client instance used to connect to the API
|
101
|
+
# (default is to use global Plaid client - Plaid.client).
|
102
|
+
#
|
103
|
+
# Returns a Plaid::User instance.
|
104
|
+
def self.load(product, token, client: nil)
|
105
|
+
new check_product(product), access_token: token, client: client
|
106
|
+
end
|
107
|
+
|
108
|
+
# Public: Exchange a Link public_token for an API access_token.
|
109
|
+
#
|
110
|
+
# public_token - The String Link public_token.
|
111
|
+
# account_id - The String account ID.
|
112
|
+
# product - The Symbol product name (default: :connect).
|
113
|
+
# client - The Plaid::Client instance used to connect to the API
|
114
|
+
# (default is to use global Plaid client - Plaid.client).
|
115
|
+
#
|
116
|
+
# Returns a new User with access token obtained from Plaid and default
|
117
|
+
# product set to product.
|
118
|
+
def self.exchange_token(public_token, account_id = nil,
|
119
|
+
product: :connect, client: nil)
|
120
|
+
check_product product
|
121
|
+
|
122
|
+
payload = { public_token: public_token }
|
123
|
+
payload[:account_id] = account_id if account_id
|
124
|
+
|
125
|
+
response = Connector.new(:exchange_token, auth: true, client: client)
|
126
|
+
.post(payload)
|
127
|
+
new product, response: response, client: client
|
128
|
+
end
|
129
|
+
|
130
|
+
# Internal: Initialize a User instance.
|
131
|
+
#
|
132
|
+
# product - The Symbol product name.
|
133
|
+
# access_token - The String access token obtained from Plaid.
|
134
|
+
# response - The Hash response body to parse.
|
135
|
+
# mfa - The Boolean flag indicating that response body
|
136
|
+
# - contains an MFA response.
|
137
|
+
# client - The Plaid::Client instance used to connect to the API
|
138
|
+
# (default is to use global Plaid client - Plaid.client).
|
139
|
+
def initialize(product, access_token: nil, response: nil, mfa: nil,
|
140
|
+
client: nil)
|
141
|
+
@product = product
|
142
|
+
@client = client
|
143
|
+
@access_token = access_token if access_token
|
144
|
+
@mfa_required = mfa
|
145
|
+
@accounts = @initial_transactions = @info = @risk = @income = nil
|
146
|
+
|
147
|
+
parse_response(response) if response
|
148
|
+
end
|
149
|
+
|
150
|
+
# Public: Find out if MFA is required based on last request.
|
151
|
+
#
|
152
|
+
# After calling e.g. User.create you might need to make an additional
|
153
|
+
# authorization step if MFA is required by the financial institution.
|
154
|
+
#
|
155
|
+
# Returns true if this step is needed, a falsey value otherwise.
|
156
|
+
def mfa?
|
157
|
+
@mfa_required
|
158
|
+
end
|
159
|
+
|
160
|
+
# Public: Submit MFA information.
|
161
|
+
#
|
162
|
+
# info - The String with MFA information (default: nil).
|
163
|
+
# send_method - The Hash with code send method information.
|
164
|
+
# E.g. { type: 'phone' } or { mask: '123-...-4321' }.
|
165
|
+
# Default is first available email.
|
166
|
+
#
|
167
|
+
# Returns true if whole MFA process is completed, false otherwise.
|
168
|
+
def mfa_step(info = nil, send_method: nil)
|
169
|
+
payload = { access_token: access_token }
|
170
|
+
payload[:mfa] = info if info
|
171
|
+
payload[:send_method] = MultiJson.dump(send_method) if send_method
|
172
|
+
|
173
|
+
conn = Connector.new(product, :step, auth: true)
|
174
|
+
response = conn.post(payload)
|
175
|
+
|
176
|
+
@mfa_required = conn.mfa?
|
177
|
+
parse_response(response)
|
178
|
+
end
|
179
|
+
|
180
|
+
# Public: Get transactions.
|
181
|
+
#
|
182
|
+
# Does a /connect/get call. Updates self.accounts with latest information.
|
183
|
+
#
|
184
|
+
# pending - the Boolean flag requesting to return pending transactions.
|
185
|
+
# account_id - the String Account ID (default: nil). If this argument is
|
186
|
+
# present, only transactions for given account will be
|
187
|
+
# requested.
|
188
|
+
# start_date - The start Date (inclusive).
|
189
|
+
# end_date - The end Date (inclusive).
|
190
|
+
#
|
191
|
+
# Returns an Array of Transaction records.
|
192
|
+
def transactions(pending: false, account_id: nil,
|
193
|
+
start_date: nil, end_date: nil)
|
194
|
+
options = { pending: pending }
|
195
|
+
options[:account] = account_id if account_id
|
196
|
+
options[:gte] = start_date.to_s if start_date
|
197
|
+
options[:lte] = end_date.to_s if end_date
|
198
|
+
|
199
|
+
response = Connector.new(:connect, :get, auth: true, client: client)
|
200
|
+
.post(access_token: access_token,
|
201
|
+
options: MultiJson.dump(options))
|
202
|
+
update_accounts(response)
|
203
|
+
build_objects(response['transactions'], Transaction)
|
204
|
+
end
|
205
|
+
|
206
|
+
# Public: Update user credentials.
|
207
|
+
#
|
208
|
+
# Updates the user credentials for the current product. See
|
209
|
+
# User#for_product.
|
210
|
+
#
|
211
|
+
# username - The String username associated with the financial
|
212
|
+
# institution.
|
213
|
+
# password - The String password associated with the financial
|
214
|
+
# institution.
|
215
|
+
# pin - The String PIN number associated with the financial
|
216
|
+
# institution (default: nil).
|
217
|
+
#
|
218
|
+
# Returns self.
|
219
|
+
def update(username, password, pin = nil)
|
220
|
+
payload = {
|
221
|
+
access_token: access_token,
|
222
|
+
username: username,
|
223
|
+
password: password
|
224
|
+
}
|
225
|
+
|
226
|
+
payload[:pin] = pin if pin
|
227
|
+
|
228
|
+
parse_response(Connector.new(product, auth: true, client: client)
|
229
|
+
.patch(payload))
|
230
|
+
|
231
|
+
self
|
232
|
+
end
|
233
|
+
|
234
|
+
# Public: Delete the user.
|
235
|
+
#
|
236
|
+
# Makes a delete request and freezes self to prevent further modifications
|
237
|
+
# to the object.
|
238
|
+
#
|
239
|
+
# Returns self.
|
240
|
+
def delete
|
241
|
+
Connector.new(product, auth: true, client: client)
|
242
|
+
.delete(access_token: access_token)
|
243
|
+
|
244
|
+
freeze
|
245
|
+
end
|
246
|
+
|
247
|
+
# Public: Upgrade the user.
|
248
|
+
#
|
249
|
+
# For an existing user that has been added via any of products (:connect,
|
250
|
+
# :auth, :income, :info, or :risk), you can upgrade that user to have
|
251
|
+
# functionality with other products.
|
252
|
+
#
|
253
|
+
# Does a POST /upgrade request.
|
254
|
+
#
|
255
|
+
# See also User#for_product.
|
256
|
+
#
|
257
|
+
# product - The Symbol product name you are upgrading the user to, one of
|
258
|
+
# Plaid::PRODUCTS.
|
259
|
+
#
|
260
|
+
# Returns another User record with the same access token, but tied to the
|
261
|
+
# new product.
|
262
|
+
def upgrade(product)
|
263
|
+
payload = { access_token: access_token, upgrade_to: product.to_s }
|
264
|
+
response = Connector.new(:upgrade, auth: true, client: client)
|
265
|
+
.post(payload)
|
266
|
+
|
267
|
+
User.new product, response: response
|
268
|
+
end
|
269
|
+
|
270
|
+
# Public: Get the current user tied to another product.
|
271
|
+
#
|
272
|
+
# No API request is made, just the current product is changed.
|
273
|
+
#
|
274
|
+
# product - The Symbol product you are selecting, one of Plaid::PRODUCTS.
|
275
|
+
#
|
276
|
+
# See also User#upgrade.
|
277
|
+
#
|
278
|
+
# Returns a new User instance.
|
279
|
+
def for_product(product)
|
280
|
+
User.load product, access_token, client: client
|
281
|
+
end
|
282
|
+
|
283
|
+
# Public: Get auth information for the user (routing numbers for accounts).
|
284
|
+
#
|
285
|
+
# Not only this method returns the new data, but it updates self.accounts as
|
286
|
+
# well.
|
287
|
+
#
|
288
|
+
# The method does a POST /auth/get request.
|
289
|
+
#
|
290
|
+
# sync - The Boolean flag which, if true, causes auth information to be
|
291
|
+
# rerequested from the server. Otherwise cached version is returned,
|
292
|
+
# if it exists.
|
293
|
+
#
|
294
|
+
# Returns an Array of Account with numbers baked in.
|
295
|
+
def auth(sync: false)
|
296
|
+
if sync || !@accounts || !@accounts[0] || !@accounts[0].numbers
|
297
|
+
response = Connector.new(:auth, :get, auth: true, client: client)
|
298
|
+
.post(access_token: access_token)
|
299
|
+
|
300
|
+
update_accounts(response)
|
301
|
+
end
|
302
|
+
|
303
|
+
accounts
|
304
|
+
end
|
305
|
+
|
306
|
+
# Public: Get info for the user.
|
307
|
+
#
|
308
|
+
# Does a POST /info/get request.
|
309
|
+
#
|
310
|
+
# sync - The Boolean flag which, if true, causes information to be
|
311
|
+
# rerequested from the server. Otherwise cached version is returned,
|
312
|
+
# if it exists.
|
313
|
+
#
|
314
|
+
# Returns a Plaid::Info instance.
|
315
|
+
def info(sync: false)
|
316
|
+
if sync || !@info
|
317
|
+
parse_response(Connector.new(:info, :get, auth: true, client: client)
|
318
|
+
.post(access_token: access_token))
|
319
|
+
end
|
320
|
+
|
321
|
+
@info
|
322
|
+
end
|
323
|
+
|
324
|
+
# Public: Get income information for the user.
|
325
|
+
#
|
326
|
+
# Does a POST /income/get request.
|
327
|
+
#
|
328
|
+
# sync - The Boolean flag which, if true, causes income information to be
|
329
|
+
# rerequested from the server. Otherwise cached version is returned,
|
330
|
+
# if it exists.
|
331
|
+
#
|
332
|
+
# Returns a Plaid::Income instance.
|
333
|
+
def income(sync: false)
|
334
|
+
if sync || !@income
|
335
|
+
parse_response(Connector.new(:income, :get, auth: true, client: client)
|
336
|
+
.post(access_token: access_token))
|
337
|
+
end
|
338
|
+
|
339
|
+
@income
|
340
|
+
end
|
341
|
+
|
342
|
+
# Public: Get risk data for the user's accounts.
|
343
|
+
#
|
344
|
+
# Does a POST /risk/get request.
|
345
|
+
#
|
346
|
+
# sync - The Boolean flag which, if true, causes risk information to be
|
347
|
+
# rerequested from the server. Otherwise cached version is returned,
|
348
|
+
# if it exists.
|
349
|
+
#
|
350
|
+
# Returns an Array of accounts with risk attribute set.
|
351
|
+
def risk(sync: false)
|
352
|
+
if sync || !@accounts || !@accounts[0] || !@accounts[0].risk
|
353
|
+
parse_response(Connector.new(:risk, :get, auth: true, client: client)
|
354
|
+
.post(access_token: access_token))
|
355
|
+
end
|
356
|
+
|
357
|
+
@accounts
|
358
|
+
end
|
359
|
+
|
360
|
+
# Public: Get current account balance.
|
361
|
+
#
|
362
|
+
# Does a POST /balance request.
|
363
|
+
#
|
364
|
+
# Returns an Array of Plaid::Account.
|
365
|
+
def balance
|
366
|
+
response = Connector.new(:balance, auth: true, client: client)
|
367
|
+
.post(access_token: access_token)
|
368
|
+
|
369
|
+
update_accounts(response)
|
370
|
+
end
|
371
|
+
|
372
|
+
private
|
373
|
+
|
374
|
+
# Internal: Validate the product name.
|
375
|
+
def self.check_product(product)
|
376
|
+
if Plaid::PRODUCTS.include?(product)
|
377
|
+
product
|
378
|
+
else
|
379
|
+
raise ArgumentError, "product (#{product.inspect}) must be one of " \
|
380
|
+
"Plaid products (#{Plaid::PRODUCTS.inspect})"
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
private_class_method :check_product
|
385
|
+
|
386
|
+
# Internal: Set up attributes from Add User response.
|
387
|
+
def parse_response(response)
|
388
|
+
@access_token = response['access_token']
|
389
|
+
return parse_mfa_response(response) if mfa?
|
390
|
+
|
391
|
+
@mfa_type = @mfa = nil
|
392
|
+
|
393
|
+
update_accounts(response) if response['accounts']
|
394
|
+
|
395
|
+
if (trans = response['transactions'])
|
396
|
+
@initial_transactions = build_objects(trans, Transaction)
|
397
|
+
end
|
398
|
+
|
399
|
+
if (income = response['income'])
|
400
|
+
@income = Plaid::Income.new(income)
|
401
|
+
end
|
402
|
+
|
403
|
+
return unless (i = response['info'])
|
404
|
+
@info = Plaid::Info.new(i)
|
405
|
+
end
|
406
|
+
|
407
|
+
# Internal: Parse an MFA response
|
408
|
+
def parse_mfa_response(response)
|
409
|
+
@mfa_type = response['type'].to_sym
|
410
|
+
@mfa = Plaid.symbolize_hash(response['mfa'])
|
411
|
+
end
|
412
|
+
|
413
|
+
# Internal: Convert an array of data into an array of objects, encapsulating
|
414
|
+
# that data.
|
415
|
+
def build_objects(data, klass)
|
416
|
+
data ? data.map { |element| klass.new(element) } : []
|
417
|
+
end
|
418
|
+
|
419
|
+
# Internal: Update account data from the response.
|
420
|
+
def update_accounts(response)
|
421
|
+
new_accounts = build_objects(response['accounts'], Account)
|
422
|
+
|
423
|
+
if @accounts
|
424
|
+
Account.merge @accounts, new_accounts
|
425
|
+
else
|
426
|
+
@accounts = new_accounts
|
427
|
+
end
|
428
|
+
end
|
429
|
+
end
|
430
|
+
end
|