fintecture 0.2.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +17 -19
  3. data/.rspec +3 -3
  4. data/.travis.yml +7 -7
  5. data/CODE_OF_CONDUCT.md +74 -74
  6. data/Gemfile +8 -6
  7. data/Gemfile.lock +59 -59
  8. data/LICENSE.txt +674 -674
  9. data/README.md +407 -238
  10. data/Rakefile +8 -6
  11. data/bin/console +15 -14
  12. data/bin/setup +8 -8
  13. data/exemples/ais.rb +53 -0
  14. data/exemples/config_ais.json +8 -0
  15. data/exemples/config_pis.json +6 -0
  16. data/exemples/pis.rb +148 -0
  17. data/exemples/ressources.rb +23 -0
  18. data/fintecture.gemspec +44 -43
  19. data/lib/fintecture/ais_client.rb +94 -0
  20. data/lib/fintecture/api/ais/account_holders.rb +61 -0
  21. data/lib/fintecture/api/ais/accounts.rb +63 -0
  22. data/lib/fintecture/api/ais/authorize.rb +72 -0
  23. data/lib/fintecture/api/ais/authorize_decoupled.rb +68 -0
  24. data/lib/fintecture/api/ais/connect.rb +65 -0
  25. data/lib/fintecture/api/ais/delete_customer.rb +53 -0
  26. data/lib/fintecture/api/ais/transactions.rb +64 -0
  27. data/lib/fintecture/{authentication.rb → api/auth/authentication.rb} +78 -76
  28. data/lib/fintecture/api/pis/connect.rb +77 -0
  29. data/lib/fintecture/api/pis/initiate.rb +52 -0
  30. data/lib/fintecture/api/pis/payments.rb +48 -0
  31. data/lib/fintecture/api/pis/refund.rb +67 -0
  32. data/lib/fintecture/api/pis/request_to_pay.rb +63 -0
  33. data/lib/fintecture/api/pis/settlements.rb +50 -0
  34. data/lib/fintecture/api/ressources/applications.rb +57 -0
  35. data/lib/fintecture/api/ressources/providers.rb +61 -0
  36. data/lib/fintecture/api/ressources/test_accounts.rb +60 -0
  37. data/lib/fintecture/base_url.rb +26 -0
  38. data/lib/fintecture/endpoints/ais.rb +17 -0
  39. data/lib/fintecture/{api/endpoints → endpoints}/authentication.rb +13 -13
  40. data/lib/fintecture/endpoints/pis.rb +16 -0
  41. data/lib/fintecture/endpoints/ressources.rb +13 -0
  42. data/lib/fintecture/exceptions.rb +72 -33
  43. data/lib/fintecture/faraday/authentication/connection.rb +140 -120
  44. data/lib/fintecture/pis_client.rb +100 -0
  45. data/lib/fintecture/utils/constants.rb +11 -14
  46. data/lib/fintecture/utils/crypto.rb +75 -78
  47. data/lib/fintecture/utils/date.rb +15 -15
  48. data/lib/fintecture/utils/validation.rb +32 -26
  49. data/lib/fintecture/version.rb +5 -3
  50. data/lib/fintecture.rb +65 -82
  51. metadata +35 -12
  52. data/lib/fintecture/api/base_url.rb +0 -29
  53. data/lib/fintecture/api/endpoints/pis.rb +0 -14
  54. data/lib/fintecture/connect.rb +0 -38
  55. data/lib/fintecture/pis.rb +0 -262
@@ -1,120 +1,140 @@
1
- require 'base64'
2
- require 'faraday'
3
- require 'uri'
4
- require 'fintecture/utils/crypto'
5
- require 'fintecture/utils/date'
6
-
7
- module Fintecture
8
- module Faraday
9
- module Authentication
10
- class Connection
11
- class << self
12
-
13
- def connection(url)
14
- ::Faraday.new(url: url) do |faraday|
15
- faraday.request :url_encoded
16
- faraday.adapter ::Faraday.default_adapter
17
- end
18
- end
19
-
20
- def post(url:, req_body: nil, custom_content_type: nil, bearer: nil, secure_headers: false, additional_headers: nil)
21
- conn = connection(url)
22
-
23
- res = conn.post do |req|
24
- req.options.params_encoder = Faraday::DisabledEncoder
25
- req.headers = req_headers(custom_content_type, bearer, secure_headers, additional_headers, method: 'post', body: req_body, url: url)
26
- req.body = req_body
27
- end
28
-
29
- !res.success? ? Fintecture::ApiException.error(res) : res
30
- end
31
-
32
- def get(url:, req_body: nil, custom_content_type: nil, bearer: nil, secure_headers: false, additional_headers: nil)
33
- conn = connection(url)
34
-
35
- res = conn.get do |req|
36
- req.options.params_encoder = Faraday::DisabledEncoder
37
- req.headers = req_headers(custom_content_type, bearer, secure_headers, additional_headers, method: 'get', url: url)
38
- req.body = req_body
39
- end
40
-
41
- !res.success? ? Fintecture::ApiException.error(res) : res
42
- end
43
-
44
- def req_headers(custom_content_type, bearer, secure_headers, additional_headers, method: '', body: {}, url:)
45
-
46
- client_token = Base64.strict_encode64("#{Fintecture.app_id}:#{Fintecture.app_secret}")
47
-
48
- {
49
- 'Accept' => 'application/json',
50
- 'User-Agent' => "Fintecture Ruby SDK v #{Fintecture::VERSION}",
51
- 'Authorization' => bearer ? bearer : "Basic #{client_token}",
52
- 'Content-Type' => custom_content_type ? custom_content_type : 'application/x-www-form-urlencoded',
53
- }.merge(secure_headers ? req_secure_headers(additional_headers, body: body, url: url, method: method) : {})
54
-
55
- end
56
-
57
- def req_secure_headers(additional_headers, body: {}, url: '', method: '')
58
- raise Fintecture::ValidationException.new('additional_headers must be an object') if additional_headers != nil && !additional_headers.is_a?(Hash)
59
-
60
- payload = ( body.class.name == 'String' ? body : body.to_s )
61
- path_name = URI(url).path
62
- search_params = URI(url).query
63
-
64
-
65
- request_target = search_params ? "#{method.downcase} #{path_name}?#{search_params}" : "#{method.downcase} #{path_name}"
66
- date = Fintecture::Utils::Date.header_time.to_s
67
- digest = load_digest(payload)
68
- x_request_id = Fintecture::Utils::Crypto.generate_uuid
69
-
70
-
71
- headers = {
72
- 'Date' => date,
73
- 'X-Request-ID' => x_request_id
74
- }.merge(payload ? digest : {})
75
-
76
- # Add additional_headers if exists
77
- headers = headers.merge(additional_headers) if additional_headers != nil
78
-
79
-
80
- headers['Signature'] = Fintecture::Utils::Crypto.create_signature_header({'(request-target)' => request_target}.merge(headers))
81
- headers
82
- end
83
-
84
- def load_digest(payload)
85
- {'Digest' => "SHA-256=#{Fintecture::Utils::Crypto.hash_base64(payload)}"}
86
- end
87
-
88
- end
89
- end
90
- end
91
-
92
-
93
- module DisabledEncoder
94
- class << self
95
- extend Forwardable
96
- def_delegators :'Faraday::Utils', :escape, :unescape
97
- end
98
-
99
-
100
- def self.encode(params)
101
- return nil if params.nil?
102
-
103
- query_string = "#{params.map{|key, value| "#{key}=#{value}"}.join('&')}"
104
-
105
- end
106
-
107
-
108
-
109
- class << self
110
- attr_accessor :sort_params
111
- end
112
-
113
- # Useful default for OAuth and caching.
114
- @sort_params = true
115
- end
116
- end
117
- end
118
-
119
-
120
-
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
@@ -0,0 +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)
71
+ res = Fintecture::Pis::Refund.generate self, session_id, amount
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,14 +1,11 @@
1
-
2
-
3
-
4
- module Fintecture
5
- module Utils
6
- module Constants
7
-
8
- SIGNEDHEADERPARAMETERLIST = %w[(request-target) Date Digest X-Request-ID];
9
- PSU_TYPES = %w[retail corporate all]
10
- SCOPES = %w[pis ais]
11
-
12
- end
13
- end
14
- 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
@@ -1,78 +1,75 @@
1
- require 'securerandom'
2
- require 'openssl'
3
- require 'base64'
4
- require 'json'
5
- require 'fintecture/exceptions'
6
- require 'fintecture/utils/constants'
7
- require 'uri'
8
-
9
- module Fintecture
10
- module Utils
11
- class Crypto
12
- class << self
13
-
14
- def generate_uuid
15
- SecureRandom.uuid
16
- end
17
-
18
- def generate_uuid_only_chars
19
- generate_uuid.gsub!('-','')
20
- end
21
-
22
- def sign_payload(payload)
23
- payload = payload.to_json.to_s if payload.is_a? Hash
24
- digest = OpenSSL::Digest::SHA256.new
25
- private_key = OpenSSL::PKey::RSA.new(Fintecture.private_key)
26
-
27
- begin
28
- signature = private_key.sign(digest, payload)
29
- Base64.strict_encode64(signature)
30
- rescue
31
- raise Fintecture::CryptoException.new('error during signature')
32
- end
33
- end
34
-
35
- def decrypt_private(digest)
36
- digest = URI.unescape digest
37
- encrypted_string = Base64.decode64(digest)
38
- private_key = OpenSSL::PKey::RSA.new(Fintecture.private_key)
39
-
40
- begin
41
- private_key.private_decrypt(encrypted_string, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
42
- rescue OpenSSL::PKey::RSAError => e
43
- raise Fintecture::CryptoException.new("error while decrypt, #{e.message}")
44
- rescue
45
- raise Fintecture::CryptoException.new('error during decryption')
46
- end
47
- end
48
-
49
- def hash_base64(plain_text)
50
- digest = Digest::SHA256.digest plain_text
51
- Base64.strict_encode64(digest)
52
- end
53
-
54
- def create_signature_header(headers)
55
- signing = []
56
- header = []
57
-
58
-
59
-
60
- Fintecture::Utils::Constants::SIGNEDHEADERPARAMETERLIST.each do |param|
61
- next unless headers[param]
62
-
63
- param_low = param.downcase
64
- signing << "#{param_low}: #{headers[param]}"
65
- header << param_low
66
- end
67
-
68
-
69
- # Double quote in join needed. If not we will get two slashes \\n
70
- signature = sign_payload signing.join("\n")
71
- 'keyId="' + Fintecture.app_id + '",algorithm="rsa-sha256",headers="' + header.join(' ') + '",signature="' + signature + '"'
72
-
73
- end
74
-
75
- end
76
- end
77
- end
78
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+ require 'openssl'
5
+ require 'base64'
6
+ require 'json'
7
+ require 'fintecture/exceptions'
8
+ require 'fintecture/utils/constants'
9
+ require 'uri'
10
+
11
+ module Fintecture
12
+ module Utils
13
+ class Crypto
14
+ class << self
15
+ def generate_uuid
16
+ SecureRandom.uuid
17
+ end
18
+
19
+ def generate_uuid_only_chars
20
+ generate_uuid.gsub!('-', '')
21
+ end
22
+
23
+ def sign_payload(payload)
24
+ payload = payload.to_json.to_s if payload.is_a? Hash
25
+ digest = OpenSSL::Digest.new('SHA256')
26
+ private_key = OpenSSL::PKey::RSA.new(@client.private_key)
27
+
28
+ begin
29
+ signature = private_key.sign(digest, payload)
30
+ Base64.strict_encode64(signature)
31
+ rescue StandardError
32
+ raise Fintecture::CryptoException, 'error during signature'
33
+ end
34
+ end
35
+
36
+ def decrypt_private(digest)
37
+ digest = URI.unescape digest
38
+ encrypted_string = Base64.decode64(digest)
39
+ private_key = OpenSSL::PKey::RSA.new(@client.private_key)
40
+
41
+ begin
42
+ private_key.private_decrypt(encrypted_string, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
43
+ rescue OpenSSL::PKey::RSAError => e
44
+ raise Fintecture::CryptoException, "error while decrypt, #{e.message}"
45
+ rescue StandardError
46
+ raise Fintecture::CryptoException, 'error during decryption'
47
+ end
48
+ end
49
+
50
+ def hash_base64(plain_text)
51
+ digest = Digest::SHA256.digest plain_text
52
+ Base64.strict_encode64(digest)
53
+ end
54
+
55
+ def create_signature_header(headers, client)
56
+ @client = client
57
+ signing = []
58
+ header = []
59
+
60
+ Fintecture::Utils::Constants::SIGNEDHEADERPARAMETERLIST.each do |param|
61
+ next unless headers[param]
62
+
63
+ param_low = param.downcase
64
+ signing << "#{param_low}: #{headers[param]}"
65
+ header << param_low
66
+ end
67
+
68
+ # Double quote in join needed. If not we will get two slashes \\n
69
+ signature = sign_payload signing.join("\n")
70
+ "keyId=\"#{@client.app_id}\",algorithm=\"rsa-sha256\",headers=\"#{header.join(' ')}\",signature=\"#{signature}\""
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -1,15 +1,15 @@
1
- require 'time'
2
-
3
- module Fintecture
4
- module Utils
5
- class Date
6
- class << self
7
-
8
- def header_time
9
- Time.now.utc.strftime("%a, %d %b %Y %H:%M:%S GMT")
10
- end
11
-
12
- end
13
- end
14
- end
15
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+
5
+ module Fintecture
6
+ module Utils
7
+ class Date
8
+ class << self
9
+ def header_time
10
+ Time.now.utc.strftime('%a, %d %b %Y %H:%M:%S GMT')
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,26 +1,32 @@
1
- require 'fintecture/exceptions'
2
-
3
- module Fintecture
4
- module Utils
5
- class Validation
6
- class << self
7
-
8
- def raise_if_klass_mismatch(target, klass, param_name = nil)
9
- return if target.is_a? klass
10
-
11
- raise Fintecture::ValidationException.new("invalid #{param_name ? param_name : 'parameter'} format, the parameter should be a #{klass} instead a #{target.class.name}")
12
- end
13
-
14
- def raise_if_invalid_date_format(date)
15
- return unless date
16
- valid_format = date.match(/\d{4}-\d{2}-\d{2}/)
17
- valid_date = ::Date.strptime(date, '%Y-%m-%d') rescue false
18
- return if valid_format && valid_date
19
-
20
- raise Fintecture::ValidationException.new("invalidss #{date} date, the format should be YYYY-MM-DD")
21
- end
22
-
23
- end
24
- end
25
- end
26
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'fintecture/exceptions'
4
+
5
+ module Fintecture
6
+ module Utils
7
+ class Validation
8
+ class << self
9
+ def raise_if_klass_mismatch(target, klass, param_name = nil)
10
+ return if target.is_a? klass
11
+
12
+ raise Fintecture::ValidationException,
13
+ "invalid #{param_name || 'parameter'} format, the parameter should be a #{klass} instead a #{target.class.name}"
14
+ end
15
+
16
+ def raise_if_invalid_date_format(date)
17
+ return unless date
18
+
19
+ valid_format = date.match(/\d{4}-\d{2}-\d{2}/)
20
+ valid_date = begin
21
+ ::Date.strptime(date, '%Y-%m-%d')
22
+ rescue StandardError
23
+ false
24
+ end
25
+ return if valid_format && valid_date
26
+
27
+ raise Fintecture::ValidationException, "invalidss #{date} date, the format should be YYYY-MM-DD"
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,3 +1,5 @@
1
- module Fintecture
2
- VERSION = '0.2.1'
3
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Fintecture
4
+ VERSION = '0.4.0'
5
+ end