giact_verification 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.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +143 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/giact_verification.gemspec +42 -0
- data/lib/giact_verification.rb +67 -0
- data/lib/giact_verification/authenticate.rb +44 -0
- data/lib/giact_verification/configuration.rb +52 -0
- data/lib/giact_verification/decorators/decorate_hash.rb +22 -0
- data/lib/giact_verification/decorators/giact_soap_decorator.rb +32 -0
- data/lib/giact_verification/errors.rb +7 -0
- data/lib/giact_verification/etc/alternative_id_types.yml +10 -0
- data/lib/giact_verification/etc/check_validator_errors.yml +11 -0
- data/lib/giact_verification/etc/customer_validator_errors.yml +35 -0
- data/lib/giact_verification/etc/serviced_countries.yml +2 -0
- data/lib/giact_verification/etc/serviced_states.yml +78 -0
- data/lib/giact_verification/etc/valid_account_types.yml +4 -0
- data/lib/giact_verification/extract_inquiry_result.rb +26 -0
- data/lib/giact_verification/inquiry_template_renderer.rb +26 -0
- data/lib/giact_verification/models/check.rb +33 -0
- data/lib/giact_verification/models/customer.rb +33 -0
- data/lib/giact_verification/models/giact_xml.rb +28 -0
- data/lib/giact_verification/requests/production_requester.rb +28 -0
- data/lib/giact_verification/requests/request_coordinator.rb +30 -0
- data/lib/giact_verification/requests/requester_factory.rb +25 -0
- data/lib/giact_verification/requests/sandbox_requester.rb +28 -0
- data/lib/giact_verification/requests/stubbed_requester.rb +38 -0
- data/lib/giact_verification/requests/support/declined_response.xml +17 -0
- data/lib/giact_verification/requests/support/error_response.xml +19 -0
- data/lib/giact_verification/requests/support/pass_response.xml +20 -0
- data/lib/giact_verification/response.rb +16 -0
- data/lib/giact_verification/response_parser.rb +35 -0
- data/lib/giact_verification/templates/inquiry.xml.erb +146 -0
- data/lib/giact_verification/validators/check_validator.rb +27 -0
- data/lib/giact_verification/validators/customer_validator.rb +77 -0
- data/lib/giact_verification/validators/giact_xml_validator.rb +25 -0
- data/lib/giact_verification/version.rb +3 -0
- data/lib/giact_verification/xml_to_hash.rb +22 -0
- metadata +214 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
|
|
3
|
+
module GiactVerification
|
|
4
|
+
class Configuration
|
|
5
|
+
|
|
6
|
+
attr_accessor :api_username
|
|
7
|
+
attr_accessor :api_password
|
|
8
|
+
attr_accessor :giact_endpoint
|
|
9
|
+
|
|
10
|
+
def initialize(args = {})
|
|
11
|
+
@giact_endpoint = :production
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def invalid?
|
|
15
|
+
api_username.nil? || api_password.nil?
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def servicing?(state)
|
|
19
|
+
serviced_states.include?(state)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def servicing_country?(country)
|
|
23
|
+
serviced_countries.include?(country)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def accepts_id_type?(id_type)
|
|
27
|
+
valid_alternative_id_types.include?(id_type)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def valid_account_type?(account_type)
|
|
31
|
+
valid_account_types.include?(account_type)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def valid_account_types
|
|
37
|
+
@valid_account_types ||= YAML.load_file(GiactVerification.config_directory + '/valid_account_types.yml')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def valid_alternative_id_types
|
|
41
|
+
@valid_alternative_id_types ||= YAML.load_file(GiactVerification.config_directory + '/alternative_id_types.yml')
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def serviced_states
|
|
45
|
+
@serviced_states ||= YAML.load_file(GiactVerification.config_directory + '/serviced_states.yml')
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def serviced_countries
|
|
49
|
+
@serviced_countries ||= YAML.load_file(GiactVerification.config_directory + '/serviced_countries.yml')
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module GiactVerification
|
|
2
|
+
class DecorateHash
|
|
3
|
+
|
|
4
|
+
def self.call(args)
|
|
5
|
+
new(args).call
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def initialize(args)
|
|
9
|
+
@input = args[:hashable].to_h
|
|
10
|
+
@decorator = args.fetch(:decorator, GiactVerification::GiactSoapDecorator)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def call
|
|
14
|
+
input.map do |key, value|
|
|
15
|
+
decorator.call(key: key, value: value)
|
|
16
|
+
end.to_h
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
attr_reader :input, :decorator
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module GiactVerification
|
|
2
|
+
class GiactSoapDecorator
|
|
3
|
+
|
|
4
|
+
KEYS_TO_UPCASE = [:state, :drivers_license_state, :country]
|
|
5
|
+
|
|
6
|
+
def self.call(args)
|
|
7
|
+
new(args).call
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def initialize(args)
|
|
11
|
+
@key = args[:key]
|
|
12
|
+
@value = args[:value]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def call
|
|
16
|
+
[key, modified_value]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
attr_reader :key, :value
|
|
21
|
+
|
|
22
|
+
def modified_value
|
|
23
|
+
if value.methods.include?(:strftime)
|
|
24
|
+
value.strftime('%Y-%m-%d')
|
|
25
|
+
elsif KEYS_TO_UPCASE.include?(key)
|
|
26
|
+
value.upcase
|
|
27
|
+
else
|
|
28
|
+
value.to_s
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
en:
|
|
2
|
+
errors:
|
|
3
|
+
valid_account_type?:
|
|
4
|
+
arg:
|
|
5
|
+
default: 'Must be a valid account type (Checking, Savings or Other)'
|
|
6
|
+
routing_number_length?:
|
|
7
|
+
arg:
|
|
8
|
+
default: 'length must be 9 digits with no dashes or whitespace'
|
|
9
|
+
account_number_length?:
|
|
10
|
+
arg:
|
|
11
|
+
default: 'length must be between 4 and 17 digits with no dashes or whitespace'
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
en:
|
|
2
|
+
errors:
|
|
3
|
+
serviced_state?:
|
|
4
|
+
arg:
|
|
5
|
+
default: 'must be a serviced US state or Canadian province (this includes all US states or CA provinces)'
|
|
6
|
+
serviced_country?:
|
|
7
|
+
arg:
|
|
8
|
+
default: 'must be a serviced country (US or CA)'
|
|
9
|
+
postal_code?:
|
|
10
|
+
arg:
|
|
11
|
+
default: 'must be a valid US (5 or 10 digit) or Canadian (7 digit) zip/postal code with no dashes or white space'
|
|
12
|
+
phone_number_length?:
|
|
13
|
+
arg:
|
|
14
|
+
default: 'length must be 10 digits with no dashes or whitespace'
|
|
15
|
+
phone_number_format?:
|
|
16
|
+
arg:
|
|
17
|
+
default: 'length must be 10 digits with 1-9 as the first digit (matching this regex: /[1-9][0-9]{9}/)'
|
|
18
|
+
last_four_ssn_length?:
|
|
19
|
+
arg:
|
|
20
|
+
default: 'length must be 4 digits with no dashes or white space'
|
|
21
|
+
ssn_or_ein_length?:
|
|
22
|
+
arg:
|
|
23
|
+
default: 'length must be 9 digits with no dashes or white space'
|
|
24
|
+
respond_to_strftime?:
|
|
25
|
+
arg:
|
|
26
|
+
default: "must be an object that responds to the method ':strftime'"
|
|
27
|
+
drivers_license_length?:
|
|
28
|
+
arg:
|
|
29
|
+
default: "length must be between 1-28 characters"
|
|
30
|
+
accepted_alternative_id?:
|
|
31
|
+
arg:
|
|
32
|
+
default: "id type must be one of the accepted alternative ids (UsaMilitaryId, UsaStateId, PassportUsa, PassportForeign, UsaResidentAlienId, StudentId, TribalId, DlCanada, DlMexico, or OtherForeignId)"
|
|
33
|
+
alternative_id_number_length?:
|
|
34
|
+
arg:
|
|
35
|
+
default: "length must be between 1 and 50 digits"
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# CANADA
|
|
2
|
+
- 'AB'
|
|
3
|
+
- 'BC'
|
|
4
|
+
- 'MB'
|
|
5
|
+
- 'NB'
|
|
6
|
+
- 'NL'
|
|
7
|
+
- 'NS'
|
|
8
|
+
- 'NU'
|
|
9
|
+
- 'ON'
|
|
10
|
+
- 'PE'
|
|
11
|
+
- 'QC'
|
|
12
|
+
- 'SK'
|
|
13
|
+
- 'NT'
|
|
14
|
+
- 'YT'
|
|
15
|
+
|
|
16
|
+
#UNITED STATES
|
|
17
|
+
- 'AA'
|
|
18
|
+
- 'AE'
|
|
19
|
+
- 'AK'
|
|
20
|
+
- 'AL'
|
|
21
|
+
- 'AP'
|
|
22
|
+
- 'AR'
|
|
23
|
+
- 'AS'
|
|
24
|
+
- 'AZ'
|
|
25
|
+
- 'CA'
|
|
26
|
+
- 'CO'
|
|
27
|
+
- 'CT'
|
|
28
|
+
- 'DC'
|
|
29
|
+
- 'DE'
|
|
30
|
+
- 'FL'
|
|
31
|
+
- 'FM'
|
|
32
|
+
- 'GA'
|
|
33
|
+
- 'GU'
|
|
34
|
+
- 'HI'
|
|
35
|
+
- 'IA'
|
|
36
|
+
- 'ID'
|
|
37
|
+
- 'IL'
|
|
38
|
+
- 'IN'
|
|
39
|
+
- 'KS'
|
|
40
|
+
- 'KY'
|
|
41
|
+
- 'LA'
|
|
42
|
+
- 'MA'
|
|
43
|
+
- 'MD'
|
|
44
|
+
- 'ME'
|
|
45
|
+
- 'MH'
|
|
46
|
+
- 'MI'
|
|
47
|
+
- 'MN'
|
|
48
|
+
- 'MO'
|
|
49
|
+
- 'MP'
|
|
50
|
+
- 'MS'
|
|
51
|
+
- 'MT'
|
|
52
|
+
- 'NC'
|
|
53
|
+
- 'ND'
|
|
54
|
+
- 'NE'
|
|
55
|
+
- 'NH'
|
|
56
|
+
- 'NJ'
|
|
57
|
+
- 'NM'
|
|
58
|
+
- 'NV'
|
|
59
|
+
- 'NY'
|
|
60
|
+
- 'OH'
|
|
61
|
+
- 'OK'
|
|
62
|
+
- 'OR'
|
|
63
|
+
- 'PA'
|
|
64
|
+
- 'PR'
|
|
65
|
+
- 'PW'
|
|
66
|
+
- 'RI'
|
|
67
|
+
- 'SC'
|
|
68
|
+
- 'SD'
|
|
69
|
+
- 'TN'
|
|
70
|
+
- 'TX'
|
|
71
|
+
- 'UT'
|
|
72
|
+
- 'VA'
|
|
73
|
+
- 'VI'
|
|
74
|
+
- 'VT'
|
|
75
|
+
- 'WA'
|
|
76
|
+
- 'WV'
|
|
77
|
+
- 'WI'
|
|
78
|
+
- 'WY'
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module GiactVerification
|
|
2
|
+
class ExtractInquiryResult
|
|
3
|
+
|
|
4
|
+
def self.call(args)
|
|
5
|
+
new(args).call
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def initialize(args)
|
|
9
|
+
@xml = args[:xml]
|
|
10
|
+
@hash = GiactVerification::XmlToHash.call(xml: xml)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def call
|
|
14
|
+
@inquiry_result = hash.dig(:'soap:envelope', :'soap:body', :post_inquiry_response, :post_inquiry_result)
|
|
15
|
+
|
|
16
|
+
if inquiry_result == nil
|
|
17
|
+
raise MalformedXmlError, xml
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
inquiry_result
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
attr_reader :xml, :hash, :inquiry_result
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'erb'
|
|
2
|
+
|
|
3
|
+
module GiactVerification
|
|
4
|
+
class InquiryTemplateRenderer
|
|
5
|
+
|
|
6
|
+
def self.call(args)
|
|
7
|
+
new(args).call
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def initialize(args)
|
|
11
|
+
@substitutions = args[:substitutions]
|
|
12
|
+
@filepath = GiactVerification.inquiry_template_directory
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def call
|
|
16
|
+
ERB.new(template_contents, nil, '>').result(binding)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
attr_reader :substitutions, :filepath, :rendered_template
|
|
21
|
+
|
|
22
|
+
def template_contents
|
|
23
|
+
File.read(filepath)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'ostruct'
|
|
2
|
+
|
|
3
|
+
module GiactVerification
|
|
4
|
+
class Check < OpenStruct
|
|
5
|
+
|
|
6
|
+
def initialize(args)
|
|
7
|
+
@attributes = args[:attributes]
|
|
8
|
+
@validation_class = args[:validation_class] || CheckValidator
|
|
9
|
+
|
|
10
|
+
super(attributes)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def invalid?
|
|
14
|
+
validator.failure?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def errors
|
|
18
|
+
validator.messages
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def decorate_for_xml
|
|
22
|
+
GiactVerification::DecorateHash.call(hashable: self)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
attr_reader :validation_class, :attributes
|
|
27
|
+
|
|
28
|
+
def validator
|
|
29
|
+
@validator ||= validation_class.call(self.to_h)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'ostruct'
|
|
2
|
+
|
|
3
|
+
module GiactVerification
|
|
4
|
+
class Customer < OpenStruct
|
|
5
|
+
|
|
6
|
+
def initialize(args)
|
|
7
|
+
@attributes = args[:attributes]
|
|
8
|
+
@validation_class = args[:validation_class] || CustomerValidator
|
|
9
|
+
|
|
10
|
+
super(attributes)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def invalid?
|
|
14
|
+
validator.failure?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def errors
|
|
18
|
+
validator.messages
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def decorate_for_xml
|
|
22
|
+
GiactVerification::DecorateHash.call(hashable: self)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
attr_reader :validation_class, :attributes
|
|
27
|
+
|
|
28
|
+
def validator
|
|
29
|
+
@validator ||= validation_class.call(self.to_h)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module GiactVerification
|
|
2
|
+
class GiactXml
|
|
3
|
+
|
|
4
|
+
def initialize(args)
|
|
5
|
+
@xml = args[:xml]
|
|
6
|
+
@validator = args[:validator] || GiactVerification::GiactXmlValidator
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def valid?
|
|
10
|
+
@valid ||= validator.call(xml: xml)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def inquiry_result
|
|
14
|
+
if invalid?
|
|
15
|
+
raise GiactVerification::GiactXmlError, 'Cannot retrieve inquiry result from invalid xml'
|
|
16
|
+
else
|
|
17
|
+
@inquiry_result ||= GiactVerification::ExtractInquiryResult.call(xml: xml)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
attr_reader :xml, :validator
|
|
23
|
+
|
|
24
|
+
def invalid?
|
|
25
|
+
!valid?
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'uri'
|
|
2
|
+
require 'net/http'
|
|
3
|
+
|
|
4
|
+
module GiactVerification
|
|
5
|
+
class ProductionRequester
|
|
6
|
+
|
|
7
|
+
PRODUCTION_URI = URI.parse('https://api.giact.com/verificationservices/v5/InquiriesWS-5-8.asmx').freeze
|
|
8
|
+
|
|
9
|
+
def self.call(args)
|
|
10
|
+
new(args).call
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def initialize(args)
|
|
14
|
+
@endpointable = PRODUCTION_URI
|
|
15
|
+
@body = args[:body]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def call
|
|
19
|
+
http = Net::HTTP.new(endpointable.host, endpointable.port)
|
|
20
|
+
http.use_ssl = true
|
|
21
|
+
|
|
22
|
+
response = http.post(endpointable.path, body, 'Content-Type' => 'text/xml')
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
attr_reader :endpointable, :body
|
|
27
|
+
end
|
|
28
|
+
end
|