creditsafe 0.6.0 → 0.6.1
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.
- checksums.yaml +5 -5
- data/.circleci/config.yml +17 -17
- data/.gitignore +2 -2
- data/.rspec +1 -1
- data/.rubocop.yml +11 -11
- data/.ruby-version +1 -1
- data/CHANGELOG.md +49 -45
- data/Gemfile +5 -5
- data/Gemfile.lock +129 -129
- data/LICENSE.txt +22 -22
- data/README.md +175 -175
- data/creditsafe.gemspec +35 -35
- data/data/creditsafe-live.xml +342 -342
- data/data/creditsafe-test.xml +342 -342
- data/lib/creditsafe.rb +4 -4
- data/lib/creditsafe/client.rb +158 -158
- data/lib/creditsafe/constants.rb +49 -49
- data/lib/creditsafe/errors.rb +16 -16
- data/lib/creditsafe/match_type.rb +115 -115
- data/lib/creditsafe/messages.rb +97 -97
- data/lib/creditsafe/namespace.rb +20 -20
- data/lib/creditsafe/request/company_report.rb +42 -42
- data/lib/creditsafe/request/find_company.rb +120 -120
- data/lib/creditsafe/version.rb +5 -5
- data/spec/creditsafe/client_spec.rb +423 -423
- data/spec/creditsafe/messages_spec.rb +76 -76
- data/spec/fixtures/company-report-not-found.xml +13 -13
- data/spec/fixtures/company-report-request.xml +1 -1
- data/spec/fixtures/company-report-successful.xml +582 -582
- data/spec/fixtures/error-fault.xml +8 -8
- data/spec/fixtures/error-invalid-credentials.html +31 -31
- data/spec/fixtures/find-companies-error-no-text.xml +11 -11
- data/spec/fixtures/find-companies-error.xml +11 -11
- data/spec/fixtures/find-companies-none-found.xml +13 -13
- data/spec/fixtures/find-companies-request.xml +1 -1
- data/spec/fixtures/find-companies-successful-multi.xml +493 -493
- data/spec/fixtures/find-companies-successful.xml +29 -29
- data/spec/spec_helper.rb +14 -14
- metadata +3 -3
data/lib/creditsafe.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "creditsafe/errors"
|
4
|
-
require "creditsafe/client"
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "creditsafe/errors"
|
4
|
+
require "creditsafe/client"
|
data/lib/creditsafe/client.rb
CHANGED
@@ -1,158 +1,158 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "securerandom"
|
4
|
-
require "savon"
|
5
|
-
require "excon"
|
6
|
-
|
7
|
-
require "creditsafe/errors"
|
8
|
-
require "creditsafe/messages"
|
9
|
-
require "creditsafe/namespace"
|
10
|
-
|
11
|
-
require "creditsafe/request/company_report"
|
12
|
-
require "creditsafe/request/find_company"
|
13
|
-
|
14
|
-
require "active_support/notifications"
|
15
|
-
|
16
|
-
module Creditsafe
|
17
|
-
class Client
|
18
|
-
ENVIRONMENTS = %i[live test].freeze
|
19
|
-
|
20
|
-
def initialize(username: nil, password: nil, savon_opts: {},
|
21
|
-
environment: :live, log_level: :warn)
|
22
|
-
raise ArgumentError, "Username must be provided" if username.nil?
|
23
|
-
raise ArgumentError, "Password must be provided" if password.nil?
|
24
|
-
|
25
|
-
unless ENVIRONMENTS.include?(environment.to_sym)
|
26
|
-
raise ArgumentError, "Environment needs to be one of #{ENVIRONMENTS.join('/')}"
|
27
|
-
end
|
28
|
-
|
29
|
-
@environment = environment.to_s
|
30
|
-
@log_level = log_level
|
31
|
-
@username = username
|
32
|
-
@password = password
|
33
|
-
@savon_opts = savon_opts
|
34
|
-
end
|
35
|
-
|
36
|
-
def find_company(search_criteria = {})
|
37
|
-
request = Creditsafe::Request::FindCompany.new(search_criteria)
|
38
|
-
response = invoke_soap(:find_companies, request.message)
|
39
|
-
|
40
|
-
companies = response.
|
41
|
-
fetch(:find_companies_response).
|
42
|
-
fetch(:find_companies_result).
|
43
|
-
fetch(:companies)
|
44
|
-
|
45
|
-
companies.nil? ? nil : companies.fetch(:company)
|
46
|
-
end
|
47
|
-
|
48
|
-
def company_report(creditsafe_id, custom_data: nil)
|
49
|
-
request =
|
50
|
-
Creditsafe::Request::CompanyReport.new(creditsafe_id, custom_data)
|
51
|
-
response = invoke_soap(:retrieve_company_online_report, request.message)
|
52
|
-
|
53
|
-
response.
|
54
|
-
fetch(:retrieve_company_online_report_response).
|
55
|
-
fetch(:retrieve_company_online_report_result).
|
56
|
-
fetch(:reports).
|
57
|
-
fetch(:report)
|
58
|
-
end
|
59
|
-
|
60
|
-
def inspect
|
61
|
-
"#<#{self.class} @username='#{@username}'>"
|
62
|
-
end
|
63
|
-
|
64
|
-
private
|
65
|
-
|
66
|
-
def handle_message_for_response(response)
|
67
|
-
[
|
68
|
-
*response.xpath("//q1:Message"),
|
69
|
-
*response.xpath("//xmlns:Message"),
|
70
|
-
].each do |message|
|
71
|
-
api_message = Creditsafe::Messages.for_code(message.attributes["Code"].value)
|
72
|
-
|
73
|
-
api_error_message = api_message.message
|
74
|
-
api_error_message += " (#{message.text})" unless message.text.blank?
|
75
|
-
|
76
|
-
raise api_message.error_class, api_error_message if api_message.error?
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
# rubocop:disable Style/RescueStandardError
|
81
|
-
# rubocop:disable Metrics/MethodLength
|
82
|
-
def invoke_soap(message_type, message)
|
83
|
-
started = Time.now
|
84
|
-
notification_payload = { request: message }
|
85
|
-
|
86
|
-
response = client.call(message_type, message: message)
|
87
|
-
handle_message_for_response(response)
|
88
|
-
notification_payload[:response] = response.body
|
89
|
-
rescue Excon::Errors::Timeout
|
90
|
-
raise TimeoutError
|
91
|
-
rescue => raw_error
|
92
|
-
processed_error = handle_error(raw_error)
|
93
|
-
notification_payload[:error] = processed_error
|
94
|
-
raise processed_error
|
95
|
-
ensure
|
96
|
-
publish("creditsafe.#{message_type}", started, Time.now,
|
97
|
-
SecureRandom.hex(10), notification_payload)
|
98
|
-
end
|
99
|
-
# rubocop:enable Metrics/MethodLength
|
100
|
-
# rubocop:enable Style/RescueStandardError
|
101
|
-
|
102
|
-
def publish(*args)
|
103
|
-
ActiveSupport::Notifications.publish(*args)
|
104
|
-
end
|
105
|
-
|
106
|
-
# There's a potential bug in the creditsafe API where they actually return
|
107
|
-
# an HTTP 401 if you're unauthorized, hence the sad special case below
|
108
|
-
#
|
109
|
-
# rubocop:disable Metrics/MethodLength
|
110
|
-
def handle_error(error)
|
111
|
-
case error
|
112
|
-
when Savon::SOAPFault
|
113
|
-
return UnknownApiError.new(error.message)
|
114
|
-
when Savon::HTTPError
|
115
|
-
if error.to_hash[:code] == 401
|
116
|
-
return AccountError.new("Unauthorized: invalid credentials")
|
117
|
-
end
|
118
|
-
return UnknownApiError.new(error.message)
|
119
|
-
when Excon::Errors::Error
|
120
|
-
return HttpError.new("Error making HTTP request: #{error.message}")
|
121
|
-
end
|
122
|
-
error
|
123
|
-
end
|
124
|
-
# rubocop:enable Metrics/MethodLength
|
125
|
-
|
126
|
-
def client
|
127
|
-
@client ||= build_savon_client
|
128
|
-
end
|
129
|
-
|
130
|
-
def auth_header
|
131
|
-
auth_value = "Basic " + Base64.encode64("#{@username}:#{@password}").chomp
|
132
|
-
{ "Authorization" => auth_value }
|
133
|
-
end
|
134
|
-
|
135
|
-
# rubocop:disable Metrics/MethodLength
|
136
|
-
def build_savon_client
|
137
|
-
options = {
|
138
|
-
env_namespace: "soapenv",
|
139
|
-
namespace_identifier: Creditsafe::Namespace::OPER,
|
140
|
-
namespaces: Creditsafe::Namespace::ALL,
|
141
|
-
wsdl: wsdl_path,
|
142
|
-
headers: auth_header,
|
143
|
-
convert_request_keys_to: :none,
|
144
|
-
adapter: :excon,
|
145
|
-
log: true,
|
146
|
-
log_level: @log_level,
|
147
|
-
pretty_print_xml: true,
|
148
|
-
}
|
149
|
-
Savon.client(options.merge(@savon_opts))
|
150
|
-
end
|
151
|
-
# rubocop:enable Metrics/MethodLength
|
152
|
-
|
153
|
-
def wsdl_path
|
154
|
-
root_dir = File.join(File.dirname(__FILE__), "..", "..")
|
155
|
-
File.join(root_dir, "data", "creditsafe-#{@environment}.xml")
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "securerandom"
|
4
|
+
require "savon"
|
5
|
+
require "excon"
|
6
|
+
|
7
|
+
require "creditsafe/errors"
|
8
|
+
require "creditsafe/messages"
|
9
|
+
require "creditsafe/namespace"
|
10
|
+
|
11
|
+
require "creditsafe/request/company_report"
|
12
|
+
require "creditsafe/request/find_company"
|
13
|
+
|
14
|
+
require "active_support/notifications"
|
15
|
+
|
16
|
+
module Creditsafe
|
17
|
+
class Client
|
18
|
+
ENVIRONMENTS = %i[live test].freeze
|
19
|
+
|
20
|
+
def initialize(username: nil, password: nil, savon_opts: {},
|
21
|
+
environment: :live, log_level: :warn)
|
22
|
+
raise ArgumentError, "Username must be provided" if username.nil?
|
23
|
+
raise ArgumentError, "Password must be provided" if password.nil?
|
24
|
+
|
25
|
+
unless ENVIRONMENTS.include?(environment.to_sym)
|
26
|
+
raise ArgumentError, "Environment needs to be one of #{ENVIRONMENTS.join('/')}"
|
27
|
+
end
|
28
|
+
|
29
|
+
@environment = environment.to_s
|
30
|
+
@log_level = log_level
|
31
|
+
@username = username
|
32
|
+
@password = password
|
33
|
+
@savon_opts = savon_opts
|
34
|
+
end
|
35
|
+
|
36
|
+
def find_company(search_criteria = {})
|
37
|
+
request = Creditsafe::Request::FindCompany.new(search_criteria)
|
38
|
+
response = invoke_soap(:find_companies, request.message)
|
39
|
+
|
40
|
+
companies = response.
|
41
|
+
fetch(:find_companies_response).
|
42
|
+
fetch(:find_companies_result).
|
43
|
+
fetch(:companies)
|
44
|
+
|
45
|
+
companies.nil? ? nil : companies.fetch(:company)
|
46
|
+
end
|
47
|
+
|
48
|
+
def company_report(creditsafe_id, custom_data: nil)
|
49
|
+
request =
|
50
|
+
Creditsafe::Request::CompanyReport.new(creditsafe_id, custom_data)
|
51
|
+
response = invoke_soap(:retrieve_company_online_report, request.message)
|
52
|
+
|
53
|
+
response.
|
54
|
+
fetch(:retrieve_company_online_report_response).
|
55
|
+
fetch(:retrieve_company_online_report_result).
|
56
|
+
fetch(:reports).
|
57
|
+
fetch(:report)
|
58
|
+
end
|
59
|
+
|
60
|
+
def inspect
|
61
|
+
"#<#{self.class} @username='#{@username}'>"
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def handle_message_for_response(response)
|
67
|
+
[
|
68
|
+
*response.xpath("//q1:Message"),
|
69
|
+
*response.xpath("//xmlns:Message"),
|
70
|
+
].each do |message|
|
71
|
+
api_message = Creditsafe::Messages.for_code(message.attributes["Code"].value)
|
72
|
+
|
73
|
+
api_error_message = api_message.message
|
74
|
+
api_error_message += " (#{message.text})" unless message.text.blank?
|
75
|
+
|
76
|
+
raise api_message.error_class, api_error_message if api_message.error?
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# rubocop:disable Style/RescueStandardError
|
81
|
+
# rubocop:disable Metrics/MethodLength
|
82
|
+
def invoke_soap(message_type, message)
|
83
|
+
started = Time.now
|
84
|
+
notification_payload = { request: message }
|
85
|
+
|
86
|
+
response = client.call(message_type, message: message)
|
87
|
+
handle_message_for_response(response)
|
88
|
+
notification_payload[:response] = response.body
|
89
|
+
rescue Excon::Errors::Timeout
|
90
|
+
raise TimeoutError
|
91
|
+
rescue => raw_error
|
92
|
+
processed_error = handle_error(raw_error)
|
93
|
+
notification_payload[:error] = processed_error
|
94
|
+
raise processed_error
|
95
|
+
ensure
|
96
|
+
publish("creditsafe.#{message_type}", started, Time.now,
|
97
|
+
SecureRandom.hex(10), notification_payload)
|
98
|
+
end
|
99
|
+
# rubocop:enable Metrics/MethodLength
|
100
|
+
# rubocop:enable Style/RescueStandardError
|
101
|
+
|
102
|
+
def publish(*args)
|
103
|
+
ActiveSupport::Notifications.publish(*args)
|
104
|
+
end
|
105
|
+
|
106
|
+
# There's a potential bug in the creditsafe API where they actually return
|
107
|
+
# an HTTP 401 if you're unauthorized, hence the sad special case below
|
108
|
+
#
|
109
|
+
# rubocop:disable Metrics/MethodLength
|
110
|
+
def handle_error(error)
|
111
|
+
case error
|
112
|
+
when Savon::SOAPFault
|
113
|
+
return UnknownApiError.new(error.message)
|
114
|
+
when Savon::HTTPError
|
115
|
+
if error.to_hash[:code] == 401
|
116
|
+
return AccountError.new("Unauthorized: invalid credentials")
|
117
|
+
end
|
118
|
+
return UnknownApiError.new(error.message)
|
119
|
+
when Excon::Errors::Error
|
120
|
+
return HttpError.new("Error making HTTP request: #{error.message}")
|
121
|
+
end
|
122
|
+
error
|
123
|
+
end
|
124
|
+
# rubocop:enable Metrics/MethodLength
|
125
|
+
|
126
|
+
def client
|
127
|
+
@client ||= build_savon_client
|
128
|
+
end
|
129
|
+
|
130
|
+
def auth_header
|
131
|
+
auth_value = "Basic " + Base64.encode64("#{@username}:#{@password}").chomp
|
132
|
+
{ "Authorization" => auth_value }
|
133
|
+
end
|
134
|
+
|
135
|
+
# rubocop:disable Metrics/MethodLength
|
136
|
+
def build_savon_client
|
137
|
+
options = {
|
138
|
+
env_namespace: "soapenv",
|
139
|
+
namespace_identifier: Creditsafe::Namespace::OPER,
|
140
|
+
namespaces: Creditsafe::Namespace::ALL,
|
141
|
+
wsdl: wsdl_path,
|
142
|
+
headers: auth_header,
|
143
|
+
convert_request_keys_to: :none,
|
144
|
+
adapter: :excon,
|
145
|
+
log: true,
|
146
|
+
log_level: @log_level,
|
147
|
+
pretty_print_xml: true,
|
148
|
+
}
|
149
|
+
Savon.client(options.merge(@savon_opts))
|
150
|
+
end
|
151
|
+
# rubocop:enable Metrics/MethodLength
|
152
|
+
|
153
|
+
def wsdl_path
|
154
|
+
root_dir = File.join(File.dirname(__FILE__), "..", "..")
|
155
|
+
File.join(root_dir, "data", "creditsafe-#{@environment}.xml")
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
data/lib/creditsafe/constants.rb
CHANGED
@@ -1,49 +1,49 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Constants
|
4
|
-
module Country
|
5
|
-
AUSTRALIA = "AU"
|
6
|
-
AUSTRIA = "AT"
|
7
|
-
BELGIUM = "BE"
|
8
|
-
BULGARIA = "BG"
|
9
|
-
CANADA = "CA"
|
10
|
-
CROATIA = "HR"
|
11
|
-
CZECH_REPUBLIC = "CZ"
|
12
|
-
DENMARK = "DK"
|
13
|
-
ESTONIA = "EE"
|
14
|
-
FINLAND = "FI"
|
15
|
-
FRANCE = "FR"
|
16
|
-
GERMANY = "DE"
|
17
|
-
GREAT_BRITAIN = "GB"
|
18
|
-
GREECE = "GR"
|
19
|
-
HUNGARY = "HU"
|
20
|
-
ICELAND = "IS"
|
21
|
-
IRELAND = "IE"
|
22
|
-
ITALY = "IT"
|
23
|
-
LATVIA = "LV"
|
24
|
-
LIECHTENSTEIN = "LI"
|
25
|
-
LITHUANIA = "LT"
|
26
|
-
LUXEMBOURG = "LU"
|
27
|
-
MALTA = "MT"
|
28
|
-
MOLDOVA = "MD"
|
29
|
-
NETHERLANDS = "NL"
|
30
|
-
NEW_ZEALAND = "NZ"
|
31
|
-
NORWAY = "NO"
|
32
|
-
POLAND = "PL"
|
33
|
-
PORTUGAL = "PT"
|
34
|
-
ROMANIA = "RO"
|
35
|
-
SLOVAKIA = "SK"
|
36
|
-
SLOVENIA = "SI"
|
37
|
-
SPAIN = "ES"
|
38
|
-
SWEDEN = "SE"
|
39
|
-
SWITZERLAND = "CH"
|
40
|
-
UK = "GB"
|
41
|
-
UNITED_STATES = "US"
|
42
|
-
|
43
|
-
VAT_NUMBER_SUPPORTED = [
|
44
|
-
GERMANY, FRANCE, CZECH_REPUBLIC, SLOVAKIA, BELGIUM, POLAND, PORTUGAL, SPAIN,
|
45
|
-
UNITED_STATES, SLOVENIA, CROATIA, BULGARIA, ROMANIA, LATVIA, ESTONIA, MOLDOVA,
|
46
|
-
AUSTRIA, ITALY, HUNGARY, FINLAND, DENMARK, AUSTRALIA, GREECE
|
47
|
-
].freeze
|
48
|
-
end
|
49
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Constants
|
4
|
+
module Country
|
5
|
+
AUSTRALIA = "AU"
|
6
|
+
AUSTRIA = "AT"
|
7
|
+
BELGIUM = "BE"
|
8
|
+
BULGARIA = "BG"
|
9
|
+
CANADA = "CA"
|
10
|
+
CROATIA = "HR"
|
11
|
+
CZECH_REPUBLIC = "CZ"
|
12
|
+
DENMARK = "DK"
|
13
|
+
ESTONIA = "EE"
|
14
|
+
FINLAND = "FI"
|
15
|
+
FRANCE = "FR"
|
16
|
+
GERMANY = "DE"
|
17
|
+
GREAT_BRITAIN = "GB"
|
18
|
+
GREECE = "GR"
|
19
|
+
HUNGARY = "HU"
|
20
|
+
ICELAND = "IS"
|
21
|
+
IRELAND = "IE"
|
22
|
+
ITALY = "IT"
|
23
|
+
LATVIA = "LV"
|
24
|
+
LIECHTENSTEIN = "LI"
|
25
|
+
LITHUANIA = "LT"
|
26
|
+
LUXEMBOURG = "LU"
|
27
|
+
MALTA = "MT"
|
28
|
+
MOLDOVA = "MD"
|
29
|
+
NETHERLANDS = "NL"
|
30
|
+
NEW_ZEALAND = "NZ"
|
31
|
+
NORWAY = "NO"
|
32
|
+
POLAND = "PL"
|
33
|
+
PORTUGAL = "PT"
|
34
|
+
ROMANIA = "RO"
|
35
|
+
SLOVAKIA = "SK"
|
36
|
+
SLOVENIA = "SI"
|
37
|
+
SPAIN = "ES"
|
38
|
+
SWEDEN = "SE"
|
39
|
+
SWITZERLAND = "CH"
|
40
|
+
UK = "GB"
|
41
|
+
UNITED_STATES = "US"
|
42
|
+
|
43
|
+
VAT_NUMBER_SUPPORTED = [
|
44
|
+
GERMANY, FRANCE, CZECH_REPUBLIC, SLOVAKIA, BELGIUM, POLAND, PORTUGAL, SPAIN,
|
45
|
+
UNITED_STATES, SLOVENIA, CROATIA, BULGARIA, ROMANIA, LATVIA, ESTONIA, MOLDOVA,
|
46
|
+
AUSTRIA, ITALY, HUNGARY, FINLAND, DENMARK, AUSTRALIA, GREECE
|
47
|
+
].freeze
|
48
|
+
end
|
49
|
+
end
|
data/lib/creditsafe/errors.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Creditsafe
|
4
|
-
class Error < StandardError; end
|
5
|
-
|
6
|
-
class HttpError < Error; end
|
7
|
-
class ApiError < Error; end
|
8
|
-
|
9
|
-
class TimeoutError < HttpError; end
|
10
|
-
|
11
|
-
class DataError < ApiError; end
|
12
|
-
class AccountError < ApiError; end
|
13
|
-
class RequestError < ApiError; end
|
14
|
-
class ProcessingError < ApiError; end
|
15
|
-
class UnknownApiError < ApiError; end
|
16
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Creditsafe
|
4
|
+
class Error < StandardError; end
|
5
|
+
|
6
|
+
class HttpError < Error; end
|
7
|
+
class ApiError < Error; end
|
8
|
+
|
9
|
+
class TimeoutError < HttpError; end
|
10
|
+
|
11
|
+
class DataError < ApiError; end
|
12
|
+
class AccountError < ApiError; end
|
13
|
+
class RequestError < ApiError; end
|
14
|
+
class ProcessingError < ApiError; end
|
15
|
+
class UnknownApiError < ApiError; end
|
16
|
+
end
|