increase 0.1.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/OPENAPI_VERSION +1 -0
  3. data/README.md +156 -48
  4. data/bin/generate +152 -0
  5. data/bin/setup +8 -0
  6. data/generate/resource.rb.erb +18 -0
  7. data/lib/increase/client.rb +2 -0
  8. data/lib/increase/configuration.rb +1 -1
  9. data/lib/increase/file_upload.rb +50 -0
  10. data/lib/increase/resource.rb +85 -119
  11. data/lib/increase/resources/account_numbers.rb +7 -0
  12. data/lib/increase/resources/account_statements.rb +15 -0
  13. data/lib/increase/resources/account_transfers.rb +10 -2
  14. data/lib/increase/resources/accounts.rb +9 -1
  15. data/lib/increase/resources/ach_prenotifications.rb +17 -0
  16. data/lib/increase/resources/ach_transfers.rb +10 -2
  17. data/lib/increase/resources/card_disputes.rb +17 -0
  18. data/lib/increase/resources/card_profiles.rb +17 -0
  19. data/lib/increase/resources/cards.rb +9 -1
  20. data/lib/increase/resources/check_deposits.rb +17 -0
  21. data/lib/increase/resources/check_transfers.rb +12 -3
  22. data/lib/increase/resources/declined_transactions.rb +15 -0
  23. data/lib/increase/resources/digital_wallet_tokens.rb +15 -0
  24. data/lib/increase/resources/documents.rb +15 -0
  25. data/lib/increase/resources/entities.rb +19 -0
  26. data/lib/increase/resources/event_subscriptions.rb +19 -0
  27. data/lib/increase/resources/events.rb +5 -0
  28. data/lib/increase/resources/external_accounts.rb +19 -0
  29. data/lib/increase/resources/files.rb +17 -0
  30. data/lib/increase/resources/groups.rb +13 -0
  31. data/lib/increase/resources/inbound_ach_transfer_returns.rb +17 -0
  32. data/lib/increase/resources/inbound_wire_drawdown_requests.rb +15 -0
  33. data/lib/increase/resources/limits.rb +7 -0
  34. data/lib/increase/resources/oauth_connections.rb +15 -0
  35. data/lib/increase/resources/pending_transactions.rb +5 -0
  36. data/lib/increase/resources/real_time_decisions.rb +15 -0
  37. data/lib/increase/resources/routing_numbers.rb +4 -0
  38. data/lib/increase/resources/transactions.rb +5 -0
  39. data/lib/increase/resources/wire_drawdown_requests.rb +17 -0
  40. data/lib/increase/resources/wire_transfers.rb +21 -0
  41. data/lib/increase/response_array.rb +19 -0
  42. data/lib/increase/version.rb +1 -1
  43. data/lib/increase/webhook/signature.rb +9 -1
  44. data/lib/increase.rb +2 -1
  45. data/openapi.json +32098 -0
  46. metadata +74 -6
@@ -1,7 +1,10 @@
1
1
  require "increase/response_hash"
2
+ require "increase/response_array"
2
3
 
3
4
  module Increase
4
5
  class Resource
6
+ PAGINATION_MAX_LIMIT = 100
7
+
5
8
  def initialize(client: nil)
6
9
  if instance_of?(Resource)
7
10
  raise NotImplementedError, "Resource is an abstract class. You should perform actions on its subclasses (Accounts, Transactions, Card, etc.)"
@@ -18,51 +21,41 @@ module Increase
18
21
  end
19
22
 
20
23
  def self.resource_url
21
- "/#{resource_name.downcase.tr(" ", "_")}"
24
+ "/#{self::API_NAME}"
22
25
  end
23
26
 
24
- def self.resource_name
25
- if self == Resource
26
- raise NotImplementedError, "Resource is an abstract class. You should perform actions on its subclasses (Accounts, Transactions, Card, etc.)"
27
- end
28
-
29
- name.split("::").last.gsub(/[A-Z]/, ' \0').strip
30
- end
31
-
32
- def self.endpoint(name, http_method, to: :same_as_name, with: nil)
33
- to = nil if to == :root
34
- to = name.to_s if to == :same_as_name
35
- to = [to].flatten.compact
27
+ def self.endpoint(name, http_method, path: nil, with: nil)
28
+ path = [path].flatten.compact
36
29
  with = [with].flatten.compact
37
30
 
38
- raise Error, "Invalid `to`. Max of 2 elements allowed" if to.size > 2
39
- raise Error, "Only one `to` allowed when not `with` an `id`" if to.size > 1 && !with.include?(:id)
31
+ # TODO: This doesn't support multiple path params
32
+ is_id = ->(path_segment) { path_segment.is_a?(Symbol) && path_segment.to_s.end_with?('id') }
33
+ has_id = path.any? is_id
40
34
 
41
35
  request_method = :request
42
36
  request_method = :paginated_request if with.include?(:pagination)
43
37
 
44
38
  method =
45
- if with.include?(:id)
39
+ if has_id
46
40
  # Method signature with a required `id` param
47
41
  ->(id, params = nil, headers = nil, &block) do
48
- url = self.class.resource_url
49
- url +=
50
- if to.size == 2
51
- "/#{to[0]}/#{id}/#{to[1]}"
52
- elsif to.size == 1
53
- # Default to id first
54
- "/#{id}/#{to[0]}"
55
- else
56
- "/#{id}"
57
- end
42
+ segments = path.map { |segment| is_id.call(segment) ? id : segment }
43
+ url = ([self.class.resource_url] + segments).join("/")
44
+
45
+ if with.include?(:file_upload)
46
+ headers = {"Content-Type" => "multipart/form-data"}.merge(headers || {})
47
+ end
58
48
 
59
49
  send(request_method, http_method, url, params, headers, &block)
60
50
  end
61
51
  else
62
52
  # Method signature without a required `id` param
63
53
  ->(params = nil, headers = nil, &block) do
64
- url = self.class.resource_url
65
- url += "/#{to[0]}" if to.size == 1
54
+ url = ([self.class.resource_url] + path).join("/")
55
+
56
+ if with.include?(:file_upload)
57
+ headers = {"Content-Type" => "multipart/form-data"}.merge(headers || {})
58
+ end
66
59
 
67
60
  send(request_method, http_method, url, params, headers, &block)
68
61
  end
@@ -87,98 +80,28 @@ module Increase
87
80
  # endpoint which is a `GET` request to the resource's root URL.
88
81
 
89
82
  def create
90
- endpoint :create, :post, to: :root
83
+ endpoint :create, :post
91
84
  end
92
85
 
93
86
  def list
94
- endpoint :list, :get, to: :root, with: :pagination
87
+ endpoint :list, :get, with: :pagination
95
88
  end
96
89
 
97
90
  def update
98
- endpoint :update, :patch, to: :root, with: :id
91
+ endpoint :update, :patch, path: [:id]
99
92
  end
100
93
 
101
94
  def retrieve
102
- endpoint :retrieve, :get, to: :root, with: :id
95
+ endpoint :retrieve, :get, path: [:id]
103
96
  end
104
97
  end
105
98
 
106
- # def self.endpoint_action(method, http_method)
107
- # define_singleton_method(method) do |*args, &block|
108
- # new.send(:action, method, http_method, *args, &block)
109
- # end
110
- #
111
- # define_method(method) do |*args, &block|
112
- # new.send(:action, method, http_method, *args, &block)
113
- # end
114
- # end
115
- #
116
- # private_class_method :endpoint_action
117
- #
118
- # private
119
- #
120
- # def create(params = nil, headers = nil)
121
- # request(:post, self.class.resource_url, params, headers)
122
- # end
123
- #
124
- # def list(params = nil, headers = nil, &block)
125
- # results = []
126
- # count = 0
127
- # limit = params&.[](:limit) || params&.[]("limit")
128
- # if limit == :all || limit&.>(100)
129
- # params&.delete(:limit)
130
- # params&.delete("limit")
131
- # end
132
- #
133
- # loop do
134
- # res = request(:get, self.class.resource_url, params, headers)
135
- # data = res["data"]
136
- # count += data.size
137
- # if ![nil, :all].include?(limit) && count >= limit
138
- # data = data[0..(limit - (count - data.size) - 1)]
139
- # end
140
- #
141
- # if block
142
- # block.call(data)
143
- # else
144
- # results += data
145
- # end
146
- #
147
- # if limit.nil? || (limit != :all && count >= limit) || res["next_cursor"].nil?
148
- # if block
149
- # break
150
- # else
151
- # return results
152
- # end
153
- # end
154
- #
155
- # params = (params || {}).merge({ cursor: res["next_cursor"] })
156
- # end
157
- # end
158
- #
159
- # def update(id, params = nil, headers = nil)
160
- # raise Error, "id must be a string" unless id.is_a?(String)
161
- # path = "#{self.class.resource_url}/#{id}"
162
- # request(:patch, path, params, headers)
163
- # end
164
- #
165
- # def retrieve(id, params = nil, headers = nil)
166
- # raise Error, "id must be a string" unless id.is_a?(String)
167
- # path = "#{self.class.resource_url}/#{id}"
168
- # request(:get, path, params, headers)
169
- # end
170
- #
171
- # # Such as for "/accounts/{account_id}/close"
172
- # # "close" is the action.
173
- # def action(action, http_method, id, params = nil, headers = nil)
174
- # raise Error, "id must be a string" unless id.is_a?(String)
175
- # path = "#{self.class.resource_url}/#{id}/#{action}"
176
- # request(http_method, path, params, headers)
177
- # end
178
-
179
99
  private
180
100
 
181
101
  def request(method, path, params = nil, headers = nil, &block)
102
+ params ||= {}
103
+ headers ||= {}
104
+
182
105
  if block
183
106
  # Assume the caller wants to automatically paginate
184
107
  return paginated_request(method, path, params, headers, &block)
@@ -188,51 +111,94 @@ module Increase
188
111
  headers = {"Content-Type" => "application/json"}.merge!(headers || {})
189
112
  end
190
113
 
114
+ # Hack to check for correct file upload params
115
+ if headers["Content-Type"] == "multipart/form-data"
116
+ attr = :file # TODO: Make this configurable
117
+ if params[attr]
118
+ unless params[attr].is_a?(FileUpload)
119
+ params[attr] = FileUpload.new(params[attr])
120
+ end
121
+
122
+ params[attr] = params[attr].file_part
123
+ end
124
+ end
125
+
191
126
  response = @client.connection.send(method, path, params, headers)
192
127
  ResponseHash.new(response.body, response: response)
193
128
  end
194
129
 
195
130
  def paginated_request(method, path, params = nil, headers = nil, &block)
131
+ params ||= {}
132
+ limit = params[:limit] || params["limit"]
133
+ if limit == :all || limit&.>(PAGINATION_MAX_LIMIT)
134
+ # Request `limit` can not be greater than `PAGINATION_MAX_LIMIT`
135
+ params.delete("limit")
136
+ params[:limit] = PAGINATION_MAX_LIMIT
137
+ end
138
+
196
139
  results = []
197
140
  count = 0
198
- limit = params&.[](:limit) || params&.[]("limit")
199
- if limit == :all || limit&.>(100)
200
- params&.delete(:limit)
201
- params&.delete("limit")
202
- end
203
141
 
204
142
  loop do
205
143
  res = request(method, path, params, headers)
206
144
  data = res["data"]
207
145
 
208
- # Handle case where endpoint doesn't actually support pagination.
209
- # For example, someone passes a block to `Account.create`
146
+ # Handle case where endpoint doesn't support pagination.
147
+ # For example, someone passes a block to `Accounts.create`
210
148
  if data.nil?
211
- # In this case, we'll both yield and return the response
212
- yield res if block
149
+ # In this case, we'll both yield and return the response.
150
+ # `res` here is already a `ResponseHash` since it comes from `request`
151
+ if block
152
+ yield res and return
153
+ end
213
154
  return res
214
155
  end
215
156
 
157
+ # From here on, the endpoint definitely supports pagination
158
+
216
159
  count += data.size
160
+ # Restrict number of results to the limit
217
161
  if ![nil, :all].include?(limit) && count >= limit
218
162
  data = data[0..(limit - (count - data.size) - 1)]
219
163
  end
220
164
 
165
+ # Either yield or collect the results
221
166
  if block
222
- block.call(data)
167
+ block.call(ResponseArray.new(data, full_response: res, response: res.response))
223
168
  else
224
169
  results += data
225
170
  end
226
171
 
227
- if limit.nil? || (limit != :all && count >= limit) || res["next_cursor"].nil?
172
+ # Handle case where user doesn't want to paginate
173
+ if limit.nil?
228
174
  if block
229
- break
175
+ # Block has already been called above
176
+ return
230
177
  else
231
- return results
178
+ return ResponseArray.new(results, full_response: res, response: res.response)
232
179
  end
233
180
  end
234
181
 
235
- params = (params || {}).merge({cursor: res["next_cursor"]})
182
+ # From here on, this is for sure a paginated request
183
+
184
+ # Handle case where we've hit the last page
185
+ if (limit != :all && count >= limit) || res["next_cursor"].nil?
186
+ if block
187
+ # We've already yielded all the data above
188
+ return
189
+ else
190
+ # Wrap with a `ResponseArray`. However, there are multiple
191
+ # requests/responses associated with this array. The `full_response`
192
+ # and `response` only store the last response.
193
+ return ResponseArray.new(results, full_response: res, response: res.response)
194
+ end
195
+ end
196
+
197
+ # Update the cursor and loop again!
198
+ params[:cursor] = res["next_cursor"]
199
+ if limit != :all
200
+ params[:limit] = [limit - count, PAGINATION_MAX_LIMIT].min
201
+ end
236
202
  end
237
203
  end
238
204
  end
@@ -4,9 +4,16 @@ require "increase/resource"
4
4
 
5
5
  module Increase
6
6
  class AccountNumbers < Resource
7
+ NAME = "Account Numbers"
8
+ API_NAME = "account_numbers"
9
+
10
+ # Create an Account Number
7
11
  create
12
+ # List Account Numbers
8
13
  list
14
+ # Update an Account Number
9
15
  update
16
+ # Retrieve an Account Number
10
17
  retrieve
11
18
  end
12
19
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class AccountStatements < Resource
7
+ NAME = "Account Statements"
8
+ API_NAME = "account_statements"
9
+
10
+ # List Account Statements
11
+ list
12
+ # Retrieve an Account Statement
13
+ retrieve
14
+ end
15
+ end
@@ -4,10 +4,18 @@ require "increase/resource"
4
4
 
5
5
  module Increase
6
6
  class AccountTransfers < Resource
7
+ NAME = "Account Transfers"
8
+ API_NAME = "account_transfers"
9
+
10
+ # Create an Account Transfer
7
11
  create
12
+ # List Account Transfers
8
13
  list
14
+ # Retrieve an Account Transfer
9
15
  retrieve
10
- endpoint :approve, :post, with: :id
11
- endpoint :cancel, :post, with: :id
16
+ # Approve an Account Transfer
17
+ endpoint :approve, :post, path: [:account_transfer_id, "approve"]
18
+ # Cancel an Account Transfer
19
+ endpoint :cancel, :post, path: [:account_transfer_id, "cancel"]
12
20
  end
13
21
  end
@@ -4,10 +4,18 @@ require "increase/resource"
4
4
 
5
5
  module Increase
6
6
  class Accounts < Resource
7
+ NAME = "Accounts"
8
+ API_NAME = "accounts"
9
+
10
+ # Create an Account
7
11
  create
12
+ # List Accounts
8
13
  list
14
+ # Update an Account
9
15
  update
16
+ # Retrieve an Account
10
17
  retrieve
11
- endpoint :close, :post, with: :id
18
+ # Close an Account
19
+ endpoint :close, :post, path: [:account_id, "close"]
12
20
  end
13
21
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class AchPrenotifications < Resource
7
+ NAME = "ACH Prenotifications"
8
+ API_NAME = "ach_prenotifications"
9
+
10
+ # Create an ACH Prenotification
11
+ create
12
+ # List ACH Prenotifications
13
+ list
14
+ # Retrieve an ACH Prenotification
15
+ retrieve
16
+ end
17
+ end
@@ -4,10 +4,18 @@ require "increase/resource"
4
4
 
5
5
  module Increase
6
6
  class AchTransfers < Resource
7
+ NAME = "ACH Transfers"
8
+ API_NAME = "ach_transfers"
9
+
10
+ # Create an ACH Transfer
7
11
  create
12
+ # List ACH Transfers
8
13
  list
14
+ # Retrieve an ACH Transfer
9
15
  retrieve
10
- endpoint :approve, :post, with: :id
11
- endpoint :cancel, :post, with: :id
16
+ # Approve an ACH Transfer
17
+ endpoint :approve, :post, path: [:ach_transfer_id, "approve"]
18
+ # Cancel a pending ACH Transfer
19
+ endpoint :cancel, :post, path: [:ach_transfer_id, "cancel"]
12
20
  end
13
21
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class CardDisputes < Resource
7
+ NAME = "Card Disputes"
8
+ API_NAME = "card_disputes"
9
+
10
+ # Create a Card Dispute
11
+ create
12
+ # List Card Disputes
13
+ list
14
+ # Retrieve a Card Dispute
15
+ retrieve
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class CardProfiles < Resource
7
+ NAME = "Card Profiles"
8
+ API_NAME = "card_profiles"
9
+
10
+ # Create a Card Profile
11
+ create
12
+ # List Card Profiles
13
+ list
14
+ # Retrieve a Card Profile
15
+ retrieve
16
+ end
17
+ end
@@ -4,10 +4,18 @@ require "increase/resource"
4
4
 
5
5
  module Increase
6
6
  class Cards < Resource
7
+ NAME = "Cards"
8
+ API_NAME = "cards"
9
+
10
+ # Create a Card
7
11
  create
12
+ # List Cards
8
13
  list
9
- endpoint :details, :get, with: :id
14
+ # Retrieve sensitive details for a Card
15
+ endpoint :details, :get, path: [:card_id, "details"]
16
+ # Update a Card
10
17
  update
18
+ # Retrieve a Card
11
19
  retrieve
12
20
  end
13
21
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class CheckDeposits < Resource
7
+ NAME = "Check Deposits"
8
+ API_NAME = "check_deposits"
9
+
10
+ # Create a Check Deposit
11
+ create
12
+ # List Check Deposits
13
+ list
14
+ # Retrieve a Check Deposit
15
+ retrieve
16
+ end
17
+ end
@@ -4,11 +4,20 @@ require "increase/resource"
4
4
 
5
5
  module Increase
6
6
  class CheckTransfers < Resource
7
+ NAME = "Check Transfers"
8
+ API_NAME = "check_transfers"
9
+
10
+ # Create a Check Transfer
7
11
  create
12
+ # List Check Transfers
8
13
  list
14
+ # Retrieve a Check Transfer
9
15
  retrieve
10
- endpoint :approve, :post, with: :id
11
- endpoint :cancel, :post, with: :id
12
- endpoint :stop_payment, :post, with: :id
16
+ # Approve a Check Transfer
17
+ endpoint :approve, :post, path: [:check_transfer_id, "approve"]
18
+ # Cancel a pending Check Transfer
19
+ endpoint :cancel, :post, path: [:check_transfer_id, "cancel"]
20
+ # Request a stop payment on a Check Transfer
21
+ endpoint :stop_payment, :post, path: [:check_transfer_id, "stop_payment"]
13
22
  end
14
23
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class DeclinedTransactions < Resource
7
+ NAME = "Declined Transactions"
8
+ API_NAME = "declined_transactions"
9
+
10
+ # List Declined Transactions
11
+ list
12
+ # Retrieve a Declined Transaction
13
+ retrieve
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class DigitalWalletTokens < Resource
7
+ NAME = "Digital Wallet Tokens"
8
+ API_NAME = "digital_wallet_tokens"
9
+
10
+ # List Digital Wallet Tokens
11
+ list
12
+ # Retrieve a Digital Wallet Token
13
+ retrieve
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class Documents < Resource
7
+ NAME = "Documents"
8
+ API_NAME = "documents"
9
+
10
+ # List Documents
11
+ list
12
+ # Retrieve a Document
13
+ retrieve
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class Entities < Resource
7
+ NAME = "Entities"
8
+ API_NAME = "entities"
9
+
10
+ # Create an Entity
11
+ create
12
+ # List Entities
13
+ list
14
+ # Retrieve an Entity
15
+ retrieve
16
+ # Create a supplemental document for an Entity
17
+ endpoint :supplemental_documents, :post, path: [:entity_id, "supplemental_documents"]
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class EventSubscriptions < Resource
7
+ NAME = "Event Subscriptions"
8
+ API_NAME = "event_subscriptions"
9
+
10
+ # Create an Event Subscription
11
+ create
12
+ # List Event Subscriptions
13
+ list
14
+ # Update an Event Subscription
15
+ update
16
+ # Retrieve an Event Subscription
17
+ retrieve
18
+ end
19
+ end
@@ -4,7 +4,12 @@ require "increase/resource"
4
4
 
5
5
  module Increase
6
6
  class Events < Resource
7
+ NAME = "Events"
8
+ API_NAME = "events"
9
+
10
+ # List Events
7
11
  list
12
+ # Retrieve an Event
8
13
  retrieve
9
14
  end
10
15
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class ExternalAccounts < Resource
7
+ NAME = "External Accounts"
8
+ API_NAME = "external_accounts"
9
+
10
+ # Create an External Account
11
+ create
12
+ # List External Accounts
13
+ list
14
+ # Update an External Account
15
+ update
16
+ # Retrieve an External Account
17
+ retrieve
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class Files < Resource
7
+ NAME = "Files"
8
+ API_NAME = "files"
9
+
10
+ # Create a File
11
+ endpoint :create, :post, with: :file_upload
12
+ # List Files
13
+ list
14
+ # Retrieve a File
15
+ retrieve
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class Groups < Resource
7
+ NAME = "Groups"
8
+ API_NAME = "groups"
9
+
10
+ # Retrieve Group details
11
+ endpoint :current, :get, path: "current"
12
+ end
13
+ end