plaid 1.4.3 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +66 -2
- data/lib/plaid/config.rb +8 -2
- data/lib/plaid/connection.rb +121 -0
- data/lib/plaid/models/account.rb +24 -0
- data/lib/plaid/models/category.rb +17 -0
- data/lib/plaid/models/exchange_token_response.rb +9 -0
- data/lib/plaid/models/info.rb +12 -0
- data/lib/plaid/models/institution.rb +20 -0
- data/lib/plaid/models/transaction.rb +23 -0
- data/lib/plaid/models/user.rb +192 -0
- data/lib/plaid/version.rb +1 -1
- data/lib/plaid.rb +77 -35
- data/plaid.gemspec +3 -1
- data/spec/account_spec.rb +35 -0
- data/spec/category_spec.rb +5 -14
- data/spec/config_spec.rb +57 -28
- data/spec/institution_spec.rb +6 -14
- data/spec/plaid_spec.rb +258 -0
- data/spec/spec_helper.rb +8 -1
- data/spec/transaction_spec.rb +30 -0
- data/spec/user_spec.rb +98 -109
- metadata +44 -12
- data/lib/plaid/add_user.rb +0 -24
- data/lib/plaid/category/category.rb +0 -29
- data/lib/plaid/institution/institution.rb +0 -29
- data/lib/plaid/user/account/account.rb +0 -35
- data/lib/plaid/user/info/info.rb +0 -23
- data/lib/plaid/user/transaction/transaction.rb +0 -19
- data/lib/plaid/user/user.rb +0 -173
- data/lib/plaid/util.rb +0 -120
- data/spec/add_user_spec.rb +0 -113
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3b8b2f76594f65f973077ad6cde5d686bf214e0f
|
4
|
+
data.tar.gz: f776703e98bdd32da28c1451c9686490eca81767
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9518764f519d2f8cc5535e50a16aed204032cb39e9e700c77c58782548dce249af9a76ab306aaa824023db281c3859449d4c47fb576c1da5abd8fc24a6c926c
|
7
|
+
data.tar.gz: 0f378b719b774502fb0f88dda4b82c66e62921e7d16b58ffb01300d1a2e6e8d524231b4b98f3ca8c26bdc11c0937636300444d62e0392887ed6e0320b0647077
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@ Ruby bindings for the Plaid API
|
|
6
6
|
|
7
7
|
This version is a beta version that contains failing tests for the new 'info' endpoint. While these have been tested individually on real accounts the tests here will fail with the test accounts supplied. These will be updated soon with test credentials.
|
8
8
|
|
9
|
-
Latest stable version: **1.
|
9
|
+
Latest stable version: **1.5.0**
|
10
10
|
|
11
11
|
This version removes the need to use 'type' in each additional call.
|
12
12
|
|
@@ -32,6 +32,7 @@ Or install it system wide as:
|
|
32
32
|
|
33
33
|
Please read the great documentation at http://plaid.com/docs/ for more information.
|
34
34
|
|
35
|
+
### Configuring Plaid
|
35
36
|
Configure the gem with your customer id, secret key, and the environment path you would like to use.
|
36
37
|
|
37
38
|
```ruby
|
@@ -39,15 +40,78 @@ Plaid.config do |p|
|
|
39
40
|
p.customer_id = 'Plaid provided customer ID here'
|
40
41
|
p.secret = 'Plaid provided secret key here'
|
41
42
|
p.environment_location = 'URL for the development or production environment'
|
43
|
+
# i.e. 'https://tartan.plaid.com/' for development, or
|
44
|
+
# 'https://api.plaid.com/' for production
|
42
45
|
end
|
43
46
|
```
|
44
47
|
|
48
|
+
### Creating a new Plaid User
|
45
49
|
Authenticate a user to your desired level of api access (auth / connect).
|
46
50
|
|
47
51
|
```ruby
|
48
52
|
user = Plaid.add_user('auth','plaid_test','plaid_good','wells')
|
49
53
|
```
|
50
54
|
|
55
|
+
If the authentication requires a pin, you can pass it in as the fifth argument:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
user = Plaid.add_user('auth', 'plaid_test', 'plaid_good', 'usaa', '1234')
|
59
|
+
```
|
60
|
+
|
61
|
+
To add options such as `login_only` or `webhooks`, use the sixth argument:
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
user = Plaid.add_user('auth','plaid_test','plaid_good','wells', nil, { login_only: true, webhooks: 'https://example.org/callbacks/plaid')
|
65
|
+
```
|
66
|
+
|
67
|
+
### Restoring a Plaid User using an access token
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
user = Plaid.set_user('access_token')
|
71
|
+
```
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
user = Plaid.set_user('access_token', 'wells')
|
75
|
+
```
|
76
|
+
|
77
|
+
### Exchanging a Link public_token for a Plaid access_token
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
Plaid.config do |p|
|
81
|
+
p.customer_id = 'test_id'
|
82
|
+
p.secret = 'test_secret'
|
83
|
+
p.environment_location = 'https://tartan.plaid.com'
|
84
|
+
end
|
85
|
+
|
86
|
+
# Exchange a Link public_token for a Plaid access_token
|
87
|
+
exchangeTokenResponse = Plaid.exchange_token('test,chase,connected')
|
88
|
+
|
89
|
+
# Use the API access_token to initialize a user
|
90
|
+
# Note: This example assumes you are using Link with the "auth" product
|
91
|
+
user = Plaid.set_user(exchangeTokenResponse.access_token, ['auth'])
|
92
|
+
|
93
|
+
# Retrieve the user's accounts
|
94
|
+
user.get('auth')
|
95
|
+
|
96
|
+
# Print the name of each account
|
97
|
+
user.accounts.each { |account| print account.meta['name'] + "\n"}
|
98
|
+
```
|
99
|
+
|
100
|
+
## Semantic Versioning
|
101
|
+
|
102
|
+
Methods marked with `API: public` are officially supported by the gem maintainers. Since
|
103
|
+
we are using semantic versioning (http://semver.org/spec/v2.0.0.html), the maintainers are
|
104
|
+
commited to backwards-compatibility support for these API calls when we update the Minor
|
105
|
+
version. So for example, going from version 1.4.x to 1.5.x will not change these public
|
106
|
+
API calls.
|
107
|
+
|
108
|
+
However, we may change these method signatures or even the gem architecture when updating
|
109
|
+
the Major number. For example, we have some breaking changes in mind with version 2.0
|
110
|
+
|
111
|
+
Methods marked with `API: semi-private` are used internally for consistency. While it is
|
112
|
+
possible to monkey-patch against them for your own use, the maintainers make no gaurantees
|
113
|
+
on backwards compatibility.
|
114
|
+
|
51
115
|
## Learn More
|
52
116
|
|
53
117
|
Learn about the full functionality of the library on our [Wiki](https://github.com/plaid/plaid-ruby/wiki)
|
@@ -56,4 +120,4 @@ Learn about the full functionality of the library on our [Wiki](https://github.c
|
|
56
120
|
|
57
121
|
We highly encourage helping out with the gem. Either adding more tests, building new helper classes, fixing bugs, or anything to increase overall quality.
|
58
122
|
|
59
|
-
Learn more about best practices, submitting a pull request, and rules for the build on our [Wiki](https://github.com/plaid/plaid-ruby/wiki/Contribute!)
|
123
|
+
Learn more about best practices, submitting a pull request, and rules for the build on our [Wiki](https://github.com/plaid/plaid-ruby/wiki/Contribute!)
|
data/lib/plaid/config.rb
CHANGED
@@ -1,13 +1,19 @@
|
|
1
1
|
module Plaid
|
2
2
|
module Configure
|
3
|
-
|
3
|
+
attr_accessor :customer_id, :secret, :environment_location
|
4
4
|
|
5
5
|
KEYS = [:customer_id, :secret, :environment_location]
|
6
6
|
|
7
7
|
def config
|
8
8
|
yield self
|
9
|
+
|
10
|
+
# Add trailing slash to api url if it is not present
|
11
|
+
if self.environment_location[-1] != '/'
|
12
|
+
self.environment_location += '/'
|
13
|
+
end
|
14
|
+
|
9
15
|
self
|
10
16
|
end
|
11
17
|
|
12
18
|
end
|
13
|
-
end
|
19
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'json'
|
3
|
+
require 'uri'
|
4
|
+
module Plaid
|
5
|
+
class Connection
|
6
|
+
class << self
|
7
|
+
# API: semi-private
|
8
|
+
def post(path, options = {})
|
9
|
+
uri = build_uri(path)
|
10
|
+
options.merge!(client_id: Plaid.customer_id, secret: Plaid.secret)
|
11
|
+
res = Net::HTTP.post_form(uri,options)
|
12
|
+
parse_response(res)
|
13
|
+
end
|
14
|
+
|
15
|
+
# API: semi-private
|
16
|
+
def get(path, id = nil)
|
17
|
+
uri = build_uri(path,id)
|
18
|
+
res = Net::HTTP.get(uri)
|
19
|
+
parse_get_response(res)
|
20
|
+
end
|
21
|
+
|
22
|
+
# API: semi-private
|
23
|
+
def secure_get(path, access_token, options = {})
|
24
|
+
uri = build_uri(path)
|
25
|
+
options.merge!({access_token:access_token})
|
26
|
+
req = Net::HTTP::Get.new(uri)
|
27
|
+
req.body = URI.encode_www_form(options) if options
|
28
|
+
req.content_type = 'multipart/form-data'
|
29
|
+
res = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == 'https') { |http| http.request(req) }
|
30
|
+
parse_response(res)
|
31
|
+
end
|
32
|
+
|
33
|
+
# API: semi-private
|
34
|
+
def patch(path, options = {})
|
35
|
+
uri = build_uri(path)
|
36
|
+
options.merge!(client_id: Plaid.customer_id, secret: Plaid.secret)
|
37
|
+
req = Net::HTTP::Patch.new(uri)
|
38
|
+
req.body = URI.encode_www_form(options) if options
|
39
|
+
req.content_type = 'multipart/form-data'
|
40
|
+
res = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == 'https') { |http| http.request(req) }
|
41
|
+
parse_response(res)
|
42
|
+
end
|
43
|
+
|
44
|
+
# API: semi-private
|
45
|
+
def delete(path, options = {})
|
46
|
+
uri = build_uri(path)
|
47
|
+
options.merge!(client_id: Plaid.customer_id, secret: Plaid.secret)
|
48
|
+
req = Net::HTTP::Delete.new(uri)
|
49
|
+
req.body = URI.encode_www_form(options) if options
|
50
|
+
req.content_type = 'multipart/form-data'
|
51
|
+
Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == 'https') { |http| http.request(req) }
|
52
|
+
end
|
53
|
+
|
54
|
+
# API: semi-private
|
55
|
+
# TODO: Refactor these to use symbols instead of strings
|
56
|
+
def error_handler(err, res = nil)
|
57
|
+
case err
|
58
|
+
when 'Bad Request'
|
59
|
+
puts res.body
|
60
|
+
raise 'The request was malformed. Did you check the API docs?'
|
61
|
+
when 'Unauthorized'
|
62
|
+
raise 'Access denied: Try using the correct credentials.'
|
63
|
+
when 'Corrupted token'
|
64
|
+
raise 'It appears that the access token has been corrupted'
|
65
|
+
else
|
66
|
+
raise err
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
protected
|
71
|
+
|
72
|
+
# API: semi-private
|
73
|
+
def build_uri(path, option = nil)
|
74
|
+
path = path + '/' + option unless option.nil?
|
75
|
+
URI.parse(Plaid.environment_location + path)
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def parse_response(res)
|
81
|
+
body = JSON.parse(res.body)
|
82
|
+
case res.code.delete('.').to_i
|
83
|
+
when 200 then body
|
84
|
+
when 201 then { msg: 'Requires further authentication', body: body}
|
85
|
+
when 400 then error_handler('Bad Request',res)
|
86
|
+
when 401
|
87
|
+
case body['code']
|
88
|
+
when 1108 then error_handler('Institution not supported', res)
|
89
|
+
when 1105 then error_handler('Corrupted token', res)
|
90
|
+
when 1106 then error_handler('Corrupted public_token', res)
|
91
|
+
when 1107 then error_handler('Missing public_token', res)
|
92
|
+
when 1501 then error_handler('Not Found', res)
|
93
|
+
else error_handler('Unauthorized',res)
|
94
|
+
end
|
95
|
+
when 402
|
96
|
+
return {msg: 'User account is locked', body: body} if body['code'] == 1205
|
97
|
+
error_handler('Request Failed', res)
|
98
|
+
when 404
|
99
|
+
error_handler('Not Found',res)
|
100
|
+
else
|
101
|
+
error_handler('Server Error',res)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def parse_get_response(res)
|
106
|
+
body = JSON.parse(res)
|
107
|
+
return body if body.kind_of?(Array)
|
108
|
+
|
109
|
+
case body['code']
|
110
|
+
when nil
|
111
|
+
body
|
112
|
+
when 1301, 1401, 1501, 1601
|
113
|
+
error_handler('Not Found',body)
|
114
|
+
else
|
115
|
+
body
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Plaid
|
2
|
+
class Account
|
3
|
+
attr_accessor :available_balance, :current_balance, :institution_type, :meta, :transactions, :numbers, :name, :id, :type, :subtype
|
4
|
+
|
5
|
+
def initialize(hash)
|
6
|
+
@id = hash['_id']
|
7
|
+
@name = hash['name']
|
8
|
+
@type = hash['type']
|
9
|
+
@meta = hash['meta']
|
10
|
+
@institution_type = hash['institution_type']
|
11
|
+
|
12
|
+
if hash['balance']
|
13
|
+
@available_balance = hash['balance']['available']
|
14
|
+
@current_balance = hash['balance']['current']
|
15
|
+
end
|
16
|
+
|
17
|
+
# Depository account only, "checkings" or "savings"
|
18
|
+
# Available on live data, but not on the test data
|
19
|
+
@subtype = hash['subtype']
|
20
|
+
|
21
|
+
@numbers = hash['numbers'] ? hash['numbers'] : 'Upgrade user to access routing information for this account'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Plaid
|
2
|
+
class Category
|
3
|
+
attr_accessor :type, :hierarchy, :id
|
4
|
+
|
5
|
+
def initialize(fields = {})
|
6
|
+
@type = fields['type']
|
7
|
+
@hierarchy = fields['hierarchy']
|
8
|
+
@id = fields['id']
|
9
|
+
end
|
10
|
+
|
11
|
+
# API: semi-private
|
12
|
+
# This method takes an array returned from the API and instantiates all of the categories
|
13
|
+
def self.all(res)
|
14
|
+
res.map { |cat| new(cat) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Plaid
|
2
|
+
class Information
|
3
|
+
attr_accessor :names, :emails, :phone_numbers, :addresses
|
4
|
+
|
5
|
+
def initialize(hash)
|
6
|
+
@names = hash['names']
|
7
|
+
@emails = hash['emails']
|
8
|
+
@phone_numbers = hash['phone_numbers']
|
9
|
+
@addresses = hash['addresses']
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Plaid
|
2
|
+
class Institution
|
3
|
+
attr_accessor :id, :name, :type, :has_mfa, :mfa
|
4
|
+
|
5
|
+
def initialize(fields = {})
|
6
|
+
@id = fields['id']
|
7
|
+
@name = fields['name']
|
8
|
+
@type = fields['type']
|
9
|
+
@has_mfa = fields['has_mfa']
|
10
|
+
@mfa = fields['mfa']
|
11
|
+
end
|
12
|
+
|
13
|
+
# API: semi-private
|
14
|
+
# This method takes an array returned from the API and instantiates all of the institutions
|
15
|
+
def self.all(res)
|
16
|
+
res.map { |inst| new(inst) }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Plaid
|
2
|
+
class Transaction
|
3
|
+
attr_accessor :id, :account, :date, :amount, :name, :meta, :location, :pending, :score, :cat, :type, :category, :category_id
|
4
|
+
|
5
|
+
def initialize(fields = {})
|
6
|
+
@id = fields['_id']
|
7
|
+
@account = fields['_account']
|
8
|
+
@date = fields['date']
|
9
|
+
@amount = fields['amount']
|
10
|
+
@name = fields['name']
|
11
|
+
@location = fields['meta'].nil? ? {} : fields['meta']['location']
|
12
|
+
@pending = fields['pending']
|
13
|
+
@score = fields['score']
|
14
|
+
@cat = Category.new({ 'id' => fields['category_id'], 'hierarchy' => fields['category'], 'type' => fields['type'] })
|
15
|
+
|
16
|
+
# Here for backwards compatibility only.
|
17
|
+
@type = fields['type']
|
18
|
+
@category = fields['category']
|
19
|
+
@category_id = fields['category_id']
|
20
|
+
@meta = fields['meta']
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
require_relative 'account'
|
2
|
+
require_relative 'transaction'
|
3
|
+
require_relative 'info'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module Plaid
|
7
|
+
class User
|
8
|
+
attr_accessor :accounts, :transactions, :access_token, :type, :permissions, :api_res, :pending_mfa_questions, :info, :information
|
9
|
+
|
10
|
+
# API: public
|
11
|
+
# Use this method to select the MFA method
|
12
|
+
def select_mfa_method(selection, type=nil)
|
13
|
+
type = self.type if type.nil?
|
14
|
+
auth_path = self.permissions.last + '/step'
|
15
|
+
res = Connection.post(auth_path, { options: { send_method: selection }.to_json, access_token: self.access_token, type: type })
|
16
|
+
update(res, self.permissions.last)
|
17
|
+
end
|
18
|
+
|
19
|
+
# API: public
|
20
|
+
# Use this method to send back the MFA code or answer
|
21
|
+
def mfa_authentication(auth, type = nil)
|
22
|
+
type = self.type if type.nil?
|
23
|
+
auth_path = self.permissions.last + '/step'
|
24
|
+
res = Connection.post(auth_path, { mfa: auth, access_token: self.access_token, type: type })
|
25
|
+
self.accounts = []
|
26
|
+
self.transactions = []
|
27
|
+
update(res)
|
28
|
+
end
|
29
|
+
|
30
|
+
# API: public
|
31
|
+
# Use this method to find out API levels available for this user
|
32
|
+
def permit?(auth_level)
|
33
|
+
self.permissions.include? auth_level
|
34
|
+
end
|
35
|
+
|
36
|
+
# API: public
|
37
|
+
# Use this method to upgrade a user to another api level
|
38
|
+
def upgrade(api_level=nil)
|
39
|
+
if api_level.nil?
|
40
|
+
api_level = 'auth' unless self.permit? 'auth'
|
41
|
+
api_level = 'connect' unless self.permit? 'connect'
|
42
|
+
end
|
43
|
+
res = Connection.post('upgrade', { access_token: self.access_token, upgrade_to: api_level })
|
44
|
+
|
45
|
+
# Reset accounts and transaction
|
46
|
+
self.accounts = []
|
47
|
+
self.transactions = []
|
48
|
+
update(res)
|
49
|
+
end
|
50
|
+
|
51
|
+
# API: public
|
52
|
+
# Use this method to delete a user from the Plaid API
|
53
|
+
def delete_user
|
54
|
+
Connection.delete('info', { access_token: self.access_token })
|
55
|
+
end
|
56
|
+
|
57
|
+
### Internal build methods
|
58
|
+
def initialize
|
59
|
+
self.accounts = []
|
60
|
+
self.transactions = []
|
61
|
+
self.permissions = []
|
62
|
+
self.access_token = ''
|
63
|
+
self.api_res = ''
|
64
|
+
self.info = {}
|
65
|
+
end
|
66
|
+
|
67
|
+
# API: semi-private
|
68
|
+
# This class method instantiates a new Account object and updates it with the results
|
69
|
+
# from the API
|
70
|
+
def self.build(res, api_level = nil)
|
71
|
+
self.new.update(res, api_level)
|
72
|
+
end
|
73
|
+
|
74
|
+
# API: semi-private
|
75
|
+
# This method updates Account with the results returned from the API
|
76
|
+
def update(res, api_level = nil)
|
77
|
+
self.permit! api_level
|
78
|
+
|
79
|
+
if res[:msg].nil?
|
80
|
+
populate_user!(res)
|
81
|
+
clean_up_user!
|
82
|
+
else
|
83
|
+
set_mfa_request!(res)
|
84
|
+
end
|
85
|
+
|
86
|
+
return self
|
87
|
+
end
|
88
|
+
|
89
|
+
# Internal helper methods
|
90
|
+
|
91
|
+
# API: semi-private
|
92
|
+
# Internal helper method to set the available API levels
|
93
|
+
def permit!(api_level)
|
94
|
+
return if api_level.nil? || self.permit?(api_level)
|
95
|
+
self.permissions << api_level
|
96
|
+
end
|
97
|
+
|
98
|
+
# API: semi-private
|
99
|
+
# Gets auth, connect, or info of the user
|
100
|
+
# TODO: (2.0) auth_level should be symbols instead of string
|
101
|
+
def get(auth_level, options = {})
|
102
|
+
return false unless self.permit? auth_level
|
103
|
+
case auth_level
|
104
|
+
when 'auth'
|
105
|
+
update(Connection.post('auth/get', access_token: self.access_token))
|
106
|
+
when 'connect'
|
107
|
+
payload = { access_token: self.access_token }.merge(options)
|
108
|
+
update(Connection.post('connect/get', payload))
|
109
|
+
when 'info'
|
110
|
+
update(Connection.secure_get('info', self.access_token))
|
111
|
+
else
|
112
|
+
raise "Invalid auth level: #{auth_level}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# API: semi-private
|
117
|
+
def get_auth
|
118
|
+
get('auth')
|
119
|
+
end
|
120
|
+
|
121
|
+
# API: semi-private
|
122
|
+
def get_connect(options={})
|
123
|
+
get('connect', options)
|
124
|
+
end
|
125
|
+
|
126
|
+
# API: semi-private
|
127
|
+
def get_info
|
128
|
+
get('info')
|
129
|
+
end
|
130
|
+
|
131
|
+
# API: semi-private
|
132
|
+
# Helper method to update user information
|
133
|
+
# Requires 'info' api level
|
134
|
+
def update_info(username,pass,pin=nil)
|
135
|
+
return false unless self.permit? 'info'
|
136
|
+
|
137
|
+
payload = { username: username, password: pass, access_token: self.access_token }
|
138
|
+
payload.merge!(pin: pin) if pin
|
139
|
+
update(Plaid.patch('info', payload))
|
140
|
+
end
|
141
|
+
|
142
|
+
# API: semi-private
|
143
|
+
# Helper method to update user balance
|
144
|
+
def update_balance
|
145
|
+
update(Connection.post('balance', { access_token: self.access_token }))
|
146
|
+
end
|
147
|
+
|
148
|
+
private
|
149
|
+
|
150
|
+
def clean_up_user!
|
151
|
+
self.accounts.select! { |c| c.instance_of? Account }
|
152
|
+
end
|
153
|
+
|
154
|
+
def set_mfa_request!(res)
|
155
|
+
self.access_token = res[:body]['access_token']
|
156
|
+
self.pending_mfa_questions = res[:body]
|
157
|
+
self.api_res = res[:msg]
|
158
|
+
end
|
159
|
+
|
160
|
+
def populate_user!(res)
|
161
|
+
res['accounts'].each do |account|
|
162
|
+
if self.accounts.any? { |h| h == account['_id'] }
|
163
|
+
owned_account = self.accounts.find { |h| h == account['_id'] }
|
164
|
+
owned_account.new(account)
|
165
|
+
else
|
166
|
+
self.accounts << Account.new(account)
|
167
|
+
end
|
168
|
+
end if res['accounts']
|
169
|
+
|
170
|
+
res['transactions'].each do |transaction|
|
171
|
+
if self.transactions.any? { |t| t == transaction['_id'] }
|
172
|
+
owned_transaction = self.transactions.find { |h| h == transaction['_id'] }
|
173
|
+
owned_transaction.new(transaction)
|
174
|
+
else
|
175
|
+
self.transactions << Transaction.new(transaction)
|
176
|
+
end
|
177
|
+
end if res['transactions']
|
178
|
+
|
179
|
+
self.pending_mfa_questions = ''
|
180
|
+
self.information = Information.new(res['info']) if res['info']
|
181
|
+
self.api_res = 'success'
|
182
|
+
|
183
|
+
# TODO: Remove the following line when upgrading to V-2
|
184
|
+
self.info.merge!(res['info']) if res['info']
|
185
|
+
# End TODO
|
186
|
+
|
187
|
+
self.access_token = res['access_token'].split[0]
|
188
|
+
self.type = res['access_token'].split[1]
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
end
|
data/lib/plaid/version.rb
CHANGED