fintecture 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +18 -17
  3. data/.rspec +3 -3
  4. data/.travis.yml +7 -7
  5. data/CODE_OF_CONDUCT.md +74 -74
  6. data/Gemfile +8 -8
  7. data/Gemfile.lock +59 -59
  8. data/LICENSE.txt +674 -674
  9. data/README.md +405 -408
  10. data/Rakefile +8 -8
  11. data/bin/console +15 -15
  12. data/bin/setup +8 -8
  13. data/exemples/ais.rb +53 -53
  14. data/exemples/config_ais.json +7 -7
  15. data/exemples/config_pis.json +5 -5
  16. data/exemples/pis.rb +148 -148
  17. data/exemples/ressources.rb +23 -23
  18. data/fintecture.gemspec +44 -44
  19. data/lib/fintecture/ais_client.rb +94 -94
  20. data/lib/fintecture/api/ais/account_holders.rb +61 -61
  21. data/lib/fintecture/api/ais/accounts.rb +63 -63
  22. data/lib/fintecture/api/ais/authorize.rb +72 -72
  23. data/lib/fintecture/api/ais/authorize_decoupled.rb +68 -68
  24. data/lib/fintecture/api/ais/connect.rb +65 -65
  25. data/lib/fintecture/api/ais/delete_customer.rb +53 -53
  26. data/lib/fintecture/api/ais/transactions.rb +64 -64
  27. data/lib/fintecture/api/auth/authentication.rb +78 -78
  28. data/lib/fintecture/api/pis/connect.rb +84 -77
  29. data/lib/fintecture/api/pis/initiate.rb +52 -52
  30. data/lib/fintecture/api/pis/payments.rb +54 -48
  31. data/lib/fintecture/api/pis/refund.rb +67 -67
  32. data/lib/fintecture/api/pis/request_to_pay.rb +63 -63
  33. data/lib/fintecture/api/pis/settlements.rb +50 -50
  34. data/lib/fintecture/api/ressources/applications.rb +57 -57
  35. data/lib/fintecture/api/ressources/providers.rb +61 -61
  36. data/lib/fintecture/api/ressources/test_accounts.rb +60 -60
  37. data/lib/fintecture/base_url.rb +26 -26
  38. data/lib/fintecture/endpoints/ais.rb +17 -17
  39. data/lib/fintecture/endpoints/authentication.rb +13 -13
  40. data/lib/fintecture/endpoints/pis.rb +16 -16
  41. data/lib/fintecture/endpoints/ressources.rb +13 -13
  42. data/lib/fintecture/exceptions.rb +48 -48
  43. data/lib/fintecture/faraday/authentication/connection.rb +140 -140
  44. data/lib/fintecture/pis_client.rb +100 -100
  45. data/lib/fintecture/utils/constants.rb +11 -11
  46. data/lib/fintecture/utils/crypto.rb +75 -75
  47. data/lib/fintecture/utils/date.rb +15 -15
  48. data/lib/fintecture/utils/validation.rb +32 -32
  49. data/lib/fintecture/version.rb +5 -5
  50. data/lib/fintecture.rb +65 -65
  51. metadata +12 -6
@@ -1,48 +1,48 @@
1
- # frozen_string_literal: true
2
-
3
- require 'json'
4
-
5
- module Fintecture
6
- class ValidationException < RuntimeError; end
7
-
8
- class CryptoException < RuntimeError; end
9
-
10
- class ApiException
11
- class << self
12
- def error(res)
13
- body = JSON.parse res.body
14
-
15
- raise construct_message_errors(res.status, body)
16
- end
17
-
18
- private
19
-
20
- def construct_message_errors(status, body)
21
- code = body['code'].presence
22
- log_id = body['log_id'].presence
23
- errors_array = body['errors'].presence || body['meta'].presence || []
24
-
25
- error_string = "\nFintecture server errors : "
26
- error_string += "\n status: #{status} " if status
27
- error_string += "\n code: #{code}" if code
28
- error_string += "\n id : #{log_id}" if log_id
29
-
30
- errors_array.compact!
31
- errors_array.each do |error|
32
- formated_error = error
33
- formated_error = error.map { |key, value| " #{key}: #{value}" }.join("\n") if error.is_a?(Hash)
34
- error_string += "\n\n#{formated_error}"
35
- end
36
-
37
- error_string += "\n\n"
38
-
39
- {
40
- type: 'Fintecture api',
41
- status: status,
42
- errors: errors_array,
43
- error_string: error_string
44
- }.to_json
45
- end
46
- end
47
- end
48
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Fintecture
6
+ class ValidationException < RuntimeError; end
7
+
8
+ class CryptoException < RuntimeError; end
9
+
10
+ class ApiException
11
+ class << self
12
+ def error(res)
13
+ body = JSON.parse res.body
14
+
15
+ raise construct_message_errors(res.status, body)
16
+ end
17
+
18
+ private
19
+
20
+ def construct_message_errors(status, body)
21
+ code = body['code'].presence
22
+ log_id = body['log_id'].presence
23
+ errors_array = body['errors'].presence || body['meta'].presence || []
24
+
25
+ error_string = "\nFintecture server errors : "
26
+ error_string += "\n status: #{status} " if status
27
+ error_string += "\n code: #{code}" if code
28
+ error_string += "\n id : #{log_id}" if log_id
29
+
30
+ errors_array.compact!
31
+ errors_array.each do |error|
32
+ formated_error = error
33
+ formated_error = error.map { |key, value| " #{key}: #{value}" }.join("\n") if error.is_a?(Hash)
34
+ error_string += "\n\n#{formated_error}"
35
+ end
36
+
37
+ error_string += "\n\n"
38
+
39
+ {
40
+ type: 'Fintecture api',
41
+ status: status,
42
+ errors: errors_array,
43
+ error_string: error_string
44
+ }.to_json
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,140 +1,140 @@
1
- # frozen_string_literal: true
2
-
3
- require 'base64'
4
- require 'faraday'
5
- require 'uri'
6
- require 'fintecture/utils/crypto'
7
- require 'fintecture/utils/date'
8
-
9
- module Fintecture
10
- module Faraday
11
- module Authentication
12
- class Connection
13
- class << self
14
- def connection(url)
15
- ::Faraday.new(url: url) do |faraday|
16
- faraday.request :url_encoded
17
- faraday.adapter ::Faraday.default_adapter
18
- end
19
- end
20
-
21
- def post(url:, req_body: nil, client: nil, custom_content_type: nil, bearer: nil, secure_headers: false, additional_headers: nil, disableAuthorization: nil)
22
- @client = client
23
- conn = connection(url)
24
- res = conn.post do |req|
25
- req.options.params_encoder = Faraday::DisabledEncoder
26
- req.headers = req_headers(custom_content_type, bearer, secure_headers, additional_headers, disableAuthorization,
27
- method: 'post', body: req_body, url: url)
28
- req.body = req_body
29
- end
30
-
31
- !res.success? ? Fintecture::ApiException.error(res) : res
32
- end
33
-
34
- def get(url:, req_body: nil, client: nil, custom_content_type: nil, bearer: nil, secure_headers: false, additional_headers: nil, disableAuthorization: nil)
35
- @client = client
36
- conn = connection(url)
37
-
38
- res = conn.get do |req|
39
- req.options.params_encoder = Faraday::DisabledEncoder
40
- req.headers = req_headers(custom_content_type, bearer, secure_headers, additional_headers, disableAuthorization,
41
- method: 'get', url: url)
42
- req.body = req_body
43
- end
44
-
45
- !res.success? ? Fintecture::ApiException.error(res) : res
46
- end
47
-
48
- def delete(url:, req_body: nil, client: nil, custom_content_type: nil, bearer: nil, secure_headers: false, additional_headers: nil, disableAuthorization: nil)
49
- @client = client
50
- conn = connection(url)
51
-
52
- res = conn.delete do |req|
53
- req.options.params_encoder = Faraday::DisabledEncoder
54
- req.headers = req_headers(custom_content_type, bearer, secure_headers, additional_headers, disableAuthorization,
55
- method: 'delete', body: req_body, url: url)
56
- req.body = req_body
57
- end
58
-
59
- !res.success? ? Fintecture::ApiException.error(res) : res
60
- end
61
-
62
- def req_headers(custom_content_type, bearer, secure_headers, additional_headers, disableAuthorization, url:, method: '', body: {})
63
- if !additional_headers.nil? && !additional_headers.is_a?(Hash)
64
- raise Fintecture::ValidationException, 'additional_headers must be an object'
65
- end
66
-
67
- client_token = Base64.strict_encode64("#{@client.app_id}:#{@client.app_secret}")
68
-
69
- headers = {
70
- 'Accept' => 'application/json',
71
- 'User-Agent' => "Fintecture Ruby SDK v #{Fintecture::VERSION}",
72
- 'Content-Type' => custom_content_type || 'application/x-www-form-urlencoded'
73
- }
74
- headers['Authorization'] = bearer || "Basic #{client_token}" unless disableAuthorization
75
- headers = headers.merge(additional_headers) unless additional_headers.nil?
76
- headers.merge(secure_headers ? req_secure_headers(body: body, url: url, method: method) : {})
77
- end
78
-
79
- def req_secure_headers(body: {}, url: '', method: '')
80
- payload = (body.instance_of?(String) ? body : body.to_s)
81
- path_name = URI(url).path
82
- search_params = URI(url).query
83
-
84
- request_target = search_params ? "#{method.downcase} #{path_name}?#{search_params}" : "#{method.downcase} #{path_name}"
85
- date = Fintecture::Utils::Date.header_time.to_s
86
- digest = load_digest(payload)
87
- x_request_id = Fintecture::Utils::Crypto.generate_uuid
88
-
89
- headers = {
90
- 'Date' => date,
91
- 'X-Request-ID' => x_request_id
92
- }.merge(payload ? digest : {})
93
-
94
- headers['Signature'] =
95
- Fintecture::Utils::Crypto.create_signature_header(
96
- { '(request-target)' => request_target }.merge(headers), @client
97
- )
98
- headers
99
- end
100
-
101
- def load_digest(payload)
102
- { 'Digest' => "SHA-256=#{Fintecture::Utils::Crypto.hash_base64(payload)}" }
103
- end
104
-
105
- end
106
- end
107
- end
108
-
109
- module DisabledEncoder
110
- class << self
111
- extend Forwardable
112
- def_delegators :'Faraday::Utils', :escape, :unescape
113
- end
114
-
115
- def self.encode(params)
116
- return nil if params.nil?
117
-
118
- newParams = {}
119
- params.each do |key, value|
120
- if value.instance_of?(Hash)
121
- value.each do |subkey, subvalue|
122
- newParams["#{key}[#{subkey}]"] = subvalue
123
- end
124
- else
125
- newParams[key] = value
126
- end
127
- end
128
-
129
- newParams.map { |key, value| "#{key}=#{value}" }.join('&').to_s
130
- end
131
-
132
- class << self
133
- attr_accessor :sort_params
134
- end
135
-
136
- # Useful default for OAuth and caching.
137
- @sort_params = true
138
- end
139
- end
140
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'base64'
4
+ require 'faraday'
5
+ require 'uri'
6
+ require 'fintecture/utils/crypto'
7
+ require 'fintecture/utils/date'
8
+
9
+ module Fintecture
10
+ module Faraday
11
+ module Authentication
12
+ class Connection
13
+ class << self
14
+ def connection(url)
15
+ ::Faraday.new(url: url) do |faraday|
16
+ faraday.request :url_encoded
17
+ faraday.adapter ::Faraday.default_adapter
18
+ end
19
+ end
20
+
21
+ def post(url:, req_body: nil, client: nil, custom_content_type: nil, bearer: nil, secure_headers: false, additional_headers: nil, disableAuthorization: nil)
22
+ @client = client
23
+ conn = connection(url)
24
+ res = conn.post do |req|
25
+ req.options.params_encoder = Faraday::DisabledEncoder
26
+ req.headers = req_headers(custom_content_type, bearer, secure_headers, additional_headers, disableAuthorization,
27
+ method: 'post', body: req_body, url: url)
28
+ req.body = req_body
29
+ end
30
+
31
+ !res.success? ? Fintecture::ApiException.error(res) : res
32
+ end
33
+
34
+ def get(url:, req_body: nil, client: nil, custom_content_type: nil, bearer: nil, secure_headers: false, additional_headers: nil, disableAuthorization: nil)
35
+ @client = client
36
+ conn = connection(url)
37
+
38
+ res = conn.get do |req|
39
+ req.options.params_encoder = Faraday::DisabledEncoder
40
+ req.headers = req_headers(custom_content_type, bearer, secure_headers, additional_headers, disableAuthorization,
41
+ method: 'get', url: url)
42
+ req.body = req_body
43
+ end
44
+
45
+ !res.success? ? Fintecture::ApiException.error(res) : res
46
+ end
47
+
48
+ def delete(url:, req_body: nil, client: nil, custom_content_type: nil, bearer: nil, secure_headers: false, additional_headers: nil, disableAuthorization: nil)
49
+ @client = client
50
+ conn = connection(url)
51
+
52
+ res = conn.delete do |req|
53
+ req.options.params_encoder = Faraday::DisabledEncoder
54
+ req.headers = req_headers(custom_content_type, bearer, secure_headers, additional_headers, disableAuthorization,
55
+ method: 'delete', body: req_body, url: url)
56
+ req.body = req_body
57
+ end
58
+
59
+ !res.success? ? Fintecture::ApiException.error(res) : res
60
+ end
61
+
62
+ def req_headers(custom_content_type, bearer, secure_headers, additional_headers, disableAuthorization, url:, method: '', body: {})
63
+ if !additional_headers.nil? && !additional_headers.is_a?(Hash)
64
+ raise Fintecture::ValidationException, 'additional_headers must be an object'
65
+ end
66
+
67
+ client_token = Base64.strict_encode64("#{@client.app_id}:#{@client.app_secret}")
68
+
69
+ headers = {
70
+ 'Accept' => 'application/json',
71
+ 'User-Agent' => "Fintecture Ruby SDK v #{Fintecture::VERSION}",
72
+ 'Content-Type' => custom_content_type || 'application/x-www-form-urlencoded'
73
+ }
74
+ headers['Authorization'] = bearer || "Basic #{client_token}" unless disableAuthorization
75
+ headers = headers.merge(additional_headers) unless additional_headers.nil?
76
+ headers.merge(secure_headers ? req_secure_headers(body: body, url: url, method: method) : {})
77
+ end
78
+
79
+ def req_secure_headers(body: {}, url: '', method: '')
80
+ payload = (body.instance_of?(String) ? body : body.to_s)
81
+ path_name = URI(url).path
82
+ search_params = URI(url).query
83
+
84
+ request_target = search_params ? "#{method.downcase} #{path_name}?#{search_params}" : "#{method.downcase} #{path_name}"
85
+ date = Fintecture::Utils::Date.header_time.to_s
86
+ digest = load_digest(payload)
87
+ x_request_id = Fintecture::Utils::Crypto.generate_uuid
88
+
89
+ headers = {
90
+ 'Date' => date,
91
+ 'X-Request-ID' => x_request_id
92
+ }.merge(payload ? digest : {})
93
+
94
+ headers['Signature'] =
95
+ Fintecture::Utils::Crypto.create_signature_header(
96
+ { '(request-target)' => request_target }.merge(headers), @client
97
+ )
98
+ headers
99
+ end
100
+
101
+ def load_digest(payload)
102
+ { 'Digest' => "SHA-256=#{Fintecture::Utils::Crypto.hash_base64(payload)}" }
103
+ end
104
+
105
+ end
106
+ end
107
+ end
108
+
109
+ module DisabledEncoder
110
+ class << self
111
+ extend Forwardable
112
+ def_delegators :'Faraday::Utils', :escape, :unescape
113
+ end
114
+
115
+ def self.encode(params)
116
+ return nil if params.nil?
117
+
118
+ newParams = {}
119
+ params.each do |key, value|
120
+ if value.instance_of?(Hash)
121
+ value.each do |subkey, subvalue|
122
+ newParams["#{key}[#{subkey}]"] = subvalue
123
+ end
124
+ else
125
+ newParams[key] = value
126
+ end
127
+ end
128
+
129
+ newParams.map { |key, value| "#{key}=#{value}" }.join('&').to_s
130
+ end
131
+
132
+ class << self
133
+ attr_accessor :sort_params
134
+ end
135
+
136
+ # Useful default for OAuth and caching.
137
+ @sort_params = true
138
+ end
139
+ end
140
+ end
@@ -1,100 +1,100 @@
1
- # frozen_string_literal: true
2
-
3
- require 'fintecture/api/pis/connect'
4
- require 'fintecture/api/pis/request_to_pay'
5
- require 'fintecture/api/pis/payments'
6
- require 'fintecture/api/pis/initiate'
7
- require 'fintecture/api/pis/refund'
8
- require 'fintecture/api/pis/settlements'
9
-
10
- require 'fintecture/api/ressources/providers'
11
- require 'fintecture/api/ressources/applications'
12
- require 'fintecture/api/ressources/test_accounts'
13
-
14
- module Fintecture
15
- class PisClient
16
- @environment = %w[local test sandbox production].freeze
17
-
18
- def initialize(config)
19
- @app_id = config[:app_id]
20
- @app_secret = config[:app_secret]
21
- @private_key = config[:private_key]
22
-
23
- environment = config[:environment].downcase
24
- unless environment.include?(environment)
25
- raise "#{environment} not a valid environment, options are [#{environment.join(', ')}]"
26
- end
27
-
28
- @environment = config[:environment]
29
- end
30
-
31
- # Getters
32
- attr_reader :app_id, :app_secret, :private_key, :environment, :token, :token_expires_in
33
-
34
- # Methodes
35
- def generate_token
36
- res = Fintecture::Authentication.get_access_token self
37
- body = JSON.parse res.body
38
-
39
- @token = body['access_token']
40
- @token_expires_in = body['expires_in']
41
-
42
- body
43
- end
44
-
45
- def connect(payload, state, redirect_uri = nil, origin_uri = nil)
46
- res = Fintecture::Pis::Connect.generate self, Marshal.load(Marshal.dump(payload)), state, redirect_uri, origin_uri
47
-
48
- JSON.parse res.body
49
- end
50
-
51
- def request_to_pay(payload, x_language, redirect_uri = nil)
52
- res = Fintecture::Pis::RequestToPay.generate self, Marshal.load(Marshal.dump(payload)), x_language, redirect_uri
53
-
54
- JSON.parse res.body
55
- end
56
-
57
- def initiate(payload, provider_id, redirect_uri, state = nil)
58
- res = Fintecture::Pis::Initiate.generate self, Marshal.load(Marshal.dump(payload)), provider_id, redirect_uri,
59
- state
60
-
61
- JSON.parse res.body
62
- end
63
-
64
- def payments(session_id = nil)
65
- res = Fintecture::Pis::Payments.get self, session_id
66
-
67
- JSON.parse res.body
68
- end
69
-
70
- def refund(session_id, amount = nil, user_id = nil)
71
- res = Fintecture::Pis::Refund.generate self, session_id, amount, user_id
72
-
73
- JSON.parse res.body
74
- end
75
-
76
- def settlements(settlement_id = nil, include_payments = false)
77
- res = Fintecture::Pis::Settlements.get self, settlement_id, include_payments
78
-
79
- JSON.parse res.body
80
- end
81
-
82
- def providers(provider_id: nil, paramsProviders: nil)
83
- res = Fintecture::Ressources::Providers.get self, provider_id, paramsProviders
84
-
85
- JSON.parse res.body
86
- end
87
-
88
- def applications
89
- res = Fintecture::Ressources::Applications.get self
90
-
91
- JSON.parse res.body
92
- end
93
-
94
- def test_accounts(provider_id = nil)
95
- res = Fintecture::Ressources::TestAccounts.get self, provider_id
96
-
97
- JSON.parse res.body
98
- end
99
- end
100
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'fintecture/api/pis/connect'
4
+ require 'fintecture/api/pis/request_to_pay'
5
+ require 'fintecture/api/pis/payments'
6
+ require 'fintecture/api/pis/initiate'
7
+ require 'fintecture/api/pis/refund'
8
+ require 'fintecture/api/pis/settlements'
9
+
10
+ require 'fintecture/api/ressources/providers'
11
+ require 'fintecture/api/ressources/applications'
12
+ require 'fintecture/api/ressources/test_accounts'
13
+
14
+ module Fintecture
15
+ class PisClient
16
+ @environment = %w[local test sandbox production].freeze
17
+
18
+ def initialize(config)
19
+ @app_id = config[:app_id]
20
+ @app_secret = config[:app_secret]
21
+ @private_key = config[:private_key]
22
+
23
+ environment = config[:environment].downcase
24
+ unless environment.include?(environment)
25
+ raise "#{environment} not a valid environment, options are [#{environment.join(', ')}]"
26
+ end
27
+
28
+ @environment = config[:environment]
29
+ end
30
+
31
+ # Getters
32
+ attr_reader :app_id, :app_secret, :private_key, :environment, :token, :token_expires_in
33
+
34
+ # Methodes
35
+ def generate_token
36
+ res = Fintecture::Authentication.get_access_token self
37
+ body = JSON.parse res.body
38
+
39
+ @token = body['access_token']
40
+ @token_expires_in = body['expires_in']
41
+
42
+ body
43
+ end
44
+
45
+ def connect(payload, state, redirect_uri = nil, origin_uri = nil, **options)
46
+ res = Fintecture::Pis::Connect.generate self, Marshal.load(Marshal.dump(payload)), state, redirect_uri, origin_uri, options
47
+
48
+ JSON.parse res.body
49
+ end
50
+
51
+ def request_to_pay(payload, x_language, redirect_uri = nil)
52
+ res = Fintecture::Pis::RequestToPay.generate self, Marshal.load(Marshal.dump(payload)), x_language, redirect_uri
53
+
54
+ JSON.parse res.body
55
+ end
56
+
57
+ def initiate(payload, provider_id, redirect_uri, state = nil)
58
+ res = Fintecture::Pis::Initiate.generate self, Marshal.load(Marshal.dump(payload)), provider_id, redirect_uri,
59
+ state
60
+
61
+ JSON.parse res.body
62
+ end
63
+
64
+ def payments(session_id = nil, **options)
65
+ res = Fintecture::Pis::Payments.get self, session_id, options
66
+
67
+ JSON.parse res.body
68
+ end
69
+
70
+ def refund(session_id, amount = nil, user_id = nil)
71
+ res = Fintecture::Pis::Refund.generate self, session_id, amount, user_id
72
+
73
+ JSON.parse res.body
74
+ end
75
+
76
+ def settlements(settlement_id = nil, include_payments = false)
77
+ res = Fintecture::Pis::Settlements.get self, settlement_id, include_payments
78
+
79
+ JSON.parse res.body
80
+ end
81
+
82
+ def providers(provider_id: nil, paramsProviders: nil)
83
+ res = Fintecture::Ressources::Providers.get self, provider_id, paramsProviders
84
+
85
+ JSON.parse res.body
86
+ end
87
+
88
+ def applications
89
+ res = Fintecture::Ressources::Applications.get self
90
+
91
+ JSON.parse res.body
92
+ end
93
+
94
+ def test_accounts(provider_id = nil)
95
+ res = Fintecture::Ressources::TestAccounts.get self, provider_id
96
+
97
+ JSON.parse res.body
98
+ end
99
+ end
100
+ end
@@ -1,11 +1,11 @@
1
- # frozen_string_literal: true
2
-
3
- module Fintecture
4
- module Utils
5
- module Constants
6
- SIGNEDHEADERPARAMETERLIST = %w[(request-target) Date Digest X-Request-ID].freeze
7
- PSU_TYPES = %w[retail corporate all].freeze
8
- SCOPES = %w[pis ais].freeze
9
- end
10
- end
11
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Fintecture
4
+ module Utils
5
+ module Constants
6
+ SIGNEDHEADERPARAMETERLIST = %w[(request-target) Date Digest X-Request-ID].freeze
7
+ PSU_TYPES = %w[retail corporate all].freeze
8
+ SCOPES = %w[pis ais].freeze
9
+ end
10
+ end
11
+ end