plaid 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a1d12271b5f68498843347df5493efca85a54331
4
- data.tar.gz: 77bd4a0ef5b50a6ac420a2067484a425d71b5f5b
3
+ metadata.gz: 275751fae8bd5e8b06ab3b12d577fb9287663fbd
4
+ data.tar.gz: 5b079f65196433ea7edfe0d27e5bcc917d4bc4f0
5
5
  SHA512:
6
- metadata.gz: 53b474fb7b12fbc2acb335aab4f072dd5d4ad96dcbc07b2a77fae42a73630b9ed7881336c7cab7e24a7b85543b666f07738eb8237df3eac8847a803244c71227
7
- data.tar.gz: d9935d472dd1cc6841a94acee6049c637777c5d9c19384b6c43443f867906ffa1631465a5707676628794c84189f4ab90df9adcb6364e208bf861601c711e033
6
+ metadata.gz: a2da99035165898c5634a704a12ee0a47f021df841e33a1172c7503b219a66451b60f6fb1bbf39f6c833ea450eeb00c13d0302dca56a8a3526b60a64126a6e6c
7
+ data.tar.gz: 53d4916be3b84f6833add1df715fad9de680391d13c4ff46969a1680d276507e46232a513f935d195a9e6515f2fa172a24e9b943c851846e02612caa7cb217ed
@@ -1,3 +1,13 @@
1
+ # 2.1.0. 19-Oct-2016
2
+
3
+ * Documentation fixes (@ishmael).
4
+ * Fix `Transaction#to_s` behavior (@michel-tricot).
5
+ * PATCH `/:product/step` flow.
6
+ * Use the same client in `User#upgrade` (@betesh).
7
+ * Webhook object (@zshannon).
8
+ * `processor_token` access in `User.exchange_token` (@gylaz).
9
+ * Raise `ServerError` in case server returned an empty response body.
10
+
1
11
  # 2.0.0. 24-May-2016
2
12
 
3
13
  * Use `~> 1.0` spec for multi_json dependency.
data/README.md CHANGED
@@ -34,7 +34,7 @@ Configure the gem with your client id, secret, and the environment you would lik
34
34
  Plaid.config do |p|
35
35
  p.client_id = '<<< Plaid provided client ID >>>'
36
36
  p.secret = '<<< Plaid provided secret key >>>'
37
- p.env = :tartan # or :api for production
37
+ p.env = :tartan # or :production
38
38
  end
39
39
  ```
40
40
 
@@ -86,7 +86,7 @@ user = Plaid::User.exchange_token('public_token') # bound to :connect product
86
86
  With more options:
87
87
 
88
88
  ```ruby
89
- user2 = Plaid::User.exchange_token('public_token', account_id: '...', product: :auth)
89
+ user2 = Plaid::User.exchange_token('public_token', 'account_id', product: :auth)
90
90
  ```
91
91
 
92
92
  If you want to [move money via Stripe's ACH
@@ -210,6 +210,55 @@ ltis = Plaid::LongTailInstitution.all(count: 20, offset: 20) # A page
210
210
  res = Plaid::LongTailInstitution.search(query: 'c') # Lookup by name
211
211
  ```
212
212
 
213
+ ### Webhooks
214
+
215
+ You can register to receive [Webhooks](https://plaid.com/docs/api/#webhook) from Plaid when your users have new events. If you do, you'll receive `POST` requests with JSON.
216
+
217
+ E.g. Initial Transaction Webhook:
218
+ ```json
219
+ {
220
+ "message": "Initial transaction pull finished",
221
+ "access_token": "xxxxx",
222
+ "total_transactions": 123,
223
+ "code": 0
224
+ }
225
+ ```
226
+
227
+ You should parse that JSON into a Ruby Hash with String keys (eg. `webhook_hash = JSON.parse(json_string)`). Then, you can convert that Hash into a Ruby object using `Plaid::Webhook`:
228
+
229
+ ```ruby
230
+ webhook = Plaid::Webhook.new(webhook_hash)
231
+
232
+ # Was that the Initial Transaction Webhook?
233
+ webhook.initial_transaction?
234
+ access_token = webhook.access_token
235
+ total_transactions = webhook.total_transactions
236
+
237
+ # Or did Historical Transactions become available?
238
+ webhook.historical_transaction?
239
+ access_token = webhook.access_token
240
+ total_transactions = webhook.total_transactions
241
+
242
+ # Or did Normal Transactions become available?
243
+ webhook.normal_transaction?
244
+ access_token = webhook.access_token
245
+ total_transactions = webhook.total_transactions
246
+
247
+ # Or maybe a transaction was removed?
248
+ webhook.removed_transaction?
249
+ access_token = webhook.access_token
250
+ removed_transactions_ids = webhook.removed_transactions_ids
251
+
252
+ # Or was the User's Webhook Updated?
253
+ webhook.user_webhook_updated?
254
+ access_token = webhook.access_token
255
+
256
+ # Otherwise, was it an error?
257
+ webhook.error_response?
258
+ # Which error?
259
+ error = webhook.error
260
+ ```
261
+
213
262
  ### Custom clients
214
263
 
215
264
  It's possible to use several Plaid environments and/or credentials in one app by
@@ -224,7 +273,7 @@ Plaid.config do |p|
224
273
  end
225
274
 
226
275
  # Creating a custom client
227
- api = Plaid::Client.new(client_id: 'client_id_2', 'secret_2', env: :api)
276
+ api = Plaid::Client.new(client_id: 'client_id_2', secret: 'secret_2', env: :production)
228
277
 
229
278
  # Tartan user (using default client)
230
279
  user1 = Plaid::User.create(:connect, 'wells', 'plaid_test', 'plaid_good')
@@ -8,6 +8,7 @@ require 'plaid/transaction'
8
8
  require 'plaid/info'
9
9
  require 'plaid/income'
10
10
  require 'plaid/client'
11
+ require 'plaid/webhook'
11
12
 
12
13
  require 'uri'
13
14
 
@@ -95,6 +95,10 @@ module Plaid
95
95
  @request = request
96
96
  @response = http.request(@request)
97
97
 
98
+ if @response.body.nil? || @response.body.empty?
99
+ raise Plaid::ServerError.new(0, 'Server error', 'Try to connect later')
100
+ end
101
+
98
102
  # All responses are expected to have a JSON body, so we always parse,
99
103
  # not looking at the status code.
100
104
  @body = MultiJson.load(@response.body)
@@ -110,7 +110,7 @@ module Plaid
110
110
  #
111
111
  # Returns a String.
112
112
  def inspect
113
- "#<Plaid::Transaction id=#{id.inspect}, account_id=#{id.inspect}, " \
113
+ "#<Plaid::Transaction id=#{id.inspect}, account_id=#{account_id.inspect}, " \
114
114
  "date=#{date}, amount=#{amount.inspect}, name=#{name.inspect}, " \
115
115
  "pending=#{pending.inspect}>"
116
116
  end
@@ -7,6 +7,9 @@ module Plaid
7
7
  # Public: The access token for authenticated user.
8
8
  attr_reader :access_token
9
9
 
10
+ # Public: The processor token for a given account and authenticated user.
11
+ attr_reader :processor_token
12
+
10
13
  # Public: The current product. Provides a context for #update and #delete
11
14
  # calls. See Plaid::PRODUCTS.
12
15
  attr_reader :product
@@ -146,7 +149,7 @@ module Plaid
146
149
  # access_token - The String access token obtained from Plaid.
147
150
  # response - The Hash response body to parse.
148
151
  # mfa - The Boolean flag indicating that response body
149
- # - contains an MFA response.
152
+ # contains an MFA response.
150
153
  # stripe_token - The String stripe bank account token.
151
154
  # client - The Plaid::Client instance used to connect to the API
152
155
  # (default is to use global Plaid client - Plaid.client).
@@ -207,7 +210,13 @@ module Plaid
207
210
  payload[:options] = MultiJson.dump(options)
208
211
  end
209
212
  conn = Connector.new(product, :step, auth: true)
210
- response = conn.post(payload)
213
+
214
+ # Use PATCH if we are in context of User#update.
215
+ response = if @mfa_patch
216
+ conn.patch(payload)
217
+ else
218
+ conn.post(payload)
219
+ end
211
220
 
212
221
  @mfa_required = conn.mfa?
213
222
  parse_response(response)
@@ -261,8 +270,17 @@ module Plaid
261
270
 
262
271
  payload[:pin] = pin if pin
263
272
 
264
- parse_response(Connector.new(product, auth: true, client: client)
265
- .patch(payload))
273
+ conn = Connector.new(product, auth: true, client: client)
274
+ resp = conn.patch(payload)
275
+
276
+ if conn.mfa?
277
+ @mfa_required = true
278
+ end
279
+
280
+ parse_response(resp)
281
+
282
+ # A note for User#mfa_step to send PATCH request too
283
+ @mfa_patch = true
266
284
 
267
285
  self
268
286
  end
@@ -321,7 +339,7 @@ module Plaid
321
339
  response = Connector.new(:upgrade, auth: true, client: client)
322
340
  .post(payload)
323
341
 
324
- User.new product, response: response
342
+ User.new product, response: response, client: client
325
343
  end
326
344
 
327
345
  # Public: Get the current user tied to another product.
@@ -443,6 +461,8 @@ module Plaid
443
461
  # Internal: Set up attributes from Add User response.
444
462
  def parse_response(response)
445
463
  @access_token = response['access_token']
464
+ @processor_token = response['processor_token']
465
+
446
466
  return parse_mfa_response(response) if mfa?
447
467
 
448
468
  @mfa_type = @mfa = nil
@@ -1,3 +1,3 @@
1
1
  module Plaid
2
- VERSION = '2.0.0'.freeze
2
+ VERSION = '2.1.0'.freeze
3
3
  end
@@ -0,0 +1,130 @@
1
+ module Plaid
2
+ # Public: Representation of a webhook.
3
+ class Webhook
4
+ # Public: The String human readable explanation of this webhook request.
5
+ # E.g. "Initial transaction pull finished".
6
+ attr_reader :message
7
+
8
+ # Public: The String access token for authenticated user.
9
+ attr_reader :access_token
10
+
11
+ # Public: The Integer number of transactions available in Plaid.
12
+ # E.g. 124
13
+ attr_reader :total_transactions
14
+
15
+ # Public: The Integer code denoting the type of webhook this is. E.g. 0
16
+ attr_reader :code
17
+
18
+ # Public: Initialize a Webhook instance.
19
+ #
20
+ # fields - The Hash with fields.
21
+ def initialize(fields)
22
+ @message = fields['message']
23
+ @access_token = fields['access_token']
24
+ @total_transactions = fields['total_transactions']
25
+ @code = fields['code']
26
+ # present only for Removed Transaction Webhook
27
+ @removed_transactions = fields['removed_transactions']
28
+ # present only for Error Response Webhook
29
+ @resolve = fields['resolve']
30
+ end
31
+
32
+ # Public: Share the type of Webhook this is from its code
33
+ #
34
+ # Returns String webhook type
35
+ def type
36
+ Webhook::CODEX[code] || 'ERROR_RESPONSE'
37
+ end
38
+
39
+ # Public: Detect if the webhook is Initial Transaction Webhook. Occurs
40
+ # once the initial transaction pull has finished.
41
+ #
42
+ # Returns true if it is.
43
+ def initial_transaction?
44
+ code == Webhook::INITIAL_TRANSACTION
45
+ end
46
+
47
+ # Public: Detect if the webhook is Historical Transaction Webhook. Occurs
48
+ # once the historical transaction pull has completed, shortly after the
49
+ # initial transaction pull.
50
+ #
51
+ # Returns true if it is.
52
+ def historical_transaction?
53
+ code == Webhook::HISTORICAL_TRANSACTION
54
+ end
55
+
56
+ # Public: Detect if the webhook is Normal Transaction Webhook. Occurs at
57
+ # set intervals throughout the day as data is updated from the financial
58
+ # institutions.
59
+ #
60
+ # Returns true if it is.
61
+ def normal_transaction?
62
+ code == Webhook::NORMAL_TRANSACTION
63
+ end
64
+
65
+ # Public: Detect if the webhook is Removed Transaction Webhook. Occurs when
66
+ # transactions have been removed from our system.
67
+ #
68
+ # Returns true if it is.
69
+ def removed_transaction?
70
+ code == Webhook::REMOVED_TRANSACTION
71
+ end
72
+
73
+ # Public: Detect if the webhook is User's Webhook Updated. Occurs when an
74
+ # user's webhook is updated via a PATCH request without credentials.
75
+ #
76
+ # Returns true if it is.
77
+ def user_webhook_updated?
78
+ code == Webhook::USER_WEBHOOK_UPDATED
79
+ end
80
+
81
+ # Public: Detect if the webhook is Error Response Webhook. Triggered when
82
+ # an error has occurred. Includes the relevant Plaid error code with
83
+ # details on both the error type and steps for error resolution.
84
+ #
85
+ # Returns true if it is.
86
+ def error_response?
87
+ Webhook::CODEX[code].nil?
88
+ end
89
+
90
+ # Public: Get transaction IDs that were removed.
91
+ #
92
+ # Returns Array[String] or nil
93
+ def removed_transactions_ids
94
+ @removed_transactions
95
+ end
96
+
97
+ # Public: Get a Plaid::Error instance if this is an Error Response Webhook
98
+ #
99
+ # Returns Plaid::Error or nil
100
+ def error
101
+ if error_response?
102
+ Plaid::PlaidError.new @code, @message, @resolve
103
+ end
104
+ end
105
+
106
+ # Public: Get a String representation of the transaction.
107
+ #
108
+ # Returns a String.
109
+ def inspect
110
+ "#<Plaid::Webhook type=#{type.inspect} code=#{code.inspect}, access_token=#{access_token.inspect}, " \
111
+ "total_transactions=#{total_transactions.inspect}, message=#{message.inspect}>"
112
+ end
113
+
114
+ # Public: Get a String representation of the transaction.
115
+ #
116
+ # Returns a String.
117
+ alias to_s inspect
118
+
119
+ private
120
+
121
+ Webhook::ERROR_RESPONSE = -1
122
+ codex = {}
123
+ ['initial transaction', 'historical transaction', 'normal transaction', 'removed transaction', 'user webhook updated'].each_with_index do |event, idx|
124
+ name = event.split.map(&:upcase).join('_')
125
+ codex[idx + 1] = name
126
+ const_set name, idx + 1
127
+ end
128
+ CODEX = codex.freeze
129
+ end
130
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plaid
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oleg Dashevskii
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-05-24 00:00:00.000000000 Z
11
+ date: 2016-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: multi_json
@@ -138,6 +138,7 @@ files:
138
138
  - lib/plaid/transaction.rb
139
139
  - lib/plaid/user.rb
140
140
  - lib/plaid/version.rb
141
+ - lib/plaid/webhook.rb
141
142
  - plaid.gemspec
142
143
  homepage: https://github.com/plaid/plaid-ruby
143
144
  licenses:
@@ -159,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
159
160
  version: '0'
160
161
  requirements: []
161
162
  rubyforge_project:
162
- rubygems_version: 2.5.1
163
+ rubygems_version: 2.4.5.1
163
164
  signing_key:
164
165
  specification_version: 4
165
166
  summary: Ruby bindings for Plaid