credit_gateway 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.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rubocop.yml +96 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +8 -0
  6. data/Gemfile.lock +71 -0
  7. data/README.md +35 -0
  8. data/Rakefile +4 -0
  9. data/bin/console +12 -0
  10. data/bin/setup +8 -0
  11. data/credit_gateway.gemspec +37 -0
  12. data/lib/credit_gateway.rb +24 -0
  13. data/lib/credit_gateway/amount.rb +9 -0
  14. data/lib/credit_gateway/authenticate.rb +47 -0
  15. data/lib/credit_gateway/balance.rb +19 -0
  16. data/lib/credit_gateway/bank_account.rb +19 -0
  17. data/lib/credit_gateway/bank_account_scheme.rb +9 -0
  18. data/lib/credit_gateway/bank_data.rb +28 -0
  19. data/lib/credit_gateway/bank_data_request.rb +18 -0
  20. data/lib/credit_gateway/base_model.rb +65 -0
  21. data/lib/credit_gateway/base_repository.rb +42 -0
  22. data/lib/credit_gateway/behavioral_badge.rb +9 -0
  23. data/lib/credit_gateway/behavioral_score.rb +21 -0
  24. data/lib/credit_gateway/behavioral_score_repository.rb +38 -0
  25. data/lib/credit_gateway/camelizer_upper.rb +14 -0
  26. data/lib/credit_gateway/client.rb +60 -0
  27. data/lib/credit_gateway/configuration.rb +32 -0
  28. data/lib/credit_gateway/errors.rb +11 -0
  29. data/lib/credit_gateway/faraday_auth.rb +33 -0
  30. data/lib/credit_gateway/financial_score_repository.rb +16 -0
  31. data/lib/credit_gateway/full_score.rb +20 -0
  32. data/lib/credit_gateway/identity.rb +9 -0
  33. data/lib/credit_gateway/rating.rb +10 -0
  34. data/lib/credit_gateway/score_data_repository.rb +17 -0
  35. data/lib/credit_gateway/score_data_request.rb +18 -0
  36. data/lib/credit_gateway/score_data_response.rb +9 -0
  37. data/lib/credit_gateway/transaction.rb +21 -0
  38. data/lib/credit_gateway/version.rb +5 -0
  39. metadata +233 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 150f31aa7963afc5536a3bdda9ccfefeddfa2ee87bb7f298e44b11a3ad7e22cf
4
+ data.tar.gz: b435194d43382b6be9a41a3aa01bf8242adb296ac27865e127237feab5795611
5
+ SHA512:
6
+ metadata.gz: 3a0d08ff82831dfa6296b55c36e3407f2b5d098bc90fa58028683d36c1a66c06f1a0488835a0a2ca38d2fe47c26a1252e4e91c4d6c3b95ff4dae47a09d9d9309
7
+ data.tar.gz: 95b6d7519efb3e5669408f6663f586502016f465ece144e759aab69b4d972470826e53c1b7c3b6ea1946b70c9b059d8e6e01c2af77f3cab32cbf83794268ab63
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ /.rspec_status
10
+ /.ruby-gemset
data/.rubocop.yml ADDED
@@ -0,0 +1,96 @@
1
+ require: rubocop-rspec
2
+
3
+ AllCops:
4
+ TargetRubyVersion: 2.6
5
+ NewCops: enable
6
+ Exclude:
7
+ - 'db/**/*'
8
+ - 'ansible/**/*'
9
+ - 'vendor/**/*'
10
+ - 'bin/**/*'
11
+ - 'node_modules/**/*'
12
+
13
+ # Don't force top level comments in every class
14
+ Style/Documentation:
15
+ Enabled: false
16
+
17
+ # A good line length is 100 chars, comments are ignored
18
+ Layout/LineLength:
19
+ Max: 100
20
+ AllowURI: true
21
+ IgnoredPatterns: ['\A(\s+)?#']
22
+
23
+ Metrics/BlockLength:
24
+ Enabled: false
25
+
26
+ Metrics/ClassLength:
27
+ Max: 300
28
+
29
+ Metrics/MethodLength:
30
+ Max: 20
31
+
32
+ Metrics/AbcSize:
33
+ Max: 30
34
+
35
+ RSpec/ExampleLength:
36
+ Enabled: false
37
+
38
+ RSpec/MultipleExpectations:
39
+ Max: 10
40
+
41
+ RSpec/LetSetup:
42
+ Enabled: false
43
+
44
+ RSpec/MessageSpies:
45
+ Enabled: false
46
+
47
+ RSpec/RepeatedExample:
48
+ Exclude:
49
+ - 'spec/policies/**/*'
50
+
51
+ RSpec/RepeatedDescription:
52
+ Exclude:
53
+ - 'spec/policies/**/*'
54
+
55
+ Layout/EmptyLinesAroundAttributeAccessor:
56
+ Enabled: true
57
+
58
+ Layout/SpaceAroundMethodCallOperator:
59
+ Enabled: true
60
+
61
+ Lint/DeprecatedOpenSSLConstant:
62
+ Enabled: true
63
+
64
+ Lint/RaiseException:
65
+ Enabled: true
66
+
67
+ Lint/StructNewOverride:
68
+ Enabled: true
69
+
70
+ Style/ExponentialNotation:
71
+ Enabled: true
72
+
73
+ Style/HashEachMethods:
74
+ Enabled: true
75
+
76
+ Style/HashTransformKeys:
77
+ Enabled: true
78
+
79
+ Style/HashTransformValues:
80
+ Enabled: true
81
+
82
+ Style/SlicingWithRange:
83
+ Enabled: true
84
+
85
+ # TODO: we should rename our fields from line_1, address_line_2, etc
86
+ Naming/VariableNumber:
87
+ Enabled: false
88
+
89
+ Metrics/CyclomaticComplexity:
90
+ Max: 9
91
+
92
+ Metrics/PerceivedComplexity:
93
+ Max: 10
94
+
95
+ RSpec/MultipleMemoizedHelpers:
96
+ Max: 8
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.6.6
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ # Specify your gem's dependencies in credit_gateway.gemspec
8
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,71 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ credit_gateway (0.1.0)
5
+ faraday
6
+ faraday_middleware
7
+ faraday_middleware-multi_json
8
+ multi_json
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ addressable (2.7.0)
14
+ public_suffix (>= 2.0.2, < 5.0)
15
+ coderay (1.1.3)
16
+ crack (0.4.5)
17
+ rexml
18
+ diff-lcs (1.4.4)
19
+ dotenv (2.7.6)
20
+ faraday (0.17.4)
21
+ multipart-post (>= 1.2, < 3)
22
+ faraday_middleware (0.14.0)
23
+ faraday (>= 0.7.4, < 1.0)
24
+ faraday_middleware-multi_json (0.0.6)
25
+ faraday_middleware
26
+ multi_json
27
+ hashdiff (1.0.1)
28
+ method_source (1.0.0)
29
+ multi_json (1.15.0)
30
+ multipart-post (2.1.1)
31
+ pry (0.13.1)
32
+ coderay (~> 1.1)
33
+ method_source (~> 1.0)
34
+ public_suffix (4.0.6)
35
+ rake (13.0.3)
36
+ rexml (3.2.4)
37
+ rspec (3.10.0)
38
+ rspec-core (~> 3.10.0)
39
+ rspec-expectations (~> 3.10.0)
40
+ rspec-mocks (~> 3.10.0)
41
+ rspec-core (3.10.1)
42
+ rspec-support (~> 3.10.0)
43
+ rspec-expectations (3.10.1)
44
+ diff-lcs (>= 1.2.0, < 2.0)
45
+ rspec-support (~> 3.10.0)
46
+ rspec-mocks (3.10.2)
47
+ diff-lcs (>= 1.2.0, < 2.0)
48
+ rspec-support (~> 3.10.0)
49
+ rspec-support (3.10.2)
50
+ vcr (6.0.0)
51
+ webmock (3.12.1)
52
+ addressable (>= 2.3.6)
53
+ crack (>= 0.3.2)
54
+ hashdiff (>= 0.4.0, < 2.0.0)
55
+
56
+ PLATFORMS
57
+ x86_64-darwin-19
58
+ x86_64-linux
59
+
60
+ DEPENDENCIES
61
+ bundler (~> 2.2)
62
+ credit_gateway!
63
+ dotenv
64
+ pry
65
+ rake
66
+ rspec
67
+ vcr
68
+ webmock
69
+
70
+ BUNDLED WITH
71
+ 2.2.11
data/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # CreditGateway
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/credit_gateway`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'credit_gateway'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install credit_gateway
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/credit_gateway.
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'credit_gateway'
5
+ require 'json'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ require 'pry'
12
+ Pry.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'credit_gateway/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'credit_gateway'
9
+ spec.version = CreditGateway::VERSION
10
+ spec.authors = ['Finpoint']
11
+ spec.email = ['nenad@finpoint.co.uk']
12
+
13
+ spec.summary = 'CRIF CreditGateway client'
14
+ spec.description = 'CRIF CreditGateway client'
15
+ spec.homepage = 'https://www.finpoint.co.uk'
16
+
17
+ # Specify which files should be added to the gem when it is released.
18
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
20
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
+ end
22
+ spec.bindir = 'exe'
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ['lib']
25
+
26
+ spec.add_dependency 'faraday'
27
+ spec.add_dependency 'faraday_middleware'
28
+ spec.add_dependency 'faraday_middleware-multi_json'
29
+ spec.add_dependency 'multi_json'
30
+ spec.add_development_dependency 'bundler', '~> 2.2'
31
+ spec.add_development_dependency 'dotenv'
32
+ spec.add_development_dependency 'pry'
33
+ spec.add_development_dependency 'rake'
34
+ spec.add_development_dependency 'rspec'
35
+ spec.add_development_dependency 'vcr'
36
+ spec.add_development_dependency 'webmock'
37
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'credit_gateway/version'
4
+ require 'credit_gateway/configuration'
5
+ require 'credit_gateway/identity'
6
+ require 'credit_gateway/behavioral_score_repository'
7
+ require 'credit_gateway/financial_score_repository'
8
+ require 'credit_gateway/score_data_repository'
9
+ require 'credit_gateway/bank_data_request'
10
+ require 'credit_gateway/balance'
11
+ require 'credit_gateway/bank_account'
12
+ require 'credit_gateway/transaction'
13
+
14
+ module CreditGateway
15
+ module_function
16
+
17
+ def configure
18
+ yield(configuration)
19
+ end
20
+
21
+ def configuration
22
+ @configuration ||= Configuration.new
23
+ end
24
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'credit_gateway/base_model'
4
+
5
+ module CreditGateway
6
+ class Amount < BaseModel
7
+ attributes :amount, :currency
8
+ end
9
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'credit_gateway/configuration'
4
+ require 'credit_gateway/errors'
5
+ require 'credit_gateway/version'
6
+
7
+ module CreditGateway
8
+ class Authenticate
9
+ def call(client_id, client_secret)
10
+ response = post(
11
+ '/connect/token',
12
+ client_id: client_id,
13
+ client_secret: client_secret,
14
+ grant_type: 'client_credentials'
15
+ )
16
+
17
+ if response.success?
18
+ response.body[:access_token]
19
+ elsif response.status == 400
20
+ raise InvalidRequestError, response.body
21
+ else
22
+ raise GenericError, response.body
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def post(path, params = {})
29
+ connection.post(path, params)
30
+ end
31
+
32
+ def connection
33
+ auth_url = CreditGateway.configuration.auth_url
34
+
35
+ @connection ||= Faraday.new(url: auth_url) do |conn|
36
+ conn.request :url_encoded
37
+
38
+ conn.headers.merge!(
39
+ user_agent: "finpoint/#{CreditGateway::VERSION}"
40
+ )
41
+ conn.response :multi_json, symbolize_keys: true
42
+ conn.response :logger if CreditGateway.configuration.debug
43
+ conn.adapter Faraday.default_adapter
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+ require 'credit_gateway/base_model'
5
+ require 'credit_gateway/amount'
6
+
7
+ module CreditGateway
8
+ class Balance < BaseModel
9
+ attributes :account_id, :date_time, :type,
10
+ :amount, :credit_debit_indicator
11
+
12
+ def self.build(json:)
13
+ super.tap do |record|
14
+ record.amount = Amount.build(json: (record.amount || {}))
15
+ record.date_time = Time.parse(record.date_time) if record.date_time
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'credit_gateway/base_model'
4
+ require 'credit_gateway/bank_account_scheme'
5
+
6
+ module CreditGateway
7
+ class BankAccount < BaseModel
8
+ attributes :account_id, :account_type, :account_sub_type,
9
+ :currency, :nickname, :account
10
+
11
+ def self.build(json:)
12
+ super.tap do |record|
13
+ record.account = (record.account || []).compact.map do |bad|
14
+ BankAccountScheme.build(json: bad)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'credit_gateway/base_model'
4
+
5
+ module CreditGateway
6
+ class BankAccountScheme < BaseModel
7
+ attributes :scheme_name, :identification
8
+ end
9
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+ require 'credit_gateway/base_model'
5
+ require 'credit_gateway/transaction'
6
+ require 'credit_gateway/balance'
7
+ require 'credit_gateway/bank_account'
8
+
9
+ module CreditGateway
10
+ class BankData < BaseModel
11
+ attributes :transactions, :balances, :account, :last_booking_date_time
12
+
13
+ def self.build(json:)
14
+ super.tap do |record|
15
+ record.transactions = (record.transactions || []).compact.map do |t|
16
+ Transaction.build(json: t)
17
+ end
18
+ record.balances = (record.balances || []).compact.map do |b|
19
+ Balance.build(json: b)
20
+ end
21
+ record.account = BankAccount.build(json: (record.account || {}))
22
+ if record.last_booking_date_time
23
+ record.last_booking_date_time = Time.parse(record.last_booking_date_time)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'credit_gateway/base_model'
4
+ require 'credit_gateway/bank_data'
5
+
6
+ module CreditGateway
7
+ class BankDataRequest < BaseModel
8
+ attributes :banks_account_data
9
+
10
+ def self.build(json:)
11
+ super.tap do |record|
12
+ record.banks_account_data = (record.banks_account_data || []).compact.map do |bad|
13
+ BankData.build(json: bad)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'credit_gateway/errors'
4
+ require 'credit_gateway/camelizer_upper'
5
+
6
+ module CreditGateway
7
+ class BaseModel
8
+ class << self
9
+ def attributes(*attributes)
10
+ @attributes ||= []
11
+
12
+ return @attributes unless attributes
13
+
14
+ attr_accessor(*attributes)
15
+
16
+ @attributes += attributes
17
+ end
18
+
19
+ def attribute_aliases(aliases = nil)
20
+ @attribute_aliases ||= {}
21
+
22
+ return @attribute_aliases unless aliases
23
+
24
+ @attribute_aliases.merge!(aliases)
25
+ end
26
+
27
+ def key_transformer
28
+ CamelizerUpper
29
+ end
30
+
31
+ # Sets all the instance variables by reading the JSON from CreditGateway and converting the keys from
32
+ # PascalCase to snake_case, as it's the standard in Ruby.
33
+ def build(json: {}, key_transformer: self.key_transformer)
34
+ new.tap do |record|
35
+ attributes.each do |attr|
36
+ key = attribute_aliases.key?(attr) ? attribute_aliases[attr] : attr
37
+ record.public_send("#{attr}=", json[key_transformer.transform(key)])
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ def initialize(attributes = {})
44
+ attributes.each do |attr, value|
45
+ public_send("#{attr}=", value)
46
+ end
47
+ end
48
+
49
+ def as_json
50
+ self.class.attributes.each_with_object({}) do |attr, hash|
51
+ value = public_send(attr)
52
+
53
+ value = value.as_json if value.respond_to?(:as_json)
54
+ if value.is_a?(Array)
55
+ value = value.map { |v| v.respond_to?(:as_json) ? v.as_json : v }
56
+ end
57
+ value = value.iso8601 if value.respond_to?(:iso8601)
58
+
59
+ key = self.class.key_transformer.transform(attr)
60
+
61
+ hash[key] = value
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'credit_gateway/errors'
4
+ require 'credit_gateway/client'
5
+
6
+ module CreditGateway
7
+ class BaseRepository
8
+ def initialize(client: nil)
9
+ @client = client || Client.new
10
+ end
11
+
12
+ private
13
+
14
+ attr_reader :client
15
+
16
+ def get(path, params: {}, identity: nil)
17
+ headers = identity ? identity.to_headers : {}
18
+ result = client.get(path.strip, headers: headers, params: params)
19
+
20
+ raise APIKeyError, result.body[:error] if result.status == 401
21
+
22
+ result
23
+ end
24
+
25
+ def post(path, params: {}, identity: nil)
26
+ headers = identity ? identity.to_headers : {}
27
+ result = client.post(path.strip, headers: headers, params: params)
28
+
29
+ raise APIKeyError, result.body[:error] if result.status == 401
30
+
31
+ result
32
+ end
33
+
34
+ def format_url(url, params)
35
+ formatted = url.dup.strip
36
+
37
+ params.each { |key, value| formatted.sub!(":#{key}", value) }
38
+
39
+ formatted
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'credit_gateway/base_model'
4
+
5
+ module CreditGateway
6
+ class BehavioralBadge < BaseModel
7
+ attributes :badge_url, :badge_tiny_url, :badge_long_url, :upgrade_url
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+ require 'credit_gateway/base_model'
5
+ require 'credit_gateway/rating'
6
+
7
+ module CreditGateway
8
+ class BehavioralScore < BaseModel
9
+ attributes :frequency, :calculated, :main_rating, :component_ratings
10
+
11
+ def self.build(json:)
12
+ super.tap do |record|
13
+ record.calculated = Time.parse(record.calculated) if record.calculated
14
+ record.main_rating = Rating.build(json: (record.main_rating || {}))
15
+ record.component_ratings = (record.component_ratings || []).map do |rating|
16
+ Rating.build(json: rating)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'credit_gateway/base_repository'
4
+ require 'credit_gateway/behavioral_score'
5
+ require 'credit_gateway/behavioral_badge'
6
+ require 'credit_gateway/full_score'
7
+
8
+ module CreditGateway
9
+ class BehavioralScoreRepository < BaseRepository
10
+ # Params:
11
+ # document_token - Token retrieved from ScoreDataRepository#prepare
12
+ def specific_rating(document_token)
13
+ result = post('/score/behavioralscore', params: { token: document_token })
14
+
15
+ FullScore.build(json: result.body)
16
+ end
17
+
18
+ def latest_rating(company_id)
19
+ url = format_url(
20
+ '/score/behavioralscore/rating/:company_id',
21
+ company_id: company_id.to_s
22
+ )
23
+ result = get(url)
24
+
25
+ BehavioralScore.build(json: result.body)
26
+ end
27
+
28
+ def badge(company_id)
29
+ url = format_url(
30
+ '/score/behavioralscore/badge/:company_id',
31
+ company_id: company_id.to_s
32
+ )
33
+ result = get(url)
34
+
35
+ BehavioralBadge.build(json: result.body)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CreditGateway
4
+ class CamelizerUpper
5
+ # Converts this_is_my_string to ThisIsMyString and returns it as a symbol.
6
+ def self.transform(underscore_string)
7
+ underscore_string.to_s
8
+ .split('_')
9
+ .map(&:capitalize)
10
+ .join
11
+ .to_sym
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday'
4
+ require 'faraday_middleware/multi_json'
5
+ require 'credit_gateway/configuration'
6
+ require 'credit_gateway/faraday_auth'
7
+
8
+ module CreditGateway
9
+ class Client
10
+ def initialize
11
+ return if Faraday::Request.fetch_middleware(:credit_gateway_auth)
12
+
13
+ Faraday::Request.register_middleware credit_gateway_auth: -> { CreditGateway::FaradayAuth }
14
+ end
15
+
16
+ def get(path, headers: {}, params: {})
17
+ connection.get(path, params, headers).tap do |response|
18
+ handle_response(response)
19
+ end
20
+ end
21
+
22
+ def post(path, headers: {}, params: {})
23
+ connection.post(path, MultiJson.dump(params), headers).tap do |response|
24
+ handle_response(response)
25
+ end
26
+ end
27
+
28
+ def connection
29
+ @connection ||= Faraday.new(url: api_url) do |conn|
30
+ conn.request :credit_gateway_auth,
31
+ CreditGateway.configuration.client_id,
32
+ CreditGateway.configuration.client_secret
33
+ conn.response :multi_json, symbolize_keys: true
34
+ if CreditGateway.configuration.debug
35
+ conn.response :logger, nil, { headers: true, bodies: CreditGateway.configuration.verbose }
36
+ end
37
+ conn.adapter Faraday.default_adapter
38
+ end
39
+ end
40
+
41
+ def api_url
42
+ CreditGateway.configuration.base_url
43
+ end
44
+
45
+ def handle_response(response)
46
+ return if response.success?
47
+
48
+ case response.status
49
+ when 400
50
+ raise InvalidRequestError, response.body
51
+ when 401
52
+ raise UnauthorizedError, response.body
53
+ when 404
54
+ raise NotFoundError, response.body
55
+ else
56
+ raise GenericError, "#{response.status}: #{response.body}"
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CreditGateway
4
+ class Configuration
5
+ BASE_URLS = {
6
+ production: '',
7
+ sandbox: 'https://apiuat.connector.crifrealtime.com'
8
+ }.freeze
9
+ AUTH_URLS = {
10
+ production: '',
11
+ sandbox: 'https://uatauth.connector.crifrealtime.com'
12
+ }.freeze
13
+
14
+ attr_accessor :client_id, :client_secret, :environment, :debug, :verbose
15
+
16
+ def initialize
17
+ @client_id = ''
18
+ @client_secret = ''
19
+ @environment = :sandbox # can be either :sandbox or :production
20
+ @debug = false
21
+ @verbose = false
22
+ end
23
+
24
+ def base_url
25
+ BASE_URLS[environment.to_sym]
26
+ end
27
+
28
+ def auth_url
29
+ AUTH_URLS[environment.to_sym]
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CreditGateway
4
+ class UnauthorizedError < StandardError; end
5
+
6
+ class GenericError < StandardError; end
7
+
8
+ class InvalidRequestError < StandardError; end
9
+
10
+ class NotFoundError < StandardError; end
11
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'credit_gateway/authenticate'
4
+ require 'credit_gateway/version'
5
+ require 'credit_gateway/errors'
6
+
7
+ module CreditGateway
8
+ class FaradayAuth < Faraday::Middleware
9
+ def initialize(app, client_id, client_secret, options = {})
10
+ super(app)
11
+ @client_id = client_id
12
+ @client_secret = client_secret
13
+ @options = options
14
+ @token = nil
15
+ end
16
+
17
+ def call(env)
18
+ @token ||= authenticate
19
+
20
+ env[:request_headers]['Authorization'] = "Bearer #{@token}"
21
+ env[:request_headers]['Content-Type'] = 'application/json'
22
+ env[:request_headers]['User-Agent'] = "finpoint/#{CreditGateway::VERSION}"
23
+
24
+ @app.call(env)
25
+ end
26
+
27
+ private
28
+
29
+ def authenticate
30
+ Authenticate.new.call(@client_id, @client_secret)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'credit_gateway/base_repository'
4
+ require 'credit_gateway/full_score'
5
+
6
+ module CreditGateway
7
+ class FinancialScoreRepository < BaseRepository
8
+ # Fetch financial score for given company
9
+ # identity - CreditGateway::Identity
10
+ def find(identity)
11
+ result = get('/score/financialscore', identity: identity)
12
+
13
+ FullScore.build(json: result.body)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+ require 'credit_gateway/base_model'
5
+ require 'credit_gateway/rating'
6
+
7
+ module CreditGateway
8
+ class FullScore < BaseModel
9
+ attributes :frequency, :calculated, :full_score, :behavioral_score, :financial_score
10
+
11
+ def self.build(json:)
12
+ super.tap do |record|
13
+ record.full_score = Rating.build(json: (record.full_score || {}))
14
+ record.behavioral_score = Rating.build(json: (record.behavioral_score || {}))
15
+ record.financial_score = Rating.build(json: (record.financial_score || {}))
16
+ record.calculated = Time.parse(record.calculated) if record.calculated
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CreditGateway
4
+ Identity = Struct.new(:name, :number, keyword_init: true) do
5
+ def to_headers
6
+ { companyName: name, companyNumber: number }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'credit_gateway/base_model'
4
+
5
+ module CreditGateway
6
+ class Rating < BaseModel
7
+ attributes :p_d, :type, :class, :scale, :label, :description,
8
+ :implied_rating, :algorithm_version
9
+ end
10
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'credit_gateway/base_repository'
4
+ require 'credit_gateway/score_data_response'
5
+
6
+ module CreditGateway
7
+ class ScoreDataRepository < BaseRepository
8
+ # Submits bank data to prepare the report
9
+ # identity - CreditGateway::Identity
10
+ # bank_data_request - CreditGateway::BankDataRequest
11
+ def prepare(identity, bank_data_request)
12
+ res = post('/score/data/prepare', params: bank_data_request.as_json, identity: identity)
13
+
14
+ ScoreDataResponse.build(json: res.body)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'credit_gateway/base_model'
4
+ require 'credit_gateway/bank_data'
5
+
6
+ module CreditGateway
7
+ class ScoreDataRequest < BaseModel
8
+ attributes :banks_account_data
9
+
10
+ def self.build(json:)
11
+ super.tap do |record|
12
+ record.banks_account_data = (record.banks_account_data || []).compact.map do |bad|
13
+ BankData.build(json: bad)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'credit_gateway/base_model'
4
+
5
+ module CreditGateway
6
+ class ScoreDataResponse < BaseModel
7
+ attributes :token, :company_id
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+ require 'credit_gateway/base_model'
5
+ require 'credit_gateway/amount'
6
+
7
+ module CreditGateway
8
+ class Transaction < BaseModel
9
+ attributes :account_id, :transaction_id, :transaction_reference,
10
+ :amount, :credit_debit_indicator, :status, :transaction_information,
11
+ :booking_date_time, :value_date_time
12
+
13
+ def self.build(json:)
14
+ super.tap do |record|
15
+ record.amount = Amount.build(json: (record.amount || {}))
16
+ record.booking_date_time = Time.parse(record.booking_date_time) if record.booking_date_time
17
+ record.value_date_time = Time.parse(record.value_date_time) if record.value_date_time
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CreditGateway
4
+ VERSION = '0.1.0'
5
+ end
metadata ADDED
@@ -0,0 +1,233 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: credit_gateway
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Finpoint
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-05-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday_middleware
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: faraday_middleware-multi_json
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: multi_json
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.2'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.2'
83
+ - !ruby/object:Gem::Dependency
84
+ name: dotenv
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: vcr
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: webmock
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ description: CRIF CreditGateway client
168
+ email:
169
+ - nenad@finpoint.co.uk
170
+ executables: []
171
+ extensions: []
172
+ extra_rdoc_files: []
173
+ files:
174
+ - ".gitignore"
175
+ - ".rubocop.yml"
176
+ - ".ruby-version"
177
+ - Gemfile
178
+ - Gemfile.lock
179
+ - README.md
180
+ - Rakefile
181
+ - bin/console
182
+ - bin/setup
183
+ - credit_gateway.gemspec
184
+ - lib/credit_gateway.rb
185
+ - lib/credit_gateway/amount.rb
186
+ - lib/credit_gateway/authenticate.rb
187
+ - lib/credit_gateway/balance.rb
188
+ - lib/credit_gateway/bank_account.rb
189
+ - lib/credit_gateway/bank_account_scheme.rb
190
+ - lib/credit_gateway/bank_data.rb
191
+ - lib/credit_gateway/bank_data_request.rb
192
+ - lib/credit_gateway/base_model.rb
193
+ - lib/credit_gateway/base_repository.rb
194
+ - lib/credit_gateway/behavioral_badge.rb
195
+ - lib/credit_gateway/behavioral_score.rb
196
+ - lib/credit_gateway/behavioral_score_repository.rb
197
+ - lib/credit_gateway/camelizer_upper.rb
198
+ - lib/credit_gateway/client.rb
199
+ - lib/credit_gateway/configuration.rb
200
+ - lib/credit_gateway/errors.rb
201
+ - lib/credit_gateway/faraday_auth.rb
202
+ - lib/credit_gateway/financial_score_repository.rb
203
+ - lib/credit_gateway/full_score.rb
204
+ - lib/credit_gateway/identity.rb
205
+ - lib/credit_gateway/rating.rb
206
+ - lib/credit_gateway/score_data_repository.rb
207
+ - lib/credit_gateway/score_data_request.rb
208
+ - lib/credit_gateway/score_data_response.rb
209
+ - lib/credit_gateway/transaction.rb
210
+ - lib/credit_gateway/version.rb
211
+ homepage: https://www.finpoint.co.uk
212
+ licenses: []
213
+ metadata: {}
214
+ post_install_message:
215
+ rdoc_options: []
216
+ require_paths:
217
+ - lib
218
+ required_ruby_version: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ required_rubygems_version: !ruby/object:Gem::Requirement
224
+ requirements:
225
+ - - ">="
226
+ - !ruby/object:Gem::Version
227
+ version: '0'
228
+ requirements: []
229
+ rubygems_version: 3.2.11
230
+ signing_key:
231
+ specification_version: 4
232
+ summary: CRIF CreditGateway client
233
+ test_files: []