tikkie-api 0.1.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 +7 -0
- data/.gitignore +14 -0
- data/.rspec +3 -0
- data/.rubocop.yml +36 -0
- data/.travis.yml +7 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +67 -0
- data/LICENSE.txt +21 -0
- data/README.md +150 -0
- data/Rakefile +10 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/lib/tikkie/api.rb +32 -0
- data/lib/tikkie/api/access_token.rb +19 -0
- data/lib/tikkie/api/authentication.rb +60 -0
- data/lib/tikkie/api/client.rb +24 -0
- data/lib/tikkie/api/configuration.rb +62 -0
- data/lib/tikkie/api/exception.rb +22 -0
- data/lib/tikkie/api/request.rb +57 -0
- data/lib/tikkie/api/requests/payment_requests.rb +56 -0
- data/lib/tikkie/api/requests/platforms.rb +32 -0
- data/lib/tikkie/api/requests/users.rb +31 -0
- data/lib/tikkie/api/responses/bank_account.rb +22 -0
- data/lib/tikkie/api/responses/base.rb +53 -0
- data/lib/tikkie/api/responses/error.rb +34 -0
- data/lib/tikkie/api/responses/pagination.rb +20 -0
- data/lib/tikkie/api/responses/payment.rb +48 -0
- data/lib/tikkie/api/responses/payment_request.rb +64 -0
- data/lib/tikkie/api/responses/payment_request_created.rb +22 -0
- data/lib/tikkie/api/responses/payment_requests.rb +42 -0
- data/lib/tikkie/api/responses/platform.rb +44 -0
- data/lib/tikkie/api/responses/platforms.rb +30 -0
- data/lib/tikkie/api/responses/user.rb +39 -0
- data/lib/tikkie/api/responses/users.rb +34 -0
- data/lib/tikkie/api/types/payment_request_status.rb +15 -0
- data/lib/tikkie/api/types/payment_status.rb +14 -0
- data/lib/tikkie/api/types/platform_status.rb +12 -0
- data/lib/tikkie/api/types/platform_usage.rb +12 -0
- data/lib/tikkie/api/types/user_status.rb +12 -0
- data/lib/tikkie/api/version.rb +7 -0
- data/tikkie-api.gemspec +31 -0
- metadata +168 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tikkie
|
4
|
+
module Api
|
5
|
+
# Tikkie API client.
|
6
|
+
class Client
|
7
|
+
def initialize(config)
|
8
|
+
@request = Tikkie::Api::Request.new(config)
|
9
|
+
end
|
10
|
+
|
11
|
+
def platforms
|
12
|
+
Tikkie::Api::Requests::Platforms.new(@request)
|
13
|
+
end
|
14
|
+
|
15
|
+
def users
|
16
|
+
Tikkie::Api::Requests::Users.new(@request)
|
17
|
+
end
|
18
|
+
|
19
|
+
def payment_requests
|
20
|
+
Tikkie::Api::Requests::PaymentRequests.new(@request)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tikkie
|
4
|
+
module Api
|
5
|
+
# Tikkie API Configuration. An API Key and private key are mandatory.
|
6
|
+
# see https://developer.abnamro.com/get-started
|
7
|
+
class Configuration
|
8
|
+
SANDBOX_API_URL = "https://api-sandbox.abnamro.com/v1/"
|
9
|
+
PRODUCTION_API_URL = "https://api.abnamro.com/v1/"
|
10
|
+
|
11
|
+
SANDBOX_OAUTH_TOKEN_URL = "https://auth-sandbox.abnamro.com/oauth/token"
|
12
|
+
PRODUCTION_OAUTH_TOKEN_URL = "https://auth.abnamro.com/oauth/token"
|
13
|
+
|
14
|
+
DEFAULT_HASHING_ALGORITHM = "RS256"
|
15
|
+
VALID_HASHING_ALGORITHMS = %w[RS256 RS384 RS512].freeze
|
16
|
+
|
17
|
+
attr_reader :api_key, :private_key, :options
|
18
|
+
|
19
|
+
def initialize(api_key, private_key, options = {})
|
20
|
+
@api_key = api_key
|
21
|
+
@private_key = private_key
|
22
|
+
@options = options
|
23
|
+
end
|
24
|
+
|
25
|
+
def private_data
|
26
|
+
unless File.exist?(@private_key)
|
27
|
+
raise Tikkie::Api::Exception, "Private key does not exist: #{@private_key}"
|
28
|
+
end
|
29
|
+
|
30
|
+
OpenSSL::PKey::RSA.new(File.read(@private_key))
|
31
|
+
end
|
32
|
+
|
33
|
+
def jwt_hashing_algorithm
|
34
|
+
if @options[:hashing_algorithm]
|
35
|
+
unless VALID_HASHING_ALGORITHMS.include?(@options[:hashing_algorithm])
|
36
|
+
raise Tikkie::Api::Exception, "Invalid hashing algorithm provided: #{@options[:hashing_algorithm]} (expected: #{VALID_HASHING_ALGORITHMS.join(', ')})"
|
37
|
+
end
|
38
|
+
|
39
|
+
@options[:hashing_algorithm]
|
40
|
+
else
|
41
|
+
DEFAULT_HASHING_ALGORITHM
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def api_url
|
46
|
+
if @options[:test]
|
47
|
+
SANDBOX_API_URL
|
48
|
+
else
|
49
|
+
PRODUCTION_API_URL
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def oauth_token_url
|
54
|
+
if @options[:test]
|
55
|
+
SANDBOX_OAUTH_TOKEN_URL
|
56
|
+
else
|
57
|
+
PRODUCTION_OAUTH_TOKEN_URL
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tikkie
|
4
|
+
module Api
|
5
|
+
# Tikkie base exception.
|
6
|
+
class Exception < RuntimeError
|
7
|
+
end
|
8
|
+
|
9
|
+
# Exception when the authentication fails.
|
10
|
+
class AuthenticationException < Tikkie::Api::Exception
|
11
|
+
attr_reader :response, :body
|
12
|
+
|
13
|
+
def initialize(response)
|
14
|
+
@response = response
|
15
|
+
@body = response.body
|
16
|
+
|
17
|
+
message = "Authentication failure at Tikkie"
|
18
|
+
super(message)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
require 'uri'
|
5
|
+
|
6
|
+
module Tikkie
|
7
|
+
module Api
|
8
|
+
# Make authenticated HTTP requests to the Tikkie API.
|
9
|
+
class Request
|
10
|
+
def initialize(config)
|
11
|
+
@config = config
|
12
|
+
end
|
13
|
+
|
14
|
+
def get(path, params = {})
|
15
|
+
uri = URI.parse(File.join(@config.api_url, path))
|
16
|
+
uri.query = URI.encode_www_form(params) unless params.empty?
|
17
|
+
|
18
|
+
request = Net::HTTP::Get.new(uri)
|
19
|
+
request["Api-Key"] = @config.api_key
|
20
|
+
request["Authorization"] = "Bearer #{access_token}"
|
21
|
+
|
22
|
+
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
|
23
|
+
http.request(request)
|
24
|
+
end
|
25
|
+
|
26
|
+
response
|
27
|
+
end
|
28
|
+
|
29
|
+
def post(path, params = {})
|
30
|
+
uri = URI.parse(File.join(@config.api_url, path))
|
31
|
+
|
32
|
+
request = Net::HTTP::Post.new(uri)
|
33
|
+
request["Api-Key"] = @config.api_key
|
34
|
+
request["Authorization"] = "Bearer #{access_token}"
|
35
|
+
request["Content-Type"] = "application/json"
|
36
|
+
request.body = params.to_json
|
37
|
+
|
38
|
+
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
|
39
|
+
http.request(request)
|
40
|
+
end
|
41
|
+
|
42
|
+
response
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def access_token
|
48
|
+
if @access_token.nil? || @access_token.expired?
|
49
|
+
@authentication ||= Tikkie::Api::Authentication.new(@config)
|
50
|
+
@access_token = @authentication.authenticate
|
51
|
+
end
|
52
|
+
|
53
|
+
@access_token.token
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bigdecimal'
|
4
|
+
|
5
|
+
module Tikkie
|
6
|
+
module Api
|
7
|
+
module Requests
|
8
|
+
# Payment requests operations at Tikkie.
|
9
|
+
class PaymentRequests
|
10
|
+
def initialize(request)
|
11
|
+
@request = request
|
12
|
+
end
|
13
|
+
|
14
|
+
def list(platform_token, user_token, options = {})
|
15
|
+
offset = options[:offset] || 0
|
16
|
+
limit = options[:limit] || 20
|
17
|
+
from_date = options[:from_date]
|
18
|
+
to_date = options[:to_date]
|
19
|
+
|
20
|
+
params = { offset: offset, limit: limit }
|
21
|
+
params[:fromDate] = from_date.respond_to?(:utc) ? from_date.utc.iso8601 : from_date if from_date
|
22
|
+
params[:toDate] = to_date.respond_to?(:utc) ? to_date.utc.iso8601 : to_date if to_date
|
23
|
+
|
24
|
+
response = @request.get("/tikkie/platforms/#{platform_token}/users/#{user_token}/paymentrequests", params)
|
25
|
+
Tikkie::Api::Responses::PaymentRequests.new(response, offset: offset, limit: limit)
|
26
|
+
end
|
27
|
+
|
28
|
+
def get(platform_token, user_token, payment_request_token)
|
29
|
+
response = @request.get("/tikkie/platforms/#{platform_token}/users/#{user_token}/paymentrequests/#{payment_request_token}")
|
30
|
+
|
31
|
+
Tikkie::Api::Responses::PaymentRequest.new(response)
|
32
|
+
end
|
33
|
+
|
34
|
+
def create(platform_token, user_token, bank_account_token, options = {})
|
35
|
+
params = {
|
36
|
+
amountInCents: to_cents(options.fetch(:amount)),
|
37
|
+
currency: options.fetch(:currency),
|
38
|
+
description: options.fetch(:description),
|
39
|
+
externalId: options[:external_id]
|
40
|
+
}
|
41
|
+
response = @request.post("/tikkie/platforms/#{platform_token}/users/#{user_token}/bankaccounts/#{bank_account_token}/paymentrequests", params)
|
42
|
+
|
43
|
+
Tikkie::Api::Responses::PaymentRequestCreated.new(response)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def to_cents(amount)
|
49
|
+
decimal = BigDecimal.new(amount.to_s)
|
50
|
+
decimal *= 100 # to cents
|
51
|
+
decimal.to_i
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tikkie
|
4
|
+
module Api
|
5
|
+
module Requests
|
6
|
+
# Platforms operations at Tikkie.
|
7
|
+
class Platforms
|
8
|
+
def initialize(request)
|
9
|
+
@request = request
|
10
|
+
end
|
11
|
+
|
12
|
+
def list
|
13
|
+
response = @request.get("/tikkie/platforms")
|
14
|
+
Tikkie::Api::Responses::Platforms.new(response)
|
15
|
+
end
|
16
|
+
|
17
|
+
def create(options = {})
|
18
|
+
params = {
|
19
|
+
name: options.fetch(:name),
|
20
|
+
phoneNumber: options.fetch(:phone_number),
|
21
|
+
platformUsage: options.fetch(:platform_usage),
|
22
|
+
email: options[:email],
|
23
|
+
notificationUrl: options[:notification_url]
|
24
|
+
}
|
25
|
+
response = @request.post("/tikkie/platforms", params)
|
26
|
+
|
27
|
+
Tikkie::Api::Responses::Platform.new(response)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tikkie
|
4
|
+
module Api
|
5
|
+
module Requests
|
6
|
+
# Users operations at Tikkie.
|
7
|
+
class Users
|
8
|
+
def initialize(request)
|
9
|
+
@request = request
|
10
|
+
end
|
11
|
+
|
12
|
+
def list(platform_token)
|
13
|
+
response = @request.get("/tikkie/platforms/#{platform_token}/users")
|
14
|
+
Tikkie::Api::Responses::Users.new(response)
|
15
|
+
end
|
16
|
+
|
17
|
+
def create(platform_token, options = {})
|
18
|
+
params = {
|
19
|
+
name: options.fetch(:name),
|
20
|
+
phoneNumber: options.fetch(:phone_number),
|
21
|
+
iban: options.fetch(:iban),
|
22
|
+
bankAccountLabel: options.fetch(:bank_account_label)
|
23
|
+
}
|
24
|
+
response = @request.post("/tikkie/platforms/#{platform_token}/users", params)
|
25
|
+
|
26
|
+
Tikkie::Api::Responses::User.new(response)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tikkie
|
4
|
+
module Api
|
5
|
+
module Responses
|
6
|
+
# Bank account of a user.
|
7
|
+
class BankAccount < Base
|
8
|
+
def bank_account_token
|
9
|
+
data[:bankAccountToken]
|
10
|
+
end
|
11
|
+
|
12
|
+
def bank_account_label
|
13
|
+
data[:bankAccountLabel]
|
14
|
+
end
|
15
|
+
|
16
|
+
def iban
|
17
|
+
data[:iban]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Tikkie
|
6
|
+
module Api
|
7
|
+
module Responses
|
8
|
+
# Base class for all responses.
|
9
|
+
class Base
|
10
|
+
attr_reader :response, :data
|
11
|
+
|
12
|
+
def initialize(response)
|
13
|
+
if response.respond_to?(:body)
|
14
|
+
@response = response
|
15
|
+
@data = JSON.parse(response.body, symbolize_names: true)
|
16
|
+
else
|
17
|
+
@data = response
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def response_code
|
22
|
+
response.code.to_i if response
|
23
|
+
end
|
24
|
+
|
25
|
+
def success?
|
26
|
+
response_code == 200 || response_code == 201
|
27
|
+
end
|
28
|
+
|
29
|
+
def error?
|
30
|
+
!success?
|
31
|
+
end
|
32
|
+
|
33
|
+
def trace_id
|
34
|
+
response["Trace-Id"] if response
|
35
|
+
end
|
36
|
+
|
37
|
+
def errors
|
38
|
+
@errors ||= begin
|
39
|
+
errors = []
|
40
|
+
|
41
|
+
if data[:errors]
|
42
|
+
data[:errors].each do |error|
|
43
|
+
errors << Tikkie::Api::Responses::Error.new(error)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
errors
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tikkie
|
4
|
+
module Api
|
5
|
+
module Responses
|
6
|
+
# Error response from Tikkie.
|
7
|
+
class Error < Base
|
8
|
+
def code
|
9
|
+
data[:code]
|
10
|
+
end
|
11
|
+
|
12
|
+
def message
|
13
|
+
data[:message]
|
14
|
+
end
|
15
|
+
|
16
|
+
def reference
|
17
|
+
data[:reference]
|
18
|
+
end
|
19
|
+
|
20
|
+
def trace_id
|
21
|
+
data[:traceId]
|
22
|
+
end
|
23
|
+
|
24
|
+
def status
|
25
|
+
data[:status]
|
26
|
+
end
|
27
|
+
|
28
|
+
def category
|
29
|
+
data[:category]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tikkie
|
4
|
+
module Api
|
5
|
+
module Responses
|
6
|
+
# Helper for paginated responses.
|
7
|
+
module Pagination
|
8
|
+
attr_accessor :offset, :limit, :elements, :total_elements
|
9
|
+
|
10
|
+
def more_elements?
|
11
|
+
@total_elements && @total_elements > @offset + @elements
|
12
|
+
end
|
13
|
+
|
14
|
+
def next_offset
|
15
|
+
@offset + @limit if more_elements?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bigdecimal'
|
4
|
+
require 'time'
|
5
|
+
|
6
|
+
module Tikkie
|
7
|
+
module Api
|
8
|
+
module Responses
|
9
|
+
# Payment that is associated with a payment request.
|
10
|
+
class Payment < Base
|
11
|
+
def payment_token
|
12
|
+
data[:paymentToken]
|
13
|
+
end
|
14
|
+
|
15
|
+
def counter_party_name
|
16
|
+
data[:counterPartyName]
|
17
|
+
end
|
18
|
+
|
19
|
+
def amount
|
20
|
+
decimal = BigDecimal.new(data[:amountInCents])
|
21
|
+
decimal /= 100.0
|
22
|
+
decimal
|
23
|
+
end
|
24
|
+
|
25
|
+
def currency
|
26
|
+
data[:amountCurrency]
|
27
|
+
end
|
28
|
+
|
29
|
+
def description
|
30
|
+
data[:description]
|
31
|
+
end
|
32
|
+
|
33
|
+
def created_at
|
34
|
+
Time.parse(data[:created]) if data[:created]
|
35
|
+
end
|
36
|
+
|
37
|
+
# See PaymentStatus
|
38
|
+
def online_payment_status
|
39
|
+
data[:onlinePaymentStatus]
|
40
|
+
end
|
41
|
+
|
42
|
+
def paid?
|
43
|
+
online_payment_status == Tikkie::Api::Types::PaymentStatus::PAID
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|