figo 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 390163889160a8aefcb91f1f8b4f99e18c84efb9
4
- data.tar.gz: 2a24495ecbb097b1659dbb29f8ad697b082d24a2
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZDMwM2ExN2I1ZDEzOGFlNGM3ZGRlY2I2ODljMTEyZTE2ZGE2MDg2OQ==
5
+ data.tar.gz: !binary |-
6
+ ODQzNGViYjA3ZTM3NzI2ZmMxMmNiN2IxNWQ2Zjg2YmZkZmIwMDRmYw==
5
7
  SHA512:
6
- metadata.gz: e0c1cc2c14a9b6db75c5724b949ec2d0b7d496103247bd4bdcd72993e549d6371465dcd1222105ca939d7837c99ee44d2f6937efe56b606cffb40982641eb52f
7
- data.tar.gz: b5401f6d092be459e5165bb86564d4180e7529cfd750261604865e17d5fcac0e0b44c3ecc311b435b194fcb4dc0d3ffd936be1840ba9dda2c5e012a48de97f2a
8
+ metadata.gz: !binary |-
9
+ NjhiZDlhYzY5NWY0ZjQ3YzEzY2YyYTQ1MjNkYjJlOTU2NDk2Y2YxNWQ5MjA3
10
+ YTJjODk1NTYzNDNmOGNmZWZiZTBmYmZkMmVlZDQ1MjY3MjY3NDAxNDE4MTc2
11
+ Y2I0MDdiZDhiNmE1YmI3MTQ0MTYyYzRhNGY2ODRmNjY0ZDczYTc=
12
+ data.tar.gz: !binary |-
13
+ NjEzZDg0MDdjNzg0MjVkYzNkZGQ0ZTliMzE4ZDlkMzAyMTgzZjU3OTI1MDU5
14
+ M2Y3NjVhMGUxZTg3OGE2Nzc4NjZiODc5Y2MxNDE1OTllZmQ1YTE5MmY0M2E1
15
+ Mjk4YWI2MWJmYmVkMTZhNTdkNzI3NzYyMzBlZGNkMTk0YzM1MTg=
data/.travis.yml CHANGED
@@ -4,11 +4,3 @@ rvm:
4
4
  - 2.0.0
5
5
  - 2.1.1
6
6
  - ruby-head
7
- - rbx-2.1.1
8
- - rbx
9
- - jruby-19mode # JRuby in 1.9 mode
10
- - jruby-head
11
- matrix:
12
- allow_failures:
13
- - rvm: jruby-19mode
14
- - rvm: jruby-head
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
- ruby-figo [![Build Status](https://secure.travis-ci.org/figo-connect/ruby-figo.png)](https://travis-ci.org/figo-connect/ruby-figo)
1
+ ruby-figo [![Build Status](https://secure.travis-ci.org/figo-connect/ruby-figo.png)](https://travis-ci.org/figo-connect/ruby-figo) [![Gem Version](http://img.shields.io/gem/v/figo.svg)](http://rubygems.org/gems/figo)
2
2
  =========
3
3
 
4
- Ruby bindings for the figo Connect API: http://developer.figo.me
4
+ Ruby bindings for the figo Connect API: http://docs.figo.io
5
5
 
6
6
  Usage
7
7
  =====
@@ -57,7 +57,7 @@ def process_redirect(authorization_code, state)
57
57
 
58
58
  # Start session.
59
59
  session = Figo::Session.new(token_hash["access_token"])
60
-
60
+
61
61
  # Print out list of account numbers.
62
62
  session.accounts.each do |account|
63
63
  puts account.account_number
@@ -67,7 +67,11 @@ end
67
67
 
68
68
  You can find more documentation at http://rubydoc.info/github/figo-connect/ruby-figo/master/frames
69
69
 
70
+ Demos
71
+ -----
72
+ In this repository you can also have a look at a simple console(`console_demo.rb`) and web demo(`web_demo`). While the console demo simply accesses the figo API, the web demo implements the full OAuth flow.
73
+
70
74
  Requirements
71
- ============
75
+ ------------
72
76
 
73
77
  This gem requires Ruby 1.9.
data/console_demo.rb ADDED
@@ -0,0 +1,14 @@
1
+ require_relative "lib/figo"
2
+
3
+ session = Figo::Session.new("ASHWLIkouP2O6_bgA2wWReRhletgWKHYjLqDaqb0LFfamim9RjexTo22ujRIP_cjLiRiSyQXyt2kM1eXU2XLFZQ0Hro15HikJQT_eNeT_9XQ")
4
+
5
+ # Print out list of account numbers and balances.
6
+ session.accounts.each do |account|
7
+ puts account.account_number
8
+ puts account.balance.balance
9
+ end
10
+
11
+ # Print out the list of all transaction originators/recipients of a specific account.
12
+ session.get_account("A1.1").transactions.each do |transaction|
13
+ puts transaction.name
14
+ end
data/figo.gemspec CHANGED
@@ -1,12 +1,12 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "figo"
3
- s.version = "1.1.1"
4
- s.authors = ["Stefan Richter", "Michael Haller"]
5
- s.email = ["stefan.richter@figo.me", "michael.haller@figo.me"]
3
+ s.version = "1.2.0"
4
+ s.authors = ["Stefan Richter"]
5
+ s.email = ["stefan.richter@figo.me"]
6
6
  s.homepage = "https://github.com/figo-connect/ruby-figo"
7
7
  s.license = "MIT"
8
8
  s.summary = %q{API wrapper for figo Connect.}
9
- s.description = %q{Library to easily use the API of http://www.figo.me}
9
+ s.description = %q{Library to easily use the API of http://figo.io}
10
10
 
11
11
  s.files = `git ls-files`.split("\n")
12
12
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
data/lib/figo.rb CHANGED
@@ -1,16 +1,16 @@
1
1
  #
2
2
  # Copyright (c) 2013 figo GmbH
3
- #
3
+ #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
6
6
  # in the Software without restriction, including without limitation the rights
7
7
  # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
8
  # copies of the Software, and to permit persons to whom the Software is
9
9
  # furnished to do so, subject to the following conditions:
10
- #
10
+ #
11
11
  # The above copyright notice and this permission notice shall be included in
12
12
  # all copies or substantial portions of the Software.
13
- #
13
+ #
14
14
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
15
  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
16
  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -18,7 +18,7 @@
18
18
  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
19
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
20
  # THE SOFTWARE.
21
- #
21
+ #
22
22
 
23
23
  require "json"
24
24
  require "net/http/persistent"
@@ -28,14 +28,13 @@ require_relative "models.rb"
28
28
 
29
29
  # Ruby bindings for the figo Connect API: http://developer.figo.me
30
30
  module Figo
31
-
32
31
  $api_endpoint = "api.figo.me"
33
32
 
34
- $valid_fingerprints = ["3A:62:54:4D:86:B4:34:38:EA:34:64:4E:95:10:A9:FF:37:27:69:C0"]
33
+ $valid_fingerprints = ["3A:62:54:4D:86:B4:34:38:EA:34:64:4E:95:10:A9:FF:37:27:69:C0",
34
+ "CF:C1:BC:7F:6A:16:09:2B:10:83:8A:B0:22:4F:3A:65:D2:70:D7:3E"]
35
35
 
36
36
  # Base class for all errors transported via the figo Connect API.
37
37
  class Error < RuntimeError
38
-
39
38
  # Initialize error object.
40
39
  #
41
40
  # @param error [String] the error code
@@ -51,12 +50,10 @@ module Figo
51
50
  def to_s
52
51
  return @error_description
53
52
  end
54
-
55
53
  end
56
54
 
57
55
  # HTTPS class with certificate authentication and enhanced error handling.
58
56
  class HTTPS < Net::HTTP::Persistent
59
-
60
57
  # Overwrite `initialize` method from `Net::HTTP::Persistent`.
61
58
  #
62
59
  # Verify fingerprints of server SSL/TLS certificates.
@@ -110,7 +107,6 @@ module Figo
110
107
  #
111
108
  # It's main purpose is to let user login via OAuth 2.0.
112
109
  class Connection
113
-
114
110
  # Create connection object with client credentials.
115
111
  #
116
112
  # @param client_id [String] the client ID
@@ -149,32 +145,32 @@ module Figo
149
145
 
150
146
  # Get the URL a user should open in the web browser to start the login process.
151
147
  #
152
- # When the process is completed, the user is redirected to the URL provided to
153
- # the constructor and passes on an authentication code. This code can be converted
148
+ # When the process is completed, the user is redirected to the URL provided to
149
+ # the constructor and passes on an authentication code. This code can be converted
154
150
  # into an access token for data access.
155
151
  #
156
- # @param state [String] this string will be passed on through the complete login
157
- # process and to the redirect target at the end. It should be used to
152
+ # @param state [String] this string will be passed on through the complete login
153
+ # process and to the redirect target at the end. It should be used to
158
154
  # validated the authenticity of the call to the redirect URL
159
- # @param scope [String] optional scope of data access to ask the user for,
155
+ # @param scope [String] optional scope of data access to ask the user for,
160
156
  # e.g. `accounts=ro`
161
157
  # @return [String] the URL to be opened by the user.
162
158
  def login_url(state, scope = nil)
163
159
  data = { "response_type" => "code", "client_id" => @client_id, "state" => state }
164
160
  data["redirect_uri"] = @redirect_uri unless @redirect_uri.nil?
165
161
  data["scope"] = scope unless scope.nil?
166
- return "https://#{$api_endpoint}/auth/code?" + URI.encode_www_form(data)
162
+ return "https://#{$api_endpoint}/auth/code?" + URI.encode_www_form(data)
167
163
  end
168
164
 
169
165
 
170
166
  # Exchange authorization code or refresh token for access token.
171
167
  #
172
- # @param authorization_code_or_refresh_token [String] either the authorization
173
- # code received as part of the call to the redirect URL at the end of the
168
+ # @param authorization_code_or_refresh_token [String] either the authorization
169
+ # code received as part of the call to the redirect URL at the end of the
174
170
  # logon process, or a refresh token
175
- # @param scope [String] optional scope of data access to ask the user for,
171
+ # @param scope [String] optional scope of data access to ask the user for,
176
172
  # e.g. `accounts=ro`
177
- # @return [Hash] object with the keys `access_token`, `refresh_token` and
173
+ # @return [Hash] object with the keys `access_token`, `refresh_token` and
178
174
  # `expires`, as documented in the figo Connect API specification.
179
175
  def obtain_access_token(authorization_code_or_refresh_token, scope = nil)
180
176
  # Authorization codes always start with "O" and refresh tokens always start with "R".
@@ -200,6 +196,18 @@ module Figo
200
196
  return nil
201
197
  end
202
198
 
199
+ # Create a new figo Account
200
+ #
201
+ # @param name [String] First and last name
202
+ # @param email [String] Email address; It must obey the figo username & password policy
203
+ # @param password [String] New figo Account password; It must obey the figo username & password policy
204
+ # @param language [String] Two-letter code of preferred language
205
+ # @param send_newsletter [Boolean] This flag indicates whether the user has agreed to be contacted by email
206
+ # @return [Hash] object with the key `recovery_password` as documented in the figo Connect API specification
207
+ def create_user(name, email, password, language='de', send_newsletter=True)
208
+ data = { 'name' => name, 'email' => email, 'password' => password, 'language' => language, 'send_newsletter' => send_newsletter, 'affiliate_client_id' => @client_id}
209
+ return query_api("/auth/user", data)
210
+ end
203
211
  end
204
212
 
205
213
  # Represents a user-bound connection to the figo Connect API and allows access to the user's data.
@@ -244,116 +252,239 @@ module Figo
244
252
  response = @https.request(uri, request)
245
253
 
246
254
  # Evaluate HTTP response.
247
- if response.nil?
248
- return nil
249
- elsif response.body.nil?
250
- return nil
251
- else
252
- return response.body == "" ? nil : JSON.parse(response.body)
253
- end
255
+ return nil if response.nil?
256
+ return nil if response.body.nil?
257
+ return response.body == "" ? nil : JSON.parse(response.body)
258
+ end
259
+
260
+ def query_api_object(type, path, data=nil, method="GET", array_name=nil) # :nodoc:
261
+ response = query_api path, data, method
262
+ return nil if response.nil?
263
+ return type.new(self, response) if array_name.nil?
264
+ return response[array_name].map {|entry| type.new(self, entry)}
265
+ end
266
+
267
+ # Retrieve current User
268
+ #
269
+ # @return [User] the current user
270
+ def user
271
+ query_api_object User, "/rest/user"
272
+ end
273
+
274
+ # Modify the current user
275
+ #
276
+ # @param user [User] the modified user object to be saved
277
+ # @return [User] the modified user returned
278
+ def modify_user(user)
279
+ query_api_object User, "/rest/user", user.dump(), "PUT"
254
280
  end
255
281
 
256
- # Request list of accounts.
282
+ # Remove the current user
283
+ # Note: this has immidiate effect and you wont be able to interact with the user after this call
284
+ def remove_user
285
+ query_api "/rest/user", nil, "DELETE"
286
+ end
287
+
288
+ # Retrieve all accounts
257
289
  #
258
290
  # @return [Array] an array of `Account` objects, one for each account the user has granted the app access
259
291
  def accounts
260
- response = query_api("/rest/accounts")
261
- return response["accounts"].map {|account| Account.new(self, account)}
292
+ query_api_object Account, "/rest/accounts", nil, "GET", "accounts"
262
293
  end
263
294
 
264
- # Request specific account.
295
+ # Retrieve specific account.
265
296
  #
266
297
  # @param account_id [String] ID of the account to be retrieved.
267
298
  # @return [Account] account object
268
299
  def get_account(account_id)
269
- response = query_api("/rest/accounts/#{account_id}")
270
- return response.nil? ? nil : Account.new(self, response)
300
+ query_api_object Account, "/rest/accounts/#{account_id}"
301
+ end
302
+
303
+ # Modify specific account
304
+ #
305
+ # @param account [Account] modified account to be saved
306
+ # @return [Account] modified account returned by the server
307
+ def modify_account(account)
308
+ query_api_object Account, "/rest/accounts/#{account.account_id}", account.dump(), "PUT"
309
+ end
310
+
311
+ # Remove specific account
312
+ #
313
+ # @param account [Account, String] the account to be removed or its ID
314
+ def remove_account(account)
315
+ query_api account.is_a?(String) ? "/rest/accounts/#{account}" : "/rest/accounts/#{account.account_id}", nil, "DELETE"
271
316
  end
272
317
 
273
- # Request list of transactions.
318
+ # Retrieve balance of an account.
274
319
  #
320
+ # @return [AccountBalance] account balance object
321
+ def get_account_balance(account_id)
322
+ query_api_object AccountBalance, "/rest/accounts/#{account_id}/balance"
323
+ end
324
+
325
+ # Modify balance or account limits
326
+ #
327
+ # @param account_id [String] ID of the account which balance should be modified
328
+ # @param account_balance [AccountBalance] modified AccountBalance to be saved
329
+ # @return [AccountBalance] modified AccountBalance returned by server
330
+ def modify_account_balance(account_id, account_balance)
331
+ query_api_object AccountBalance, "/rest/accounts/#{account_id}/balance", account_balance.dump(), "PUT"
332
+ end
333
+
334
+ # Retrieve specific bank
335
+ #
336
+ # @return [Bank] bank object
337
+ def get_bank(bank_id)
338
+ query_api_object Bank, "/rest/banks/#{bank_id}"
339
+ end
340
+
341
+ # Modify bank
342
+ #
343
+ # @param bank [Bank] modified bank object
344
+ # @return [Bank] modified bank object returned by server
345
+ def modify_bank(bank)
346
+ query_api_object Bank, "/rest/banks/#{bank.bank_id}", bank.dump(), "PUT"
347
+ end
348
+
349
+ # Remove stored PIN from bank
350
+ #
351
+ # @param bank [Bank, String] the bank whose stored PIN should be removed or its ID
352
+ # @return [nil]
353
+ def remove_bank_pin(bank)
354
+ query_app bank.is_a?(String) ? "/rest/banks/#{bank}/submit": "/rest/banks/#{bank.bank_id}/submit", nil, "POST"
355
+ end
356
+
357
+ # Retrieve list of transactions (on all or a specific account)
358
+ #
359
+ # @param account_id [String] ID of the account for which to list the transactions
275
360
  # @param since [String, Date] this parameter can either be a transaction ID or a date
276
361
  # @param start_id [String] do only return transactions which were booked after the start transaction ID
277
362
  # @param count [Integer] limit the number of returned transactions
278
- # @param include_pending [Boolean] this flag indicates whether pending transactions should be included
279
- # in the response; pending transactions are always included as a complete set, regardless of
363
+ # @param include_pending [Boolean] this flag indicates whether pending transactions should be included
364
+ # in the response; pending transactions are always included as a complete set, regardless of
280
365
  # the `since` parameter
281
366
  # @return [Array] an array of `Transaction` objects, one for each transaction of the user
282
- def transactions(since = nil, start_id = nil, count = 1000, include_pending = false)
283
- data = {}
284
- data["since"] = (since.is_a?(Date) ? since.to_s : since) unless since.nil?
367
+ def transactions(account_id = nil, since = nil, start_id = nil, count = 1000, include_pending = false)
368
+ data = {"count" => count.to_s, "include_pending" => include_pending ? "1" : "0"}
369
+ data["since"] = ((since.is_a?(Date) ? since.to_s : since) unless since.nil?)
285
370
  data["start_id"] = start_id unless start_id.nil?
286
- data["count"] = count.to_s
287
- data["include_pending"] = include_pending ? "1" : "0"
288
- response = query_api("/rest/transactions?" + URI.encode_www_form(data))
289
- return response["transactions"].map {|transaction| Transaction.new(self, transaction)}
371
+
372
+ query_api_object Transaction, (account_id.nil? ? "/rest/transactions?" : "/rest/accounts/#{account_id}/transactions?") + URI.encode_www_form(data), nil, "GET", "transactions"
290
373
  end
291
374
 
292
- # Request the URL a user should open in the web browser to start the synchronization process.
375
+ # Retrieve a specific transaction
376
+ #
377
+ # @param account_id [String] ID of the account on which the transaction occured
378
+ # @param transaction_id [String] ID of the transaction to be retrieved
379
+ # @return [Transaction] transaction object
380
+ def get_transaction(account_id, transaction_id)
381
+ query_api_object Transaction, "/rest/accounts/#{account_id}/transactions/#{transaction_id}"
382
+ end
383
+
384
+ # Retrieve the URL a user should open in the web browser to start the synchronization process.
293
385
  #
294
386
  # @param redirect_uri [String] the user will be redirected to this URL after the process completes
295
- # @param state [String] this string will be passed on through the complete synchronization process
296
- # and to the redirect target at the end. It should be used to validated the authenticity of
387
+ # @param state [String] this string will be passed on through the complete synchronization process
388
+ # and to the redirect target at the end. It should be used to validated the authenticity of
297
389
  # the call to the redirect URL
298
- # @param disable_notifications [Booleon] this flag indicates whether notifications should be sent
299
- # @param if_not_synced_since [Integer] if this parameter is set, only those accounts will be
390
+ # @param if_not_synced_since [Integer] if this parameter is set, only those accounts will be
300
391
  # synchronized, which have not been synchronized within the specified number of minutes.
301
392
  # @return [String] the URL to be opened by the user.
302
- def sync_url(redirect_uri, state, disable_notifications = false, if_not_synced_since = 0)
303
- data = { "redirect_uri" => redirect_uri, "state" => state, "disable_notifications" => disable_notifications, "if_not_synced_since" => if_not_synced_since }
304
- response = query_api("/rest/sync", data, "POST")
393
+ def sync_url(redirect_uri, state, if_not_synced_since = 0)
394
+ response = query_api "/rest/sync", {"redirect_uri" => redirect_uri, "state" => state, "if_not_synced_since" => if_not_synced_since}, "POST"
305
395
  return "https://#{$api_endpoint}/task/start?id=#{response["task_token"]}"
306
396
  end
307
397
 
308
- # Request list of registered notifications.
398
+ # Retrieve list of registered notifications.
309
399
  #
310
400
  # @return [Notification] an array of `Notification` objects, one for each registered notification
311
401
  def notifications
312
- response = query_api("/rest/notifications")
313
- return response["notifications"].map {|notification| Notification.new(self, notification)}
402
+ query_api_object Notification, "/rest/notifications", nil, "GET", "notifications"
314
403
  end
315
404
 
316
- # Request specific notification.
405
+ # Retrieve specific notification.
317
406
  #
318
407
  # @param notification_id [String] ID of the notification to be retrieved
319
408
  # @return [Notification] `Notification` object for the respective notification
320
409
  def get_notification(notification_id)
321
- response = query_api("/rest/notifications/#{notification_id}")
322
- return response.nil? ? nil : Notification.new(self, response)
410
+ query_api_object Notification, "/rest/notifications/#{notification_id}"
323
411
  end
324
412
 
325
- # Register notification.
413
+ # Register a new notification.
326
414
  #
327
- # @param observe_key [String] one of the notification keys specified in the figo Connect API
328
- # specification
329
- # @param notify_uri [String] notification messages will be sent to this URL
330
- # @param state [String] any kind of string that will be forwarded in the notification message
415
+ # @param notification [Notification] notification to be crated. It should not have a notification_id set.
331
416
  # @return [Notification] newly created `Notification` object
332
- def add_notification(observe_key, notify_uri, state)
333
- data = { "observe_key" => observe_key, "notify_uri" => notify_uri, "state" => state }
334
- response = query_api("/rest/notifications", data, "POST")
335
- return Notification.new(self, response)
417
+ def add_notification(notification)
418
+ query_api_object Notification, "/rest/notifications", notification.dump(), "POST"
336
419
  end
337
420
 
338
421
  # Modify notification.
339
422
  #
340
423
  # @param notification [Notification] modified notification object
341
- # @return [nil]
424
+ # @return [Notification] modified notification returned by server
342
425
  def modify_notification(notification)
343
- data = { "observe_key" => notification.observe_key, "notify_uri" => notification.notify_uri, "state" => notification.state }
344
- query_api("/rest/notifications/#{notification.notification_id}", data, "PUT")
345
- return nil
426
+ query_api_object Notification, "/rest/notifications/#{notification.notification_id}", notification.dump(), "PUT"
346
427
  end
347
428
 
348
429
  # Unregister notification.
349
430
  #
350
- # @param notification [Notification] notification object which should be deleted
351
- # @return [nil]
431
+ # @param notification [Notification, String] notification object which should be deleted or its ID
352
432
  def remove_notification(notification)
353
- query_api("/rest/notifications/#{notification.notification_id}", nil, "DELETE")
354
- return nil
433
+ query_api notification.is_a?(String) ? "/rest/notifications/#{notification}" : "/rest/notifications/#{notification.notification_id}", nil, "DELETE"
355
434
  end
356
435
 
357
- end
436
+ # Retrieve list of all payments (on all accounts or one)
437
+ #
438
+ # @param account_id [String] ID of the account for whicht to list the payments
439
+ # @return [Payment] an array of `Payment` objects, one for each payment
440
+ def payments(account_id = nil)
441
+ query_api_object Payment, account_id.nil? ? "/rest/payments" : "/rest/accounts/#{account_id}/payments", nil, "GET", "payments"
442
+ end
358
443
 
444
+ # Retrieve specific payment.
445
+ #
446
+ # @param account_id [String] ID for the account on which the payment to be retrieved was created
447
+ # @param payment_id [String] ID of the notification to be retrieved
448
+ # @return [Payment] `Payment` object for the respective payment
449
+ def get_payment(account_id, payment_id)
450
+ query_api_object Payment, "/rest/accounts/#{account_id}/payments/#{payment_id}"
451
+ end
452
+
453
+ # Create new payment
454
+ #
455
+ # @param payment [Payment] payment object to be created. It should not have a payment_id set.
456
+ # @return [Payment] newly created `Payment` object
457
+ def add_payment(payment)
458
+ query_api_object Payment, "/rest/accounts/#{payment.account_id}/payments", payment.dump(), "POST"
459
+ end
460
+
461
+ # Modify payment
462
+ #
463
+ # @param payment [Payment] modified payment object
464
+ # @return [Payment] modified payment object
465
+ def modify_payment(payment)
466
+ query_api_object Payment, "/rest/accounts/#{payment.account_id}/payments/#{payment.payment_id}", payment.dump(), "PUT"
467
+ end
468
+
469
+ # Submit payment
470
+ #
471
+ # @param tan_scheme_id [String] TAN scheme ID of user-selected TAN scheme
472
+ # @param state [String] Any kind of string that will be forwarded in the callback response message
473
+ # @param redirect_uri [String] At the end of the submission process a response will be sent to this callback URL
474
+ # @return [String] the URL to be opened by the user for the TAN process
475
+ def submit_payment(payment, tan_scheme_id, state, redirect_uri = nil)
476
+ params = {"tan_scheme_id" => tan_scheme_id, "state" => state}
477
+ params['redirect_uri'] = redirect_uri unless redirect_uri.nil?
478
+
479
+ response = query_api "/rest/accounts/#{payment.account_id}/payments/#{payment.payment_id}/submit", params, "POST"
480
+ return "https://#{$api_endpoint}/task/start?id=#{response["task_token"]}"
481
+ end
482
+
483
+ # Remove payment
484
+ #
485
+ # @param payment [Payment, String] payment object which should be removed
486
+ def remove_payment(payment)
487
+ query_api "/rest/accounts/#{payment.account_id}/payments/#{payment.payment_id}", nil, "DELETE"
488
+ end
489
+ end
359
490
  end