monobank-lotarc 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +6 -0
  3. data/lib/monobank/auth/corporate.rb +35 -0
  4. data/lib/monobank/auth/private.rb +17 -0
  5. data/lib/monobank/bank/currency.rb +22 -0
  6. data/lib/monobank/client.rb +44 -0
  7. data/lib/monobank/configuration.rb +9 -0
  8. data/lib/monobank/connection.rb +16 -0
  9. data/lib/monobank/corporate/client.rb +60 -0
  10. data/lib/monobank/corporate.rb +21 -0
  11. data/lib/monobank/error.rb +3 -0
  12. data/lib/monobank/methods/base.rb +48 -0
  13. data/lib/monobank/methods/get.rb +15 -0
  14. data/lib/monobank/methods/post.rb +15 -0
  15. data/lib/monobank/personal/auth_check.rb +22 -0
  16. data/lib/monobank/personal/auth_request.rb +31 -0
  17. data/lib/monobank/personal/client_info.rb +20 -0
  18. data/lib/monobank/personal/corporate_webhook.rb +15 -0
  19. data/lib/monobank/personal/registration.rb +46 -0
  20. data/lib/monobank/personal/registration_status.rb +32 -0
  21. data/lib/monobank/personal/settings.rb +20 -0
  22. data/lib/monobank/personal/statement.rb +34 -0
  23. data/lib/monobank/personal/webhook.rb +32 -0
  24. data/lib/monobank/resources/bank/currency.rb +11 -0
  25. data/lib/monobank/resources/base.rb +35 -0
  26. data/lib/monobank/resources/error.rb +9 -0
  27. data/lib/monobank/resources/personal/accounts.rb +11 -0
  28. data/lib/monobank/resources/personal/auth_check.rb +11 -0
  29. data/lib/monobank/resources/personal/auth_request.rb +15 -0
  30. data/lib/monobank/resources/personal/client_info.rb +18 -0
  31. data/lib/monobank/resources/personal/registration.rb +11 -0
  32. data/lib/monobank/resources/personal/registration_status.rb +11 -0
  33. data/lib/monobank/resources/personal/settings.rb +11 -0
  34. data/lib/monobank/resources/personal/statement.rb +11 -0
  35. data/lib/monobank/resources/personal/webhook.rb +12 -0
  36. data/lib/monobank/version.rb +3 -0
  37. data/lib/monobank.rb +32 -0
  38. data/spec/monobank_corporate_spec.rb +290 -0
  39. data/spec/monobank_spec.rb +147 -0
  40. data/spec/spec_helper.rb +21 -0
  41. metadata +162 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 276ba643439c166bbae6db3ecf5c13b26ec36391fbdd1ab27db419e6bd6ccdc2
4
+ data.tar.gz: d8767ff05dd47192d419607486cd7decbd7e067f1d503100aa78c6d3012cb51f
5
+ SHA512:
6
+ metadata.gz: 49d30266da1855287cc6465763674bb1aa394b743e55804ee642c011544019d8642f8561297f16f3376cdddae54b47b0dee9961450d29ba86bea45784e00ff87
7
+ data.tar.gz: a9ae330fe93ca9d3f6cb518c9127298102aaeac9830defb4d01f7a7f8d26eae8f6d0e52a16f49e672062786dd6d2d823e079a9fb631a9d6400c8afff28a741e1
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,35 @@
1
+ module Monobank
2
+ module Auth
3
+ class Corporate
4
+ def initialize(private_key:, key_id: nil, request_id: nil)
5
+ @private_key = init_key(private_key:)
6
+ @key_id = key_id
7
+ @request_id = request_id
8
+ end
9
+
10
+ def to_headers(pathname:)
11
+ time = Time.now.to_i
12
+
13
+ {
14
+ 'X-Time' => time.to_s,
15
+ 'X-Sign' => Base64.strict_encode64(sign(pathname:, time:))
16
+ }.tap do |headers|
17
+ headers['X-Key-Id'] = key_id unless key_id.nil?
18
+ headers['X-Request-Id'] = request_id unless request_id.nil?
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ attr_accessor :private_key, :key_id, :request_id
25
+
26
+ def init_key(private_key:)
27
+ OpenSSL::PKey::EC.new(private_key)
28
+ end
29
+
30
+ def sign(pathname:, time:)
31
+ private_key.sign(OpenSSL::Digest::SHA256.new, "#{time}#{request_id}#{pathname}")
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,17 @@
1
+ module Monobank
2
+ module Auth
3
+ class Private
4
+ def initialize(token:)
5
+ @token = token
6
+ end
7
+
8
+ def to_headers(*)
9
+ { 'X-Token' => token }
10
+ end
11
+
12
+ private
13
+
14
+ attr_reader :token
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ require 'monobank/methods/get'
2
+ require 'monobank/resources/bank/currency'
3
+
4
+ module Monobank
5
+ module Bank
6
+ class Currency < Methods::Get
7
+ ENDPOINT = '/bank/currency'.freeze
8
+
9
+ private
10
+
11
+ def define_resources(attributes)
12
+ attributes.map do |attrs|
13
+ Monobank::Resources::Bank::Currency.new(attrs)
14
+ end
15
+ end
16
+
17
+ def pathname
18
+ ENDPOINT
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,44 @@
1
+ require 'monobank/connection'
2
+ require 'monobank/auth/private'
3
+ require 'monobank/bank/currency'
4
+ require 'monobank/personal/client_info'
5
+ require 'monobank/personal/statement'
6
+ require 'monobank/personal/webhook'
7
+
8
+ module Monobank
9
+ class Client
10
+ attr_reader :token
11
+
12
+ def initialize(token: nil)
13
+ @token = token
14
+ end
15
+
16
+ def bank_currency
17
+ Bank::Currency.new.call
18
+ end
19
+
20
+ def client_info(token: nil)
21
+ Personal::ClientInfo.new(auth: auth(token: token || @token)).call
22
+ end
23
+
24
+ def statement(account_id:, from:, to: nil, token: nil)
25
+ Personal::Statement.new(
26
+ account_id: account_id,
27
+ from: from,
28
+ to: to,
29
+ auth: auth(token: token || @token)
30
+ ).call
31
+ end
32
+
33
+ def set_webhook(url:, token: nil)
34
+ Personal::Webhook.new(url: url, auth: auth(token: token || @token)).call
35
+ end
36
+
37
+ private
38
+
39
+ def auth(token:)
40
+ raise ArgumentError, "Token is required" if token.nil?
41
+ Auth::Private.new(token: token)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,9 @@
1
+ module Monobank
2
+ class Configuration
3
+ attr_accessor :token
4
+
5
+ def initialize
6
+ @token = nil
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ require 'httparty'
2
+
3
+ module Monobank
4
+ class Connection
5
+ include HTTParty
6
+ base_uri 'https://api.monobank.ua'
7
+
8
+ def get(pathname, options = {})
9
+ self.class.get(pathname, options)
10
+ end
11
+
12
+ def post(pathname, options = {})
13
+ self.class.post(pathname, options)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,60 @@
1
+ require 'monobank/auth/corporate'
2
+ require 'monobank/personal/registration'
3
+ require 'monobank/personal/registration_status'
4
+ require 'monobank/personal/corporate_webhook'
5
+ require 'monobank/personal/settings'
6
+ require 'monobank/personal/auth_request'
7
+ require 'monobank/personal/auth_check'
8
+ require 'monobank/personal/client_info'
9
+ require 'monobank/personal/statement'
10
+
11
+ module Monobank
12
+ module Corporate
13
+ class Client
14
+ def initialize(private_key:, key_id:)
15
+ @private_key = private_key
16
+ @key_id = key_id
17
+ end
18
+
19
+ def registration(public_key:, name:, description:, contact_person:, phone:, email:, logo:)
20
+ Personal::Registration.new(public_key:, name:, description:, contact_person:, phone:, email:, logo:, auth:).call
21
+ end
22
+
23
+ def registration_status(public_key:)
24
+ Personal::RegistrationStatus.new(public_key:, auth:).call
25
+ end
26
+
27
+ def set_webhook(url:)
28
+ Personal::CorporateWebhook.new(url: url, auth:).call
29
+ end
30
+
31
+ def settings
32
+ Personal::Settings.new(auth:).call
33
+ end
34
+
35
+ def auth_request(callback: nil)
36
+ Personal::AuthRequest.new(callback:, auth:).call
37
+ end
38
+
39
+ def auth_check(request_id:)
40
+ Personal::AuthCheck.new(auth: auth(request_id:)).call
41
+ end
42
+
43
+ def client_info(request_id:)
44
+ Personal::ClientInfo.new(auth: auth(request_id:)).call
45
+ end
46
+
47
+ def statement(request_id:, account_id:, from:, to: nil)
48
+ Personal::Statement.new(account_id:, from:, to:, auth: auth(request_id:)).call
49
+ end
50
+
51
+ private
52
+
53
+ attr_reader :private_key, :key_id
54
+
55
+ def auth(request_id: nil)
56
+ Auth::Corporate.new(private_key:, key_id:, request_id:)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,21 @@
1
+ require 'forwardable'
2
+ require 'monobank/corporate/client'
3
+
4
+ module Monobank
5
+ module Corporate
6
+ extend SingleForwardable
7
+ def_delegators \
8
+ :client, :registration, :registration_status, :set_webhook, :settings,
9
+ :auth_request, :auth_check, :client_info, :statement
10
+
11
+ def self.configure(private_key:, key_id: nil)
12
+ @private_key = private_key
13
+ @key_id = key_id
14
+ @client = nil
15
+ end
16
+
17
+ def self.client
18
+ @client ||= Client.new(private_key: @private_key, key_id: @key_id)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ module Monobank
2
+ class Error < StandardError; end
3
+ end
@@ -0,0 +1,48 @@
1
+ require 'monobank/resources/error'
2
+
3
+ module Monobank
4
+ module Methods
5
+ class Base
6
+ def initialize(auth: nil)
7
+ @auth = auth
8
+ end
9
+
10
+ def call
11
+ http_response = response
12
+ attributes = http_response.parsed_response
13
+ return define_resources(attributes) if http_response.code == 200
14
+
15
+ Monobank::Resources::Error.new(attributes.merge('code' => http_response.code))
16
+ end
17
+
18
+ private
19
+
20
+ attr_reader :auth
21
+
22
+ def pathname
23
+ raise NotImplementedError
24
+ end
25
+
26
+ def response
27
+ raise NotImplementedError
28
+ end
29
+
30
+ def options
31
+ {
32
+ headers: (headers || {}).merge(auth&.to_headers(pathname:) || {}),
33
+ body: body.to_json
34
+ }
35
+ end
36
+
37
+ def headers
38
+ {}
39
+ end
40
+
41
+ def body; end
42
+
43
+ def connection
44
+ @connection ||= Connection.new
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,15 @@
1
+ require 'monobank/methods/base'
2
+ require 'monobank/resources/error'
3
+
4
+ module Monobank
5
+ module Methods
6
+ class Get < Base
7
+
8
+ private
9
+
10
+ def response
11
+ connection.get(pathname, options)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'monobank/methods/base'
2
+ require 'monobank/resources/error'
3
+
4
+ module Monobank
5
+ module Methods
6
+ class Post < Base
7
+
8
+ private
9
+
10
+ def response
11
+ connection.post(pathname, options)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ require 'monobank/methods/get'
2
+ require 'monobank/resources/personal/auth_check'
3
+
4
+ module Monobank
5
+ module Personal
6
+ class AuthCheck < Methods::Get
7
+ ENDPOINT = '/personal/auth/request'.freeze
8
+
9
+ private
10
+
11
+ attr_reader :request_id
12
+
13
+ def pathname
14
+ ENDPOINT
15
+ end
16
+
17
+ def define_resources(attributes)
18
+ Monobank::Resources::Personal::AuthCheck.new(attributes)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,31 @@
1
+ require 'monobank/methods/post'
2
+ require 'monobank/resources/personal/auth_request'
3
+
4
+ module Monobank
5
+ module Personal
6
+ class AuthRequest < Methods::Post
7
+ ENDPOINT = '/personal/auth/request'.freeze
8
+
9
+ def initialize(callback: nil, **rest)
10
+ super(**rest)
11
+ @callback = callback
12
+ end
13
+
14
+ private
15
+
16
+ attr_reader :callback
17
+
18
+ def pathname
19
+ ENDPOINT
20
+ end
21
+
22
+ def headers
23
+ {'X-Callback' => callback} if callback
24
+ end
25
+
26
+ def define_resources(attributes)
27
+ Monobank::Resources::Personal::AuthRequest.new(attributes)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,20 @@
1
+ require 'monobank/methods/get'
2
+ require 'monobank/resources/personal/client_info'
3
+
4
+ module Monobank
5
+ module Personal
6
+ class ClientInfo < Methods::Get
7
+ ENDPOINT = '/personal/client-info'.freeze
8
+
9
+ private
10
+
11
+ def pathname
12
+ ENDPOINT
13
+ end
14
+
15
+ def define_resources(attributes)
16
+ Monobank::Resources::Personal::ClientInfo.new(attributes)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ require 'monobank/personal/webhook'
2
+
3
+ module Monobank
4
+ module Personal
5
+ class CorporateWebhook < Webhook
6
+ ENDPOINT = '/personal/corp/webhook'.freeze
7
+
8
+ private
9
+
10
+ def pathname
11
+ ENDPOINT
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,46 @@
1
+ require 'monobank/methods/post'
2
+ require 'monobank/resources/personal/registration'
3
+
4
+ module Monobank
5
+ module Personal
6
+ class Registration < Methods::Post
7
+ ENDPOINT = '/personal/auth/registration'.freeze
8
+
9
+ def initialize(public_key:, name:, description:, contact_person:, phone:, email:, logo:, **rest)
10
+ super(**rest)
11
+
12
+ @public_key = public_key
13
+ @name = name
14
+ @description = description
15
+ @contact_person = contact_person
16
+ @phone = phone
17
+ @email = email
18
+ @logo = logo
19
+ end
20
+
21
+ def pathname
22
+ ENDPOINT
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :public_key, :name, :description, :contact_person, :phone, :email, :logo
28
+
29
+ def body
30
+ {
31
+ pubkey: public_key,
32
+ name:,
33
+ description:,
34
+ contactPerson: contact_person,
35
+ phone:,
36
+ email:,
37
+ logo:
38
+ }
39
+ end
40
+
41
+ def define_resources(attributes)
42
+ Resources::Personal::Registration.new(attributes)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,32 @@
1
+ require 'monobank/methods/post'
2
+ require 'monobank/resources/personal/registration_status'
3
+
4
+ module Monobank
5
+ module Personal
6
+ class RegistrationStatus < Methods::Post
7
+ ENDPOINT = '/personal/auth/registration/status'.freeze
8
+
9
+ def initialize(public_key:, **rest)
10
+ super(**rest)
11
+
12
+ @public_key = public_key
13
+ end
14
+
15
+ def pathname
16
+ ENDPOINT
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :public_key
22
+
23
+ def body
24
+ { pubkey: public_key }
25
+ end
26
+
27
+ def define_resources(attributes)
28
+ Resources::Personal::RegistrationStatus.new(attributes)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,20 @@
1
+ require 'monobank/methods/post'
2
+ require 'monobank/resources/personal/settings'
3
+
4
+ module Monobank
5
+ module Personal
6
+ class Settings < Methods::Post
7
+ ENDPOINT = '/personal/corp/settings'.freeze
8
+
9
+ def pathname
10
+ ENDPOINT
11
+ end
12
+
13
+ private
14
+
15
+ def define_resources(attributes)
16
+ Resources::Personal::Settings.new(attributes)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,34 @@
1
+ require 'monobank/methods/get'
2
+ require 'monobank/resources/personal/statement'
3
+
4
+ module Monobank
5
+ module Personal
6
+ class Statement < Methods::Get
7
+ ENDPOINT = '/personal/statement'.freeze
8
+
9
+ def initialize(account_id:, from:, to:, **rest)
10
+ super(**rest)
11
+
12
+ @account_id = account_id
13
+ @from = from
14
+ @to = to
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :account_id, :from, :to
20
+
21
+ def pathname
22
+ path = "#{ENDPOINT}/#{account_id}/#{from}"
23
+ path = "#{path}/#{to}" if to
24
+ path
25
+ end
26
+
27
+ def define_resources(attributes)
28
+ attributes.map do |attrs|
29
+ Monobank::Resources::Personal::Statement.new(attrs)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,32 @@
1
+ require 'monobank/methods/post'
2
+ require 'monobank/resources/personal/webhook'
3
+
4
+ module Monobank
5
+ module Personal
6
+ class Webhook < Methods::Post
7
+ ENDPOINT = '/personal/webhook'.freeze
8
+
9
+ def initialize(url:, **rest)
10
+ super(**rest)
11
+
12
+ @url = url
13
+ end
14
+
15
+ private
16
+
17
+ attr_reader :url
18
+
19
+ def pathname
20
+ ENDPOINT
21
+ end
22
+
23
+ def body
24
+ { webHookUrl: url }
25
+ end
26
+
27
+ def define_resources(attributes)
28
+ Monobank::Resources::Personal::Webhook.new(attributes)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,11 @@
1
+ require 'monobank/resources/base'
2
+
3
+ module Monobank
4
+ module Resources
5
+ module Bank
6
+ class Currency < Base
7
+ define_fields %w[currency_code_a currency_code_b date rate_sell rate_buy rate_cross]
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,35 @@
1
+ module Monobank
2
+ module Resources
3
+ class Base
4
+ def self.define_fields(attributes)
5
+ attributes.each do |attribute|
6
+ define_method(attribute) { instance_variable_get("@attributes")[attribute] }
7
+ end
8
+ end
9
+
10
+ def initialize(attributes)
11
+ @attributes = deep_snake_case(attributes)
12
+ end
13
+
14
+ def method_name(key)
15
+ key.gsub(/(.)([A-Z])/,'\1_\2').downcase
16
+ end
17
+
18
+ def deep_snake_case(object)
19
+ if object.is_a?(Hash)
20
+ object.map do |key, value|
21
+ [method_name(key), deep_snake_case(value)]
22
+ end.to_h
23
+ elsif object.is_a?(Array)
24
+ object.map do |value|
25
+ deep_snake_case(value)
26
+ end
27
+ else
28
+ object
29
+ end
30
+ end
31
+
32
+ attr_reader :attributes
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,9 @@
1
+ require 'monobank/resources/base'
2
+
3
+ module Monobank
4
+ module Resources
5
+ class Error < Base
6
+ define_fields %w[error_description code]
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ require 'monobank/resources/base'
2
+
3
+ module Monobank
4
+ module Resources
5
+ module Personal
6
+ class Accounts < Base
7
+ define_fields %w[id type balance credit_limit currency_code cashback_type]
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require 'monobank/resources/base'
2
+
3
+ module Monobank
4
+ module Resources
5
+ module Personal
6
+ class AuthCheck < Base
7
+ define_fields %w[status]
8
+ end
9
+ end
10
+ end
11
+ end