credit_gateway 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []