monobank-lotarc 1.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.
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