plaid 4.0.0 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.env.sample +3 -0
- data/CHANGELOG.md +44 -0
- data/CONTRIBUTING.md +42 -2
- data/LICENSE.txt +1 -1
- data/PUBLISHING.md +14 -0
- data/README.md +12 -152
- data/Rakefile +34 -2
- data/UPGRADING.md +64 -0
- data/circle.yml +7 -1
- data/lib/plaid.rb +4 -5
- data/lib/plaid/client.rb +65 -47
- data/lib/plaid/errors.rb +16 -10
- data/lib/plaid/middleware.rb +25 -0
- data/lib/plaid/products/credit_details.rb +9 -2
- data/lib/plaid/products/institutions.rb +6 -3
- data/lib/plaid/products/item.rb +12 -0
- data/lib/plaid/products/transactions.rb +0 -13
- data/lib/plaid/version.rb +1 -1
- data/plaid.gemspec +10 -4
- metadata +82 -8
- data/lib/plaid/connect.rb +0 -75
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f1feea43dc48ce5bad450da5642293cf9a26637
|
4
|
+
data.tar.gz: 8e355726ca0db3969979088c505889b4f29d147f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6bcaccd07ed115c5629bd65ba34529aa3cb6264afc575bc9a8adf1859f9e217ac2544c74770283ccd8714edc26e3a167c957422b9d264486a99e3f80b986e2b5
|
7
|
+
data.tar.gz: 7a895e92f13d9ea624f0990834ecedab18613ffb946799d03c7c1972d3fb44ad948ec286d90d0fecb6cdf14627d3414fec1147039838d5c921f6c2168dc644b5
|
data/.env.sample
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# 4.1.0 04-Jan-2018
|
2
|
+
|
3
|
+
* Make `/item/remove` the primary Item removal endpoint
|
4
|
+
* Add #options parameter to `/institutions/get`
|
5
|
+
* Handle network errors with `PlaidServerError`
|
6
|
+
|
7
|
+
# 4.0.0 09-Mar-2017
|
8
|
+
|
9
|
+
* Refactored the entire library to support [Plaid's new API](https://blog.plaid.com/improving-our-api/). Use the [transition guide](https://plaid.com/docs/link/transition-guide) to update your integration. Version 3.x.x of this gem is mirrored at [plaid-legacy](https://github.com/plaid/plaid-ruby-legacy).
|
10
|
+
|
11
|
+
# 3.0.0. 17-Jan-2017
|
12
|
+
|
13
|
+
* Add `/institutions/all` and `/institutions/all/search` endpoints, see [UPGRADING.md](UPGRADING.md#upgrading-from-2xx-to-300)
|
14
|
+
|
15
|
+
# 2.2.0. 03-Nov-2016
|
16
|
+
|
17
|
+
* Add `Transaction#reference_number` (@ericbirdsall).
|
18
|
+
* Fix webhook codes and add risk and income webhooks.
|
19
|
+
|
20
|
+
# 2.1.0. 19-Oct-2016
|
21
|
+
|
22
|
+
* Documentation fixes (@ishmael).
|
23
|
+
* Fix `Transaction#to_s` behavior (@michel-tricot).
|
24
|
+
* PATCH `/:product/step` flow.
|
25
|
+
* Use the same client in `User#upgrade` (@betesh).
|
26
|
+
* Webhook object (@zshannon).
|
27
|
+
* `processor_token` access in `User.exchange_token` (@gylaz).
|
28
|
+
* Raise `ServerError` in case server returned an empty response body.
|
29
|
+
|
30
|
+
# 2.0.0. 24-May-2016
|
31
|
+
|
32
|
+
* Use `~> 1.0` spec for multi_json dependency.
|
33
|
+
* Support `stripe_bank_account_token` in `User.exchange_token`.
|
34
|
+
|
35
|
+
# 2.0.0.alpha.2. 14-May-2016
|
36
|
+
|
37
|
+
* Use `:production` instead of `:api` to signify production environment
|
38
|
+
in `Plaid::Client#env=`.
|
39
|
+
* `User#mfa_step` allows to specify options now (thanks @gcweeks).
|
40
|
+
* Implemented `User#update_webhook`.
|
41
|
+
|
42
|
+
# 2.0.0.alpha. 06-May-2016
|
43
|
+
|
44
|
+
* Rewrite everything.
|
data/CONTRIBUTING.md
CHANGED
@@ -4,6 +4,46 @@ After checking out the repo, run `bin/setup` to install dependencies. You can al
|
|
4
4
|
|
5
5
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
6
6
|
|
7
|
+
## Running tests
|
8
|
+
|
9
|
+
The gem test suite can be run in two modes. By default, it runs against the
|
10
|
+
live sandbox environment, creating items on the fly and calling various API
|
11
|
+
endpoints for them. For this to work you'll need real `client_id`, `secret`,
|
12
|
+
and `public_key` from your Plaid dashboard. Create a file named `.env`
|
13
|
+
based on `.env.sample` which is provided:
|
14
|
+
|
15
|
+
```text
|
16
|
+
PLAID_RUBY_CLIENT_ID=the_real_client_id
|
17
|
+
PLAID_RUBY_SECRET=the_real_secret
|
18
|
+
PLAID_RUBY_PUBLIC_KEY=the_real_public_key
|
19
|
+
```
|
20
|
+
This file will be loaded during the tests.
|
21
|
+
|
22
|
+
Another mode employs pre-recorded API responses using the
|
23
|
+
[vcr](https://github.com/vcr/vcr) gem. It runs much faster. Just use
|
24
|
+
`rake test_stubbed` and you're good to go even without `.env`!
|
25
|
+
|
26
|
+
## Updating VCR "cassettes"
|
27
|
+
|
28
|
+
In case you're adding new API endpoints or when there were any substantial
|
29
|
+
changes in API you'll need to update the pre-recorded responses. Here's how:
|
30
|
+
|
31
|
+
1. Make sure that `STUB_API=1 rake test` fails. It will fail saying something
|
32
|
+
like "... An HTTP request has been made that VCR does not know how to
|
33
|
+
handle".
|
34
|
+
2. Run `RECORD_MODE=all STUB_API=1 rake test`. This will run the whole suite
|
35
|
+
and re-record everything. If you only need to update data for one test class,
|
36
|
+
use this:
|
37
|
+
|
38
|
+
```
|
39
|
+
RECORD_MODE=all STUB_API=1 ruby -w -I"lib:test" -rminitest/pride test/test_which_fails.rb
|
40
|
+
```
|
41
|
+
3. Run `rake vcr_hide_credentials`. This step is essential, because
|
42
|
+
newly recorded files will contain your real `client_id` and friends. This
|
43
|
+
Rake task will go over all recorded files and replace real values with
|
44
|
+
stubbed ones used by `STUB_API=1 rake test`.
|
45
|
+
4. Run `STUB_API=1 rake test` and verify that everything works.
|
46
|
+
|
7
47
|
## Contributing
|
8
48
|
|
9
49
|
1. Make one or more atomic commits, and ensure that each commit has a
|
@@ -14,8 +54,8 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
14
54
|
|
15
55
|
3. Make sure that you've documented all public methods using [TomDoc](http://tomdoc.org/).
|
16
56
|
|
17
|
-
4. Run
|
18
|
-
in place using `git rebase` or `git commit --amend` to make the
|
57
|
+
4. Run tests (in both modes, see above) and address any errors. Preferably,
|
58
|
+
fix commits in place using `git rebase` or `git commit --amend` to make the
|
19
59
|
changes easier to review.
|
20
60
|
|
21
61
|
5. Open a pull request.
|
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2017
|
3
|
+
Copyright (c) 2017 Plaid Technologies, Inc.
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/PUBLISHING.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Publishing
|
2
|
+
|
3
|
+
The module is published to [RubyGems][1] under the gem name [plaid][2].
|
4
|
+
|
5
|
+
To publish:
|
6
|
+
|
7
|
+
1. `rake test` (runs the test suite locally).
|
8
|
+
2. Update, commit, and merge (with review) the `lib/plaid/version.rb` and `CHANGELOG.md` files.
|
9
|
+
5. `git pull` (makes sure your `HEAD` is up-to-date).
|
10
|
+
6. `rake release` (builds the gem, creates a tag, pushes the gem to RubyGems and tag to GitHub).
|
11
|
+
7. `rake update_github_docs` (generates RDoc files, updates `gh-pages` branch and pushes it to GitHub).
|
12
|
+
|
13
|
+
[1]: https://rubygems.org/
|
14
|
+
[2]: https://rubygems.org/gems/plaid
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
# plaid-ruby [![
|
1
|
+
# plaid-ruby [![Circle CI](https://circleci.com/gh/plaid/plaid-ruby.svg?style=svg&circle-token=30ee002ac2021da5b5b5a701d45fe2888af124a5)](https://circleci.com/gh/plaid/plaid-ruby) [![Gem Version](https://badge.fury.io/rb/plaid.svg)](http://badge.fury.io/rb/plaid)
|
2
2
|
|
3
3
|
The official Ruby bindings for the [Plaid API](https://plaid.com/docs).
|
4
4
|
|
5
|
-
This module was recently released as version `4.0.x`
|
5
|
+
**Note:** This module was recently refactored and released as version `4.0.x` to support [Plaid's updated API][1]. The previous module version, `3.0.x`, and API legacy documentation, is still available via RubyGems and mirrored as [`plaid-legacy`][2].
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
@@ -26,7 +26,7 @@ The gem supports Ruby 2.1+ only.
|
|
26
26
|
|
27
27
|
This gem wraps the Plaid API, which is fully described in the [documentation](https://plaid.com/docs/api).
|
28
28
|
|
29
|
-
The RubyDoc for the gem is available [here](
|
29
|
+
The RubyDoc for the gem is available [here](http://plaid.github.io/plaid-ruby/).
|
30
30
|
|
31
31
|
### Creating a Plaid client
|
32
32
|
|
@@ -43,87 +43,13 @@ $client = Plaid::Client.new(env: :sandbox,
|
|
43
43
|
```
|
44
44
|
|
45
45
|
The `env` field is the environment which the client will be running in. Your choices for the `env` field include:
|
46
|
-
- `:sandbox` allows you to do your initial integrations tests against preloaded data without being billed or making expensive API calls. More information about using the API sandbox can be found on the [API Sandbox documentation](https://plaid.com/docs/api
|
46
|
+
- `:sandbox` allows you to do your initial integrations tests against preloaded data without being billed or making expensive API calls. More information about using the API sandbox can be found on the [API Sandbox documentation](https://plaid.com/docs/api#sandbox).
|
47
47
|
- `:development` allows you to test against both real and test accounts without being billed. More information about Plaid test accounts can be found in our [API documentation](https://plaid.com/docs/api/#sandbox).
|
48
48
|
- `:production` is the production environment where you can launch your production ready application and be charged for your Plaid usage.
|
49
49
|
|
50
|
-
### Creating a new item
|
51
|
-
|
52
|
-
A new item can be created by providing a set of credentials, an institution code, and a list of products to create the item with.
|
53
|
-
|
54
|
-
```ruby
|
55
|
-
item = client.item.create(credentials: { username: 'user_good',
|
56
|
-
password: 'pass_good',
|
57
|
-
pin: '1234' },
|
58
|
-
institution_id: 'ins_109509',
|
59
|
-
initial_products: %i(auth identity transactions))
|
60
|
-
```
|
61
|
-
The first argument for `client.item.create` is always the credentials in the form of a hash.
|
62
|
-
```ruby
|
63
|
-
credentials = { username: 'user_good',
|
64
|
-
password: 'pass_good',
|
65
|
-
pin: '1234' }
|
66
|
-
```
|
67
|
-
The `pin` field in the credentials hash is not required and does not need to be entered if your institution does not require it.
|
68
|
-
|
69
|
-
A successful, non-MFA (multi-factor authentication) response (HTTP 200) to an item creation will come in the form of a hash where each of these attributes can be accessed by the corresponding string key:
|
70
|
-
```ruby
|
71
|
-
{ "access_token" => String,
|
72
|
-
"item" => { "available_products" => [String],
|
73
|
-
"billed_products" => [String],
|
74
|
-
"error" => Object,
|
75
|
-
"institution_id" => String,
|
76
|
-
"item_id" => String,
|
77
|
-
"webhook" => nullable String },
|
78
|
-
"request_id" => String }
|
79
|
-
```
|
80
|
-
The response provides three primary pieces of information:
|
81
|
-
- `access_token` is your token to access this item and the item's products in the future such as `auth` or `transactions`
|
82
|
-
- `item` provides information about the item such as the `item_id` and `available_products`
|
83
|
-
- `request_id` is the identifier for your actual request, this is often used to file tickets if necessary
|
84
|
-
|
85
|
-
There are other responses you can receive from an item creation such as an MFA response and an error response (they're all in hash form).
|
86
|
-
|
87
|
-
An MFA response (HTTP 210) looks like this:
|
88
|
-
```ruby
|
89
|
-
{ "access_token" => String,
|
90
|
-
"device" => nullable String,
|
91
|
-
"device_list" => nullable [Object],
|
92
|
-
"mfa_type" => String Enum (device, device_list, questions, selections),
|
93
|
-
"questions" => nullable [String],
|
94
|
-
"request_id" => String,
|
95
|
-
"selections" => nullable [Object] }
|
96
|
-
```
|
97
|
-
|
98
|
-
An example of how an MFA onboarding flow looks like can be seen below in the Examples section.
|
99
|
-
|
100
|
-
If an error occurs during the creation, an error will be thrown. The class for the error has values that you can access by using the following keys.
|
101
|
-
```ruby
|
102
|
-
{ "error_type" => String,
|
103
|
-
"error_code" => String,
|
104
|
-
"error_message" => String,
|
105
|
-
"display_message" => (nullable) String,
|
106
|
-
"request_id" => String }
|
107
|
-
```
|
108
|
-
Additional information on the meaning or usage of each field can be found in our [API Error documentation](https://plaid.com/docs/api#errors).
|
109
|
-
|
110
|
-
You can also add options such as `transactions.await_results` or `webhook` to your item creation, use keyed arguments:
|
111
|
-
|
112
|
-
```ruby
|
113
|
-
item = client.item.create(credentials: { username: 'user_good',
|
114
|
-
password: 'pass_good' },
|
115
|
-
institution_id: 'ins_109509',
|
116
|
-
initial_products: %i(auth identity transactions),
|
117
|
-
transactions_await_results: true,
|
118
|
-
webhook: 'https://plaid.com/webhook-test')
|
119
|
-
```
|
120
|
-
|
121
|
-
More information about item creation options can be found in our [API documentation](https://plaid.com/docs/api#post-itemcreate).
|
122
|
-
|
123
|
-
|
124
50
|
## Examples
|
125
51
|
|
126
|
-
### Exchanging a Link
|
52
|
+
### Exchanging a Link public_token for a Plaid access_token
|
127
53
|
|
128
54
|
If you have a [Link](https://github.com/plaid/link) `public token`, use this function to get an `access_token`: `client.item.public_token.exchange(public_token)`
|
129
55
|
|
@@ -134,75 +60,6 @@ response = client.item.public_token.exchange(public_token)
|
|
134
60
|
access_token = response['access_token']
|
135
61
|
```
|
136
62
|
|
137
|
-
### Handle MFA during item creation
|
138
|
-
|
139
|
-
If MFA is requested by the financial institution, there will be additional steps required to finish the item creation flow:
|
140
|
-
```ruby
|
141
|
-
require 'plaid'
|
142
|
-
|
143
|
-
def answer_mfa(client, access_token, data)
|
144
|
-
case data['mfa_type']
|
145
|
-
when 'questions'
|
146
|
-
answer_questions(client, access_token, data['questions'])
|
147
|
-
when 'device_list'
|
148
|
-
answer_device_list(client, access_token, data['device_list'])
|
149
|
-
when 'selections'
|
150
|
-
answer_selections(client, access_token, data['selections'])
|
151
|
-
when 'device'
|
152
|
-
answer_device(client, access_token, data['device'])
|
153
|
-
else
|
154
|
-
raise 'Unknown MFA type from Plaid'
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
def answer_questions(client, access_token, _questions)
|
159
|
-
# We have magically inferred the answer here, so we respond immediately.
|
160
|
-
# In the real world, we would present the questions to our user and
|
161
|
-
# submit their responses.
|
162
|
-
answers = ['answer_0_0']
|
163
|
-
client.item.mfa(access_token, 'questions', answers)
|
164
|
-
end
|
165
|
-
|
166
|
-
def answer_device_list(client, access_token, device_list)
|
167
|
-
# We have picked the first device here.
|
168
|
-
# In the real world, we would ask our user which device the passcode
|
169
|
-
# should be sent to.
|
170
|
-
device = device_list[0]['device_id']
|
171
|
-
client.item.mfa(access_token, 'device_list', [device])
|
172
|
-
end
|
173
|
-
|
174
|
-
def answer_device(client, access_token, _device)
|
175
|
-
# Another magically inferred answer.
|
176
|
-
# In the real world, we would ask our user for the passcode they received.
|
177
|
-
client.item.mfa(access_token, 'device', ['1234'])
|
178
|
-
end
|
179
|
-
|
180
|
-
def answer_selections(client, access_token, _selections)
|
181
|
-
# We have magically inferred the answer here, so we respond immediately.
|
182
|
-
# In the real world, we would present the selection question and choices
|
183
|
-
# to our user and submit their responses.
|
184
|
-
answers = %w(tomato ketchup)
|
185
|
-
client.item.mfa(access_token, 'selections', answers)
|
186
|
-
end
|
187
|
-
|
188
|
-
begin
|
189
|
-
client = Plaid::Client.new(env: :sandbox,
|
190
|
-
client_id: '***',
|
191
|
-
secret: '***',
|
192
|
-
public_key: '***')
|
193
|
-
|
194
|
-
response = client.item.create(credentials: { username: 'user_good',
|
195
|
-
password: 'mfa_device' },
|
196
|
-
institution_id: 'ins_109508',
|
197
|
-
initial_products: %i(transactions auth))
|
198
|
-
|
199
|
-
access_token = response['access_token']
|
200
|
-
response = answer_mfa(client, access_token, response) while response.key?('mfa_type')
|
201
|
-
rescue Plaid::PlaidError
|
202
|
-
raise 'Error in main flow.'
|
203
|
-
end
|
204
|
-
```
|
205
|
-
|
206
63
|
### Deleting an item
|
207
64
|
|
208
65
|
```ruby
|
@@ -220,8 +77,8 @@ response = client.item.create(credentials: { username: 'user_good',
|
|
220
77
|
|
221
78
|
access_token = response['access_token']
|
222
79
|
|
223
|
-
# Provide the access_token for the Item you want to
|
224
|
-
client.item.
|
80
|
+
# Provide the access_token for the Item you want to remove
|
81
|
+
client.item.remove(access_token)
|
225
82
|
```
|
226
83
|
|
227
84
|
### Get paginated transactions
|
@@ -245,7 +102,7 @@ transactions = transaction_response['transactions']
|
|
245
102
|
|
246
103
|
# the transactions in the response are paginated, so make multiple calls while
|
247
104
|
# increasing the offset to retrieve all transactions
|
248
|
-
while transactions.length <
|
105
|
+
while transactions.length < transaction_response['total_transactions']
|
249
106
|
transaction_response = client.transactions.get(access_token,
|
250
107
|
'2016-07-12',
|
251
108
|
'2017-01-09',
|
@@ -255,7 +112,7 @@ end
|
|
255
112
|
|
256
113
|
```
|
257
114
|
|
258
|
-
### Obtaining
|
115
|
+
### Obtaining Item-related data
|
259
116
|
|
260
117
|
If you have an `access_token`, you can use following code to retreive data:
|
261
118
|
```ruby
|
@@ -353,3 +210,6 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/plaid/
|
|
353
210
|
## License
|
354
211
|
|
355
212
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
213
|
+
|
214
|
+
[1]: https://blog.plaid.com/improving-our-api/
|
215
|
+
[2]: https://github.com/plaid/plaid-ruby-legacy
|
data/Rakefile
CHANGED
@@ -2,6 +2,7 @@ require 'bundler/gem_tasks'
|
|
2
2
|
require 'sdoc'
|
3
3
|
require 'rdoc/task'
|
4
4
|
require 'rake/testtask'
|
5
|
+
require 'dotenv/load'
|
5
6
|
require 'fileutils'
|
6
7
|
|
7
8
|
RDoc::Task.new do |rdoc|
|
@@ -9,7 +10,7 @@ RDoc::Task.new do |rdoc|
|
|
9
10
|
rdoc.generator = 'sdoc'
|
10
11
|
rdoc.main = 'README.md'
|
11
12
|
|
12
|
-
rdoc.rdoc_files.include('README.md', 'LICENSE
|
13
|
+
rdoc.rdoc_files.include('README.md', 'LICENSE.txt', 'lib/**/*.rb')
|
13
14
|
rdoc.markup = 'tomdoc'
|
14
15
|
end
|
15
16
|
|
@@ -50,4 +51,35 @@ task update_github_docs: %i(rdoc update_gh_pages) do
|
|
50
51
|
sh 'git push origin gh-pages'
|
51
52
|
end
|
52
53
|
|
53
|
-
|
54
|
+
desc 'Hide real credentials in VCR cassettes'
|
55
|
+
task :vcr_hide_credentials do
|
56
|
+
|
57
|
+
all_creds = %w(PLAID_RUBY_CLIENT_ID PLAID_RUBY_SECRET PLAID_RUBY_PUBLIC_KEY)
|
58
|
+
|
59
|
+
all_creds.each do |cred|
|
60
|
+
fail "#{cred} is not set" unless ENV[cred]
|
61
|
+
end
|
62
|
+
|
63
|
+
Dir['test/vcr_cassettes/*'].each do |fn|
|
64
|
+
data = File.read(fn)
|
65
|
+
data_0 = data.clone
|
66
|
+
|
67
|
+
all_creds.each do |cred|
|
68
|
+
data.gsub! ENV[cred], cred
|
69
|
+
end
|
70
|
+
|
71
|
+
if data != data_0
|
72
|
+
File.open(fn, 'w') { |f| f.write data }
|
73
|
+
|
74
|
+
puts ">> Updated #{fn}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
task :test_stubbed do
|
81
|
+
ENV['STUB_API'] ||= '1'
|
82
|
+
Rake::Task['test'].invoke
|
83
|
+
end
|
84
|
+
|
85
|
+
task default: :test_stubbed
|
data/UPGRADING.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
## Upgrading from 3.x.x to 4.0.0
|
2
|
+
|
3
|
+
Version 4.0.0 supports [Plaid's new API](https://blog.plaid.com/improving-our-api/). Use the [transition guide](https://plaid.com/docs/link/transition-guide) to update your integration.
|
4
|
+
|
5
|
+
## Upgrading from 2.x.x to 3.0.0
|
6
|
+
|
7
|
+
Version 3.0.0 makes `Plaid::Institution` use new `institutions/all` endpoint
|
8
|
+
of Plaid API which unites "native" and "long tail" institutions.
|
9
|
+
`Plaid::LongTailInstitution` class is removed, its functionality is
|
10
|
+
concentrated in `Plaid::Institution`.
|
11
|
+
|
12
|
+
Use `Plaid::Institution.all` instead of `Plaid::LongTailInstitution.all` (the
|
13
|
+
semantics is the same, with added products param).
|
14
|
+
|
15
|
+
Use `Plaid::Institution.search` instead of `Plaid::LongTailInstitution.search`.
|
16
|
+
|
17
|
+
Use `Plaid::Institution.search_by_id` instead of `Plaid::LongTailInstitution.get`.
|
18
|
+
|
19
|
+
|
20
|
+
## Upgrading from 1.x to 2.0.0
|
21
|
+
|
22
|
+
Make sure you use Ruby 2.0 or higher.
|
23
|
+
|
24
|
+
Update the `Plaid.config` block:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
Plaid.config do |p|
|
28
|
+
p.client_id = '<<< Plaid provided client ID >>>' # WAS: customer_id
|
29
|
+
p.secret = '<<< Plaid provided secret key >>>' # No change
|
30
|
+
p.env = :tartan # or :api for production # WAS: environment_location
|
31
|
+
end
|
32
|
+
```
|
33
|
+
|
34
|
+
Use `Plaid::User.create` instead of `Plaid.add_user` (**NOTE**: parameter order has changed!)
|
35
|
+
|
36
|
+
Use `Plaid::User.load` instead of `Plaid.set_user` (**NOTE**: parameter order has changed!)
|
37
|
+
|
38
|
+
Use `Plaid::User.exchange_token` instead of `Plaid.exchange_token` (**NOTE**: parameter list has changed!)
|
39
|
+
|
40
|
+
Use `Plaid::User.create` or (`.load`) and `Plaid::User#transactions` instead of `Plaid.transactions`.
|
41
|
+
|
42
|
+
Use `Plaid::Institution.all` and `Plaid::Institution.get` instead of `Plaid.institution`.
|
43
|
+
|
44
|
+
Use `Plaid::Category.all` and `Plaid::Category.get` instead of `Plaid.category`.
|
45
|
+
|
46
|
+
`Plaid::Account#institution_type` was renamed to `Plaid::Account#institution`.
|
47
|
+
|
48
|
+
`Plaid::Transaction#account` was renamed to `Plaid::Transaction#account_id`.
|
49
|
+
|
50
|
+
`Plaid::Transaction#date` is a Date, not a String object now.
|
51
|
+
|
52
|
+
`Plaid::Transaction#cat` was removed. Use `Plaid::Transaction#category_hierarchy` and `Plaid::Transaction#category_id` directly.
|
53
|
+
|
54
|
+
`Plaid::Transaction#category` was renamed to `Plaid::Transaction#category_hierarchy`.
|
55
|
+
|
56
|
+
`Plaid::Transaction#pending_transaction` was renamed to `Plaid::Transaction#pending_transaction_id`.
|
57
|
+
|
58
|
+
Use `Plaid::User#mfa_step` instead of `Plaid::User#select_mfa_method` and `Plaid::User#mfa_authentication`.
|
59
|
+
|
60
|
+
`Plaid::User#permit?` was removed. You don't need this.
|
61
|
+
|
62
|
+
`Plaid::User.delete_user` was renamed to `Plaid::User.delete`.
|
63
|
+
|
64
|
+
**NOTE** that Symbols are now consistently used instead of Strings as product names, keys in hashes, etc. Look at the docs, they have all the examples.
|
data/circle.yml
CHANGED
data/lib/plaid.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'faraday_middleware'
|
3
|
+
|
4
|
+
require_relative 'plaid/middleware'
|
1
5
|
require_relative 'plaid/client'
|
2
|
-
require_relative 'plaid/connect'
|
3
6
|
require_relative 'plaid/errors'
|
4
7
|
require_relative 'plaid/version'
|
5
8
|
require_relative 'plaid/products/accounts'
|
@@ -13,7 +16,3 @@ require_relative 'plaid/products/item'
|
|
13
16
|
require_relative 'plaid/products/processor'
|
14
17
|
require_relative 'plaid/products/sandbox'
|
15
18
|
require_relative 'plaid/products/transactions'
|
16
|
-
|
17
|
-
# Public: The Plaid namespace.
|
18
|
-
module Plaid
|
19
|
-
end
|
data/lib/plaid/client.rb
CHANGED
@@ -1,36 +1,29 @@
|
|
1
1
|
# Public: The Plaid namespace.
|
2
2
|
module Plaid
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# env - The type of the environment in symbol form
|
6
|
-
#
|
7
|
-
# Returns a string representing an environment URL
|
8
|
-
def self.url_from_env(env)
|
9
|
-
case env
|
10
|
-
when :sandbox
|
11
|
-
'https://sandbox.plaid.com/'
|
12
|
-
when :development
|
13
|
-
'https://development.plaid.com/'
|
14
|
-
when :production
|
15
|
-
'https://production.plaid.com/'
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# Public: A class encapsulating client_id, secret, public key, and Plaid environment.
|
3
|
+
# Public: The main interface to Plaid API.
|
20
4
|
class Client
|
21
|
-
#
|
22
|
-
|
23
|
-
|
5
|
+
# Public: All possible environments for the client to use.
|
6
|
+
ENVIRONMENTS = %i(sandbox development production)
|
7
|
+
|
8
|
+
# Public: The current environment in use (one of ENVIRONMENTS).
|
9
|
+
attr_reader :env
|
10
|
+
|
11
|
+
# Public: Construct a Client instance
|
24
12
|
#
|
25
|
-
#
|
13
|
+
# Optionally takes a block to allow overriding the default Faraday connection options.
|
26
14
|
#
|
27
|
-
#
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
15
|
+
# env - The Symbol (:sandbox, :development, :production)
|
16
|
+
# client_id - The String Plaid account client ID to authenticate requests
|
17
|
+
# secret - The String Plaid account secret to authenticate requests
|
18
|
+
# public_key - The String Plaid account public key to authenticate requests
|
19
|
+
def initialize(env:, client_id:, secret:, public_key:, &block)
|
20
|
+
@env = env.to_sym
|
21
|
+
@api_host = api_host
|
22
|
+
@client_id = client_id
|
23
|
+
@secret = secret
|
24
|
+
@public_key = public_key
|
25
|
+
|
26
|
+
create_connection(&block)
|
34
27
|
end
|
35
28
|
|
36
29
|
# Public: Memoized class instance to make requests from Plaid::Account
|
@@ -88,19 +81,6 @@ module Plaid
|
|
88
81
|
@transactions ||= Plaid::Transactions.new(self)
|
89
82
|
end
|
90
83
|
|
91
|
-
# Public: Construct a Client instance
|
92
|
-
#
|
93
|
-
# env - The Symbol (:sandbox, :development, :production)
|
94
|
-
# client_id - The String Plaid account client ID to authenticate requests
|
95
|
-
# secret - The String Plaid account secret to authenticate requests
|
96
|
-
# public_key - The String Plaid account public key to authenticate requests
|
97
|
-
def initialize(env:, client_id:, secret:, public_key:)
|
98
|
-
@env = env_map(env)
|
99
|
-
@client_id = client_id
|
100
|
-
@secret = secret
|
101
|
-
@public_key = public_key
|
102
|
-
end
|
103
|
-
|
104
84
|
# Public: Make a post request
|
105
85
|
#
|
106
86
|
# path - Path or URL to make the request to
|
@@ -108,7 +88,7 @@ module Plaid
|
|
108
88
|
#
|
109
89
|
# Returns the resulting parsed JSON of the request
|
110
90
|
def post(path, payload)
|
111
|
-
|
91
|
+
@connection.post(path, payload).body
|
112
92
|
end
|
113
93
|
|
114
94
|
# Public: Make a post request with appended authentication fields
|
@@ -118,9 +98,9 @@ module Plaid
|
|
118
98
|
#
|
119
99
|
# Returns the resulting parsed JSON of the request
|
120
100
|
def post_with_auth(path, payload)
|
121
|
-
|
122
|
-
|
123
|
-
|
101
|
+
@connection.post(
|
102
|
+
path,
|
103
|
+
payload.merge(client_id: @client_id, secret: @secret)).body
|
124
104
|
end
|
125
105
|
|
126
106
|
# Public: Make a post request with appended public key field.
|
@@ -130,8 +110,46 @@ module Plaid
|
|
130
110
|
#
|
131
111
|
# Returns the resulting parsed JSON of the request.
|
132
112
|
def post_with_public_key(path, payload)
|
133
|
-
|
134
|
-
|
113
|
+
@connection.post(path, payload.merge(public_key: @public_key)).body
|
114
|
+
end
|
115
|
+
|
116
|
+
protected
|
117
|
+
|
118
|
+
# Internal: Gets the API hostname for given environment.
|
119
|
+
#
|
120
|
+
# env - The Symbol (:sandbox, :development, :production)
|
121
|
+
#
|
122
|
+
# Returns a String representing the environment URL.
|
123
|
+
# Raises ArgumentError if environment is unknown.
|
124
|
+
def api_host
|
125
|
+
unless ENVIRONMENTS.include?(@env)
|
126
|
+
raise ArgumentError,
|
127
|
+
"Invalid value for env (#{@env.inspect}): must be one of " +
|
128
|
+
ENVIRONMENTS.map(&:inspect) * ', '
|
129
|
+
end
|
130
|
+
|
131
|
+
"https://#{@env}.plaid.com"
|
132
|
+
end
|
133
|
+
|
134
|
+
# Internal: Initializes a new Plaid connection object via Faraday.
|
135
|
+
#
|
136
|
+
# Optionally takes a block to allow overriding the defaults.
|
137
|
+
def create_connection(&block)
|
138
|
+
@connection = Faraday.new(url: @api_host) do |builder|
|
139
|
+
block_given? ? yield(builder) : build_default_connection(builder)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# Internal: Set Plaid defaults on the Faraday connection.
|
144
|
+
#
|
145
|
+
# builder - The Faraday builder object.
|
146
|
+
def build_default_connection(builder)
|
147
|
+
builder.options[:timeout] = Plaid::Middleware::NETWORK_TIMEOUT
|
148
|
+
builder.headers = Plaid::Middleware::NETWORK_HEADERS
|
149
|
+
builder.request :json
|
150
|
+
builder.use Plaid::Middleware
|
151
|
+
builder.response :json, content_type: /\bjson$/
|
152
|
+
builder.adapter Faraday.default_adapter
|
135
153
|
end
|
136
154
|
end
|
137
155
|
end
|
data/lib/plaid/errors.rb
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
module Plaid
|
2
|
-
#
|
3
|
-
class PlaidError < StandardError
|
2
|
+
# Public: Base class for Plaid SDK errors
|
3
|
+
class PlaidError < StandardError; end
|
4
|
+
|
5
|
+
# Public: returned on Plaid server or network issues
|
6
|
+
class PlaidServerError < PlaidError; end
|
7
|
+
|
8
|
+
# Public: Base class for any error returned by the API
|
9
|
+
class PlaidAPIError < PlaidError
|
4
10
|
attr_reader :error_type, :error_code, :error_message, :display_message, :request_id
|
5
11
|
|
6
12
|
# Internal: Initialize an error with proper attributes
|
@@ -27,28 +33,28 @@ module Plaid
|
|
27
33
|
end
|
28
34
|
|
29
35
|
# Public: returned when the request is malformed and cannot be processed.
|
30
|
-
class InvalidRequestError <
|
36
|
+
class InvalidRequestError < PlaidAPIError; end
|
31
37
|
|
32
38
|
# Public: returned when all fields are provided and are in the correct format,
|
33
39
|
# but the values provided are incorrect in some way.
|
34
|
-
class InvalidInputError <
|
40
|
+
class InvalidInputError < PlaidAPIError; end
|
35
41
|
|
36
42
|
# Public: returned when the request is valid but has exceeded established rate limits.
|
37
|
-
class RateLimitExceededError <
|
43
|
+
class RateLimitExceededError < PlaidAPIError; end
|
38
44
|
|
39
45
|
# Public: returned during planned maintenance windows and
|
40
46
|
# in response to API internal server errors.
|
41
|
-
class APIError <
|
47
|
+
class APIError < PlaidAPIError; end
|
42
48
|
|
43
49
|
# Public: indicates that information provided for the item (such as credentials or MFA)
|
44
50
|
# may be invalid or that the item is not supported on Plaid's platform.
|
45
|
-
class ItemError <
|
51
|
+
class ItemError < PlaidAPIError; end
|
46
52
|
|
47
53
|
# Internal: A module that provides utilities for errors.
|
48
54
|
module Error
|
49
|
-
# Internal: Map error_type to
|
55
|
+
# Internal: Map error_type to PlaidAPIError
|
50
56
|
#
|
51
|
-
# Maps an error_type from an error HTTP response to an actual
|
57
|
+
# Maps an error_type from an error HTTP response to an actual PlaidAPIError class instance
|
52
58
|
#
|
53
59
|
# error_type - The type of the error as indicated by the error response body
|
54
60
|
#
|
@@ -66,7 +72,7 @@ module Plaid
|
|
66
72
|
when 'ITEM_ERROR'
|
67
73
|
Plaid::ItemError
|
68
74
|
else
|
69
|
-
Plaid::
|
75
|
+
Plaid::PlaidAPIError
|
70
76
|
end
|
71
77
|
end
|
72
78
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'net/http'
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
require_relative 'version'
|
6
|
+
|
7
|
+
module Plaid
|
8
|
+
class Middleware < ::Faraday::Response::Middleware
|
9
|
+
# Internal: Headers used for correct request and SDK tracking.
|
10
|
+
NETWORK_HEADERS = { 'User-Agent' => "Plaid Ruby v#{Plaid::VERSION}",
|
11
|
+
'Content-Type' => 'application/json' }.freeze
|
12
|
+
|
13
|
+
# Internal: Default read timeout for HTTP calls in seconds.
|
14
|
+
NETWORK_TIMEOUT = 600
|
15
|
+
|
16
|
+
def on_complete(env)
|
17
|
+
return unless Faraday::Response::RaiseError::ClientErrorStatuses.include?(env[:status])
|
18
|
+
raise Plaid::Error.error_from_type(env.body['error_type']).new(env.body['error_type'],
|
19
|
+
env.body['error_code'],
|
20
|
+
env.body['error_message'],
|
21
|
+
env.body['display_message'],
|
22
|
+
env.body['request_id'])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -11,10 +11,17 @@ module Plaid
|
|
11
11
|
# and access_token's item
|
12
12
|
#
|
13
13
|
# access_token - access_token who's item to fetch credit_details for
|
14
|
+
# account_ids - Specific account ids to fetch credit_details for (optional)
|
14
15
|
#
|
15
16
|
# Returns a parsed JSON of credit_details information
|
16
|
-
def get(access_token)
|
17
|
-
|
17
|
+
def get(access_token, account_ids: nil)
|
18
|
+
options_payload = {}
|
19
|
+
options_payload[:account_ids] = account_ids unless account_ids.nil?
|
20
|
+
payload = {
|
21
|
+
access_token: access_token,
|
22
|
+
options: options_payload
|
23
|
+
}
|
24
|
+
|
18
25
|
@client.post_with_auth('credit_details/get', payload)
|
19
26
|
end
|
20
27
|
end
|
@@ -10,13 +10,16 @@ module Plaid
|
|
10
10
|
# Does a POST /institutions/get call pulls a list of supported Plaid institutions
|
11
11
|
# with the information for each institution
|
12
12
|
#
|
13
|
-
# count
|
14
|
-
# offset
|
13
|
+
# count - Amount of institutions to pull
|
14
|
+
# offset - Offset to start pulling institutions
|
15
|
+
# options - Options for filtering institutions
|
15
16
|
#
|
16
17
|
# Returns a parsed JSON of listed institution information
|
17
|
-
def get(count:, offset:)
|
18
|
+
def get(count:, offset:, options: nil)
|
18
19
|
payload = { count: count,
|
19
20
|
offset: offset }
|
21
|
+
payload[:options] = options unless options.nil?
|
22
|
+
|
20
23
|
@client.post_with_auth('institutions/get', payload)
|
21
24
|
end
|
22
25
|
|
data/lib/plaid/products/item.rb
CHANGED
@@ -226,5 +226,17 @@ module Plaid
|
|
226
226
|
payload = { access_token: access_token }
|
227
227
|
@client.post_with_auth('item/delete', payload)
|
228
228
|
end
|
229
|
+
|
230
|
+
# Public: Removes an item
|
231
|
+
#
|
232
|
+
# Does a POST /item/remove call which is used to remove an item
|
233
|
+
#
|
234
|
+
# access_token - access_token who's item to remove
|
235
|
+
#
|
236
|
+
# Returns a parsed JSON of remove result
|
237
|
+
def remove(access_token)
|
238
|
+
payload = { access_token: access_token }
|
239
|
+
@client.post_with_auth('item/remove', payload)
|
240
|
+
end
|
229
241
|
end
|
230
242
|
end
|
@@ -57,18 +57,5 @@ module Plaid
|
|
57
57
|
options: options_payload }
|
58
58
|
@client.post_with_auth('transactions/get', payload)
|
59
59
|
end
|
60
|
-
|
61
|
-
# Public: Deactivate transactions for given access_token.
|
62
|
-
#
|
63
|
-
# Does a POST /transactions/deactivate call which deactivates the transaction product
|
64
|
-
# for a given access_token
|
65
|
-
#
|
66
|
-
# access_token - access_token to deactivate transactions for
|
67
|
-
#
|
68
|
-
# Returns a parsed JSON containing a message describing deactivation success.
|
69
|
-
def deactivate(access_token)
|
70
|
-
payload = { access_token: access_token }
|
71
|
-
@client.post_with_auth('transactions/deactivate', payload)
|
72
|
-
end
|
73
60
|
end
|
74
61
|
end
|
data/lib/plaid/version.rb
CHANGED
data/plaid.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
19
19
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
20
20
|
if spec.respond_to?(:metadata)
|
21
|
-
spec.metadata['allowed_push_host'] =
|
21
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
22
22
|
else
|
23
23
|
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
24
24
|
'public gem pushes.'
|
@@ -32,10 +32,16 @@ Gem::Specification.new do |spec|
|
|
32
32
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
33
33
|
spec.require_paths = ['lib']
|
34
34
|
|
35
|
-
spec.required_ruby_version = '>= 2.
|
35
|
+
spec.required_ruby_version = '>= 2.1.0'
|
36
|
+
|
37
|
+
spec.add_dependency 'faraday'
|
38
|
+
spec.add_dependency 'faraday_middleware'
|
36
39
|
|
37
40
|
spec.add_development_dependency 'bundler', '~> 1.7'
|
38
|
-
spec.add_development_dependency '
|
41
|
+
spec.add_development_dependency 'dotenv'
|
42
|
+
spec.add_development_dependency 'rake', '>= 10.0'
|
39
43
|
spec.add_development_dependency 'sdoc', '~> 0.4.1'
|
40
|
-
spec.add_development_dependency 'minitest', '~> 5.
|
44
|
+
spec.add_development_dependency 'minitest', '~> 5.10'
|
45
|
+
spec.add_development_dependency 'minitest-around', '~> 0.4.0'
|
46
|
+
spec.add_development_dependency 'vcr', '~> 3.0.3'
|
41
47
|
end
|
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: plaid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Edmund Loo
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday_middleware
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
13
41
|
- !ruby/object:Gem::Dependency
|
14
42
|
name: bundler
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -24,18 +52,32 @@ dependencies:
|
|
24
52
|
- - "~>"
|
25
53
|
- !ruby/object:Gem::Version
|
26
54
|
version: '1.7'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: dotenv
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
27
69
|
- !ruby/object:Gem::Dependency
|
28
70
|
name: rake
|
29
71
|
requirement: !ruby/object:Gem::Requirement
|
30
72
|
requirements:
|
31
|
-
- - "
|
73
|
+
- - ">="
|
32
74
|
- !ruby/object:Gem::Version
|
33
75
|
version: '10.0'
|
34
76
|
type: :development
|
35
77
|
prerelease: false
|
36
78
|
version_requirements: !ruby/object:Gem::Requirement
|
37
79
|
requirements:
|
38
|
-
- - "
|
80
|
+
- - ">="
|
39
81
|
- !ruby/object:Gem::Version
|
40
82
|
version: '10.0'
|
41
83
|
- !ruby/object:Gem::Dependency
|
@@ -58,14 +100,42 @@ dependencies:
|
|
58
100
|
requirements:
|
59
101
|
- - "~>"
|
60
102
|
- !ruby/object:Gem::Version
|
61
|
-
version: '5.
|
103
|
+
version: '5.10'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '5.10'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: minitest-around
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.4.0
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.4.0
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: vcr
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 3.0.3
|
62
132
|
type: :development
|
63
133
|
prerelease: false
|
64
134
|
version_requirements: !ruby/object:Gem::Requirement
|
65
135
|
requirements:
|
66
136
|
- - "~>"
|
67
137
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
138
|
+
version: 3.0.3
|
69
139
|
description: Ruby gem wrapper for the Plaid API. Read more at the homepage, the wiki,
|
70
140
|
or in the Plaid documentation.
|
71
141
|
email:
|
@@ -74,18 +144,22 @@ executables: []
|
|
74
144
|
extensions: []
|
75
145
|
extra_rdoc_files: []
|
76
146
|
files:
|
147
|
+
- ".env.sample"
|
148
|
+
- CHANGELOG.md
|
77
149
|
- CONTRIBUTING.md
|
78
150
|
- Gemfile
|
79
151
|
- LICENSE.txt
|
152
|
+
- PUBLISHING.md
|
80
153
|
- README.md
|
81
154
|
- Rakefile
|
155
|
+
- UPGRADING.md
|
82
156
|
- bin/console
|
83
157
|
- bin/setup
|
84
158
|
- circle.yml
|
85
159
|
- lib/plaid.rb
|
86
160
|
- lib/plaid/client.rb
|
87
|
-
- lib/plaid/connect.rb
|
88
161
|
- lib/plaid/errors.rb
|
162
|
+
- lib/plaid/middleware.rb
|
89
163
|
- lib/plaid/products/accounts.rb
|
90
164
|
- lib/plaid/products/auth.rb
|
91
165
|
- lib/plaid/products/categories.rb
|
@@ -112,7 +186,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
112
186
|
requirements:
|
113
187
|
- - ">="
|
114
188
|
- !ruby/object:Gem::Version
|
115
|
-
version: 2.
|
189
|
+
version: 2.1.0
|
116
190
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
191
|
requirements:
|
118
192
|
- - ">="
|
data/lib/plaid/connect.rb
DELETED
@@ -1,75 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'net/http'
|
3
|
-
require 'uri'
|
4
|
-
|
5
|
-
require_relative 'version'
|
6
|
-
|
7
|
-
module Plaid
|
8
|
-
# Internal: A module encapsulating HTTP post requests
|
9
|
-
module Connect
|
10
|
-
# Internal: Headers used for correct request and SDK tracking.
|
11
|
-
NETWORK_HEADERS = { 'User-Agent' => "Plaid Ruby v#{Plaid::VERSION}",
|
12
|
-
'Content-Type' => 'application/json' }.freeze
|
13
|
-
|
14
|
-
# Internal: Default read timeout for HTTP calls in seconds.
|
15
|
-
NETWORK_TIMEOUT = 600
|
16
|
-
|
17
|
-
# Internal: Run POST request on path with payload.
|
18
|
-
#
|
19
|
-
# path - The path to send the request to.
|
20
|
-
# payload - The hash with data.
|
21
|
-
#
|
22
|
-
# Returns the parsed JSON response body.
|
23
|
-
def self.post(path, payload)
|
24
|
-
uri = URI.parse(path)
|
25
|
-
|
26
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
27
|
-
http.use_ssl = true
|
28
|
-
|
29
|
-
http.read_timeout = Plaid::Connect::NETWORK_TIMEOUT
|
30
|
-
|
31
|
-
request = Net::HTTP::Post.new(uri.path, Plaid::Connect::NETWORK_HEADERS)
|
32
|
-
request.body = JSON.generate(payload)
|
33
|
-
|
34
|
-
Plaid::Connect.run http, request
|
35
|
-
end
|
36
|
-
|
37
|
-
# Internal: Run the request and process the response.
|
38
|
-
#
|
39
|
-
# http - Object created by Net::HTTP.new
|
40
|
-
# request - Object created by Net::HTTP::Post.new (for POST)
|
41
|
-
#
|
42
|
-
# Returns the parsed JSON body or raises an appropriate PlaidError
|
43
|
-
def self.run(http, request)
|
44
|
-
response = http.request(request)
|
45
|
-
|
46
|
-
if response.body.nil? || response.body.empty?
|
47
|
-
raise Plaid::PlaidError.new(0, 'Server error', 'Try to connect later')
|
48
|
-
end
|
49
|
-
|
50
|
-
# All responses are expected to have a JSON body, so we always parse,
|
51
|
-
# not looking at the status code.
|
52
|
-
body = JSON.parse(response.body)
|
53
|
-
|
54
|
-
case response
|
55
|
-
when Net::HTTPSuccess
|
56
|
-
body
|
57
|
-
else
|
58
|
-
raise_error(body)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
# Internal: Raise an error with the class depending on reponse body.
|
63
|
-
#
|
64
|
-
# body - A parsed response body with error.
|
65
|
-
#
|
66
|
-
# Raises a PlaidError
|
67
|
-
def self.raise_error(body)
|
68
|
-
raise Plaid::Error.error_from_type(body['error_type']).new(body['error_type'],
|
69
|
-
body['error_code'],
|
70
|
-
body['error_message'],
|
71
|
-
body['display_message'],
|
72
|
-
body['request_id'])
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|