alloy-kyc 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d51359802cec9afbf0b07fe5cbd6aaf1fa37c203
4
+ data.tar.gz: 974ecb72d83b5d9d3355848beb1dcf768bf00b50
5
+ SHA512:
6
+ metadata.gz: 764eae0db923c1d8fc5f119dac777284d6632cb9a796091e5397f3d6337cbdf5dcef2ac256f42f8c1c5c5ed5d0cb312d361568a66c9eade713ccd4f82e5e907a
7
+ data.tar.gz: 2d4c71319a76f7507bd3846efc82681fc817d184e9404b31b8173d6a98606d019db4a332c5cfae78ebee683959b4ac14b32685d7da364da7680f061426ccf962
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.12.5
@@ -0,0 +1,2 @@
1
+ * March 10, 2017 - 0.1.0
2
+ Initial release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in alloy-kyc.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Doug Ramsay
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,85 @@
1
+ ## Installation
2
+
3
+ Add this line to your application's Gemfile:
4
+
5
+ ```ruby
6
+ gem 'alloy-kyc'
7
+ ```
8
+
9
+ And then execute:
10
+
11
+ $ bundle
12
+
13
+ Or install it yourself as:
14
+
15
+ $ gem install alloy-kyc
16
+
17
+ ## Usage
18
+
19
+ Configure the gem using your issued Alloy credentials in an initializer file. For example, in config/initializers/alloy-kyc.rb:
20
+
21
+ ```ruby
22
+ Alloy::KYC.configure do |config|
23
+ config.application_token = ENV['ALLOY_APPLICATION_TOKEN']
24
+ config.application_secret = ENV['ALLOY_APPLICATION_SECRET']
25
+ end
26
+ ```
27
+
28
+ Create a new evaluation:
29
+
30
+ ```ruby
31
+ Alloy::KYC::Evaluation.create({
32
+ phone_number: "18042562188",
33
+ name_first: "Thomas",
34
+ name_last: "Nicholas",
35
+ email_address: "tommy@alloy.co",
36
+ birth_date: "1985-01-23",
37
+ address_line_1: "1717 E Test St",
38
+ address_city: "Richmond",
39
+ address_state: "VA",
40
+ document_ssn: "123456789",
41
+ address_postal_code: "23220",
42
+ address_country_code: "US",
43
+ social_twitter: "tommyrva"
44
+ })
45
+ ```
46
+
47
+ If evaluation requires further information around out-of-wallet questions:
48
+
49
+ ```ruby
50
+ evaluation = Alloy::KYC::Evaluation.create({phone_number: "18042562188", name_first: "Thomas",...})
51
+ if evaluation.requires_oow?
52
+ # collect answers and either match locally or resubmit
53
+ updated_evaluation = evaluation.submit_oow_responses(responses)
54
+ end
55
+ ```
56
+
57
+ ## Testing
58
+
59
+ To prevent this gem from making API calls when your tests are running, use mock mode:
60
+
61
+ ```ruby
62
+ Alloy::KYC.mock_mode!
63
+ ```
64
+
65
+ When in mock mode methods will return "successful" results; i.e., a call to `Alloy::KYC::Evaluation.create` will return an `Evaluation` that doesn't require an out of wallet followup. To simulate a failure, call `Alloy::KYC::Evaluation.create` with a `document_ssn` of `111223333`:
66
+
67
+ ```ruby
68
+ Alloy::KYC::Evaluation.create(document_ssn: "111223333", ...) # any other parameters are ignored
69
+ ```
70
+
71
+ Similarly, you can simulate an out-of-wallet response that requires more responses by passing that same `document_ssn` to `submit_oow_responses`:
72
+
73
+ ```ruby
74
+ # given an existing Evaluation e:
75
+ e.submit_oow_responses({document_ssn: "111223333", ...}) # any other parameters are ignored
76
+ ```
77
+
78
+ ## Contributing
79
+
80
+ Bug reports and pull requests are welcome on GitHub at https://github.com/qedinvestors/alloy-kyc.
81
+
82
+
83
+ ## License
84
+
85
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'alloy/kyc/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "alloy-kyc"
8
+ spec.version = Alloy::KYC::VERSION
9
+ spec.authors = ["Doug Ramsay"]
10
+ spec.email = ["doug@qedinvestors.com"]
11
+
12
+ spec.summary = %q{Gem to wrap the Alloy.co API}
13
+ spec.description = %q{Gem to wrap the Alloy.co API}
14
+ spec.homepage = "https://github.com/qedinvestors/alloy-kyc"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.12"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "rspec", "~> 3.0"
25
+ spec.add_development_dependency "vcr"
26
+ spec.add_development_dependency "webmock"
27
+ spec.add_development_dependency "byebug"
28
+ spec.add_dependency "faraday"
29
+ spec.add_dependency "json"
30
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "alloy/kyc"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -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 @@
1
+ {"evaluation_token":"S-1y1hBJt8qpXmjzzNmsIQ","error":null,"timestamp":1488488005916,"entity_token":"P-Jdr5V9jbZap5adZ0vIzO","application_token":"dpDD6z4olOSI7N4fMCsAlKjFa7reBYhu","application_version_id":11,"required":[{"key":"name_first","type":"string","description":"First name","regex":"^[^d]*$"},{"key":"name_last","type":"string","description":"Last name","regex":"^[^d]*$"},{"key":"address_line_1","type":"string","description":"Address field 1","regex":""},{"key":"address_city","type":"string","description":"Address city","regex":""},{"key":"address_state","type":"string","description":"US state","regex":""},{"key":"address_postal_code","type":"string","description":"Address postal code","regex":""},{"key":"birth_date","type":"date","description":"Birth date - valid ISO 8601 format","regex":""}],"optional":[{"key":"name_middle","type":"string","description":"Middle name","regex":"^[^d]*$"},{"key":"name_suffix","type":"string","description":"Name suffix","regex":"^[^d]*$"},{"key":"address_line_2","type":"string","description":"Address field 2","regex":""},{"key":"ip_address_v4","type":"string","description":null},{"key":"gender","type":"string","description":"Gender of evaluation target."},{"key":"email_address","type":"string","description":"Primary email address"},{"key":"document_ssn","type":"string","description":"US social security number"},{"key":"document_ssn_last4","type":"string","description":"Last four digits of a US social security number"}],"prompts":{},"or":{"required":[{"key":"document_ssn","type":"string","description":"US social security number"},{"key":"document_ssn_last4","type":"string","description":"Last four digits of a US social security number"}]}}
@@ -0,0 +1 @@
1
+ {"status_code":201,"error":null,"timestamp":1488486910882,"evaluation_token":"S-povLiQYnBFQLGGs9bs2C","entity_token":"P-iBuYneyLEpBPAdE2qokA","application_token":"dpDD6z4olOSI7N4fMCsAlKjFa7reBYhu","application_version_id":11,"summary":{"result":"success","score":1,"tags":[],"outcome":null,"services":{"Lexis Nexis Instant ID":"executed"}},"supplied":{"address_city":"Richmond","address_country_code":"US","address_line_1":"1717 E Test St","address_postal_code":"23220","address_state":"VA","birth_date":"1985-01-23","document_ssn":"123456789","email_address":"tommy@alloy.co","name_first":"Thomas","name_last":"Nicholas","phone_number":"18042562188","social_twitter":"tommyrva"},"formatted":{"address_city":"Richmond","address_country_code":"US","address_line_1":"1717 E Test St","address_postal_code":"23220","address_state":"VA","birth_date":"1985-01-23","document_ssn":"123456789","email_address":"tommy@alloy.co","name_first":"Thomas","name_last":"Nicholas","phone_number":"+18042562188","social_twitter":"tommyrva"},"matching":{"name":{"score":1,"matched":["Lexis Nexis Instant ID"],"unmatched":[]},"address":{"score":1,"matched":["Lexis Nexis Instant ID"],"unmatched":[]},"ssn":{"score":1,"matched":["Lexis Nexis Instant ID"],"unmatched":[]},"dob":{"score":1,"matched":["Lexis Nexis Instant ID"],"unmatched":[]},"phone":{"score":1,"matched":["Lexis Nexis Instant ID"],"unmatched":[]}},"diligence":{"watchlists":{"lists":["BES","CFTC","DTC","EUDT","FBI","FCEN","FAR","IMW","OFAC","OCC","OSFI","PEP","SDT","UNNT","BIS","WBIF"],"matches":[]},"fraud":null,"financial":null,"identity_questions":null},"related_data":{},"raw_responses":{"Lexis Nexis Instant ID":[{"response":{"Header":{"Status":0,"TransactionId":"0"},"Result":{"InputEcho":{"SSN":"123456789","SSNLast4":"6789","IPAddress":"192.168.0.1","Name":{"Last":"Nicholas","First":"Thomas"},"Address":{"StreetAddress1":"1717 E Test St","StreetAddress2":"APT 2L","City":"Richmond","State":"VA","Zip5":"23220"},"DOB":{"Year":1985,"Month":1,"Day":23},"Channel":null,"Passport":{"Number":"","Country":"","ExpirationDate":null,"MachineReadableLine1":"","MachineReadableLine2":""},"HomePhone":"+18042562188","OwnOrRent":null,"ApplicationDateTime":{"Day":2,"Year":2017,"Month":3,"Hour24":20,"Minute":35,"Second":10}},"UniqueId":"1567805191","NameAddressSSNSummary":12,"AdditionalScore1":0,"AdditionalScore2":0,"PhoneOfNameAddress":8043563199,"SSNInfo":{"Valid":"G","IssuedEndDate":{"Year":"1979","Month":"12"},"IssuedLocation":"VIRGINIA","IssuedStartDate":{"Year":"1977","Month":"01"}},"CurrentName":{"Last":"NICHOLAS","First":"THOMAS"},"ReversePhone":{"Name":{"Last":"NICHOLAS","First":"THOMAS"},"Address":{"City":"RICHMOND","Zip5":"23220","State":"VA","StreetName":"STUART","UnitNumber":"1","StreetNumber":"300","StreetSuffix":"AVE","StreetAddress1":"3000 STUART AVE APT 1","UnitDesignation":"APT"}},"VerifiedInput":{"DOB":{"Day":"XX","Year":"1986","Month":"04"},"SSN":"61252xxxx","Name":{"Last":"NICHOLAS","First":"THOMAS"},"Address":{"City":"RICHMOND","Zip4":"2186","Zip5":"23220","State":"VA","StreetName":"STUART","UnitNumber":"1","StreetNumber":"3000","StreetSuffix":"AVE","StreetAddress1":"3000 STUART AVE","UnitDesignation":"APT"},"HomePhone":"8043563199"},"ComprehensiveVerification":{"ComprehensiveVerificationIndex":50,"PotentialFollowupActions":{"FollowupAction":[{"RiskCode":"B","Description":"Verify name with Social (via SSN card, DL if applicable, paycheck stub, or other Government Issued ID)"},{"RiskCode":"C","Description":"Verify name with Address (via DL, utility bill, Directory Assistance, paycheck stub, or other Government Issued ID)"}]},"RiskIndicators":{"RiskIndicator":[{"RiskCode":"PA","Sequence":1,"Description":"Potential address discrepancy - the Input address may be previous address"},{"RiskCode":"SD","Sequence":2,"Description":"The input address state is different than LN best address on file"},{"RiskCode":"10","Sequence":3,"Description":"The input phone number is a mobile number"}]}},"NameAddressPhone":{"Summary":12},"AddressPOBox":false,"SSNFoundForLexID":true,"AddressCMRA":false,"DOBMatchLevel":8,"PassportValidated":false,"InstantIDVersion":"1","ChronologyHistories":{"ChronologyHistory":[{"Address":{"City":"RICHMOND","Zip4":"2186","Zip5":"23220","State":"VA","StreetName":"STUART","UnitNumber":"1","StreetNumber":"300","StreetSuffix":"AVE","StreetAddress1":"3000 STUART AVE APT 1","UnitDesignation":"APT"},"DateLastSeen":{"Year":"2015","Month":"07"},"DateFirstSeen":{"Year":"2007","Month":"09"},"IsBestAddress":true},{"Phone":"8043563199","Address":{"City":"FORT WASHINGTON","Zip4":"4851","Zip5":"20749","State":"MD","StreetAddress1":"PO BOX 44851"},"DateLastSeen":{"Year":"2013","Month":"07"},"DateFirstSeen":{"Year":"1999","Month":"02"}},{"Phone":"8043563199","Address":{"City":"FREDERICKSBURG","Zip4":"6495","Zip5":"22406","State":"VA","StreetAddress1":"606 ENGLAND POINTE DR"},"DateLastSeen":{"Year":"2013","Month":"07"},"DateFirstSeen":{"Year":"2000","Month":"05"}}]},"DOBVerified":true,"WatchLists":{"WatchList":[]}}}}]},"formatted_responses":{"Lexis Nexis Instant ID":{"matching":{"name":{"score":1,"matched":true},"address":{"score":1,"matched":true},"ssn":{"score":1,"matched":true},"dob":{"score":1,"matched":true},"phone":{"score":1,"matched":true}},"diligence":{"watchlists":{"lists":["BES","CFTC","DTC","EUDT","FBI","FCEN","FAR","IMW","OFAC","OCC","OSFI","PEP","SDT","UNNT","BIS","WBIF"],"matches":[]},"fraud":{"score":null,"flags":null},"financial":{"credit":null,"banking":null},"identity_questions":null},"data":{"identity_theft_risk":1,"risk_codes":["PA","SD","10"],"followup_codes":[],"address":{"po_box":false,"commercial_mail":false},"ssn":{"issuance_start_date":"1977-01-1","issuance_end_date":"1979-12-1","issuance_state":"VIRGINIA"},"reverse_phone":{"name_first":"THOMAS","name_last":"NICHOLAS","address_city":"RICHMOND","address_state":"VA","address_postal_code_last5":"23220"},"reverse_name_address":{"phone_number":8043563199},"verification":{"dob_day":true,"dob_month":true,"dob_year":true,"name_first_last":true,"name_first_address":true,"name_last_address":true,"name_first_phone":true,"name_last_phone":true,"name_first_ssn":true,"name_last_ssn":true,"address_phone":true,"address_ssn":true,"name_first_last_address":true,"name_first_last_phone":true,"name_first_last_ssn":true,"name_first_address_phone":true,"name_last_address_phone":true,"name_first_last_address_phone":true,"name_first_address_ssn":true,"name_last_address_ssn":true,"name_first_last_address_ssn":true}}}},"audit_archive":null}
@@ -0,0 +1 @@
1
+ {"status_code":201,"error":null,"timestamp":1488557844974,"evaluation_token":"S-ICca9HJX52eqfrAkDvij","entity_token":"P-cIoyTcsO7CFmQFBZJvSw","application_token":"dpDD6z4olOSI7N4fMCsAlKjFa7reBYhu","application_version_id":11,"summary":{"result":"success","score":1,"tags":[],"outcome":null,"services":{"Lexis Nexis Instant ID":"executed"}},"supplied":{"name_last":"Nicholas","birth_date":"1985-01-23","name_first":"Thomas","address_city":"Richmond","document_ssn":"123456789","phone_number":"18042562188","address_state":"VA","email_address":"tommy@alloy.co","address_line_1":"1717 E Test St","social_twitter":"tommyrva","address_postal_code":"23220","address_country_code":"US"},"formatted":{"name_last":"Nicholas","birth_date":"1985-01-23","name_first":"Thomas","address_city":"Richmond","document_ssn":"123456789","phone_number":"+18042562188","address_state":"VA","email_address":"tommy@alloy.co","address_line_1":"1717 E Test St","social_twitter":"tommyrva","address_postal_code":"23220","address_country_code":"US"},"matching":{"name":{"score":1,"matched":["Lexis Nexis Instant ID"],"unmatched":[]},"address":{"score":1,"matched":["Lexis Nexis Instant ID"],"unmatched":[]},"ssn":{"score":1,"matched":["Lexis Nexis Instant ID"],"unmatched":[]},"dob":{"score":1,"matched":["Lexis Nexis Instant ID"],"unmatched":[]},"phone":{"score":1,"matched":["Lexis Nexis Instant ID"],"unmatched":[]}},"diligence":{"watchlists":{"lists":["BES","CFTC","DTC","EUDT","FBI","FCEN","FAR","IMW","OFAC","OCC","OSFI","PEP","SDT","UNNT","BIS","WBIF"],"matches":[]},"fraud":null,"financial":null,"identity_questions":null},"related_data":{},"raw_responses":{"Lexis Nexis Instant ID":[{"response":{"Header":{"Status":0,"TransactionId":"0"},"Result":{"InputEcho":{"SSN":"123456789","SSNLast4":"6789","IPAddress":"192.168.0.1","Name":{"Last":"Nicholas","First":"Thomas"},"Address":{"StreetAddress1":"1717 E Test St","StreetAddress2":"APT 2L","City":"Richmond","State":"VA","Zip5":"23220"},"DOB":{"Year":1985,"Month":1,"Day":23},"Channel":null,"Passport":{"Number":"","Country":"","ExpirationDate":null,"MachineReadableLine1":"","MachineReadableLine2":""},"HomePhone":"+18042562188","OwnOrRent":null,"ApplicationDateTime":{"Day":3,"Year":2017,"Month":3,"Hour24":16,"Minute":17,"Second":24}},"UniqueId":"1567805191","NameAddressSSNSummary":12,"AdditionalScore1":0,"AdditionalScore2":0,"PhoneOfNameAddress":8043563199,"SSNInfo":{"Valid":"G","IssuedEndDate":{"Year":"1979","Month":"12"},"IssuedLocation":"VIRGINIA","IssuedStartDate":{"Year":"1977","Month":"01"}},"CurrentName":{"Last":"NICHOLAS","First":"THOMAS"},"ReversePhone":{"Name":{"Last":"NICHOLAS","First":"THOMAS"},"Address":{"City":"RICHMOND","Zip5":"23220","State":"VA","StreetName":"STUART","UnitNumber":"1","StreetNumber":"300","StreetSuffix":"AVE","StreetAddress1":"3000 STUART AVE APT 1","UnitDesignation":"APT"}},"VerifiedInput":{"DOB":{"Day":"XX","Year":"1986","Month":"04"},"SSN":"61252xxxx","Name":{"Last":"NICHOLAS","First":"THOMAS"},"Address":{"City":"RICHMOND","Zip4":"2186","Zip5":"23220","State":"VA","StreetName":"STUART","UnitNumber":"1","StreetNumber":"3000","StreetSuffix":"AVE","StreetAddress1":"3000 STUART AVE","UnitDesignation":"APT"},"HomePhone":"8043563199"},"ComprehensiveVerification":{"ComprehensiveVerificationIndex":50,"PotentialFollowupActions":{"FollowupAction":[{"RiskCode":"B","Description":"Verify name with Social (via SSN card, DL if applicable, paycheck stub, or other Government Issued ID)"},{"RiskCode":"C","Description":"Verify name with Address (via DL, utility bill, Directory Assistance, paycheck stub, or other Government Issued ID)"}]},"RiskIndicators":{"RiskIndicator":[{"RiskCode":"PA","Sequence":1,"Description":"Potential address discrepancy - the Input address may be previous address"},{"RiskCode":"SD","Sequence":2,"Description":"The input address state is different than LN best address on file"},{"RiskCode":"10","Sequence":3,"Description":"The input phone number is a mobile number"}]}},"NameAddressPhone":{"Summary":12},"AddressPOBox":false,"SSNFoundForLexID":true,"AddressCMRA":false,"DOBMatchLevel":8,"PassportValidated":false,"InstantIDVersion":"1","ChronologyHistories":{"ChronologyHistory":[{"Address":{"City":"RICHMOND","Zip4":"2186","Zip5":"23220","State":"VA","StreetName":"STUART","UnitNumber":"1","StreetNumber":"300","StreetSuffix":"AVE","StreetAddress1":"3000 STUART AVE APT 1","UnitDesignation":"APT"},"DateLastSeen":{"Year":"2015","Month":"07"},"DateFirstSeen":{"Year":"2007","Month":"09"},"IsBestAddress":true},{"Phone":"8043563199","Address":{"City":"FORT WASHINGTON","Zip4":"4851","Zip5":"20749","State":"MD","StreetAddress1":"PO BOX 44851"},"DateLastSeen":{"Year":"2013","Month":"07"},"DateFirstSeen":{"Year":"1999","Month":"02"}},{"Phone":"8043563199","Address":{"City":"FREDERICKSBURG","Zip4":"6495","Zip5":"22406","State":"VA","StreetAddress1":"606 ENGLAND POINTE DR"},"DateLastSeen":{"Year":"2013","Month":"07"},"DateFirstSeen":{"Year":"2000","Month":"05"}}]},"DOBVerified":true,"WatchLists":{"WatchList":[]}}}}]},"formatted_responses":{"Lexis Nexis Instant ID":{"matching":{"name":{"score":1,"matched":true},"address":{"score":1,"matched":true},"ssn":{"score":1,"matched":true},"dob":{"score":1,"matched":true},"phone":{"score":1,"matched":true}},"diligence":{"watchlists":{"lists":["BES","CFTC","DTC","EUDT","FBI","FCEN","FAR","IMW","OFAC","OCC","OSFI","PEP","SDT","UNNT","BIS","WBIF"],"matches":[]},"fraud":{"score":null,"flags":null},"financial":{"credit":null,"banking":null},"identity_questions":null},"data":{"identity_theft_risk":1,"risk_codes":["PA","SD","10"],"followup_codes":[],"address":{"po_box":false,"commercial_mail":false},"ssn":{"issuance_start_date":"1977-01-1","issuance_end_date":"1979-12-1","issuance_state":"VIRGINIA"},"reverse_phone":{"name_first":"THOMAS","name_last":"NICHOLAS","address_city":"RICHMOND","address_state":"VA","address_postal_code_last5":"23220"},"reverse_name_address":{"phone_number":8043563199},"verification":{"dob_day":true,"dob_month":true,"dob_year":true,"name_first_last":true,"name_first_address":true,"name_last_address":true,"name_first_phone":true,"name_last_phone":true,"name_first_ssn":true,"name_last_ssn":true,"address_phone":true,"address_ssn":true,"name_first_last_address":true,"name_first_last_phone":true,"name_first_last_ssn":true,"name_first_address_phone":true,"name_last_address_phone":true,"name_first_last_address_phone":true,"name_first_address_ssn":true,"name_last_address_ssn":true,"name_first_last_address_ssn":true}}}},"audit_archive":null}
@@ -0,0 +1,28 @@
1
+ require "faraday"
2
+ require "json"
3
+ require "base64"
4
+ require "ostruct"
5
+
6
+ require "alloy/kyc/version"
7
+ require "alloy/kyc/configuration"
8
+ require "alloy/kyc/bearer_token"
9
+ require "alloy/kyc/evaluation"
10
+ require 'alloy/kyc/backends/remote'
11
+ require 'alloy/kyc/backends/mock'
12
+
13
+ module Alloy
14
+ module KYC
15
+ class << self
16
+ attr_accessor :configuration
17
+ end
18
+
19
+ def self.configure
20
+ self.configuration ||= Configuration.new
21
+ yield(configuration) if block_given?
22
+ end
23
+
24
+ def self.mock_mode!
25
+ self.configuration.backend = Alloy::KYC::Backends::Mock.new
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,90 @@
1
+ module Alloy
2
+
3
+ module KYC
4
+
5
+ module Backends
6
+
7
+ class Mock
8
+
9
+ attr_accessor :bearer_token, :database
10
+
11
+ def initialize
12
+ @database = generate_fake_data
13
+ nil
14
+ end
15
+
16
+ def get_bearer_token
17
+ @bearer_token = BearerToken.new("access_token", Time.now + (60*60*24*365))
18
+ end
19
+
20
+ def requires_bearer_token?
21
+ bearer_token.nil? || bearer_token.expired?
22
+ end
23
+
24
+ def create_evaluation(params)
25
+ if !params[:document_ssn].nil? && params[:document_ssn] == "111223333"
26
+ wrap_in_struct(database[:create_evaluations][:requires_oow])
27
+ else
28
+ wrap_in_struct(database[:create_evaluations][:success])
29
+ end
30
+ end
31
+
32
+ def submit_oow_responses(path, responses)
33
+ if responses[:document_ssn] == "111223333"
34
+ wrap_in_struct(database[:submit_oow_responses][:requires_oow])
35
+ else
36
+ wrap_in_struct(database[:submit_oow_responses][:success])
37
+ end
38
+ end
39
+
40
+ def fork_evaluation(path)
41
+ wrap_in_struct(database[:fork_evaluation][:success])
42
+ end
43
+
44
+ private
45
+
46
+ def wrap_in_struct(hash)
47
+ json = hash.to_json
48
+ OpenStruct.new(raw_response: json, body: json)
49
+ end
50
+
51
+ def generate_fake_data
52
+ {
53
+ create_evaluations: {
54
+ success: fake_create_evaluations_response_success,
55
+ requires_oow: fake_create_evaluations_response_requires_oow
56
+ },
57
+ submit_oow_responses: {
58
+ success: fake_create_evaluations_response_success,
59
+ requires_oow: fake_create_evaluations_response_requires_oow
60
+ },
61
+ fork_evaluation: {
62
+ success: fake_fork_response_success
63
+ }
64
+ }
65
+ end
66
+
67
+ def fake_fork_response_success
68
+ load_mock_data("fake_fork_response_success.json")
69
+ end
70
+
71
+ def fake_create_evaluations_response_requires_oow
72
+ load_mock_data("fake_create_evaluations_response_requires_oow.json")
73
+ end
74
+
75
+ def fake_create_evaluations_response_success
76
+ load_mock_data("fake_create_evaluations_response_success.json")
77
+ end
78
+
79
+ def load_mock_data(filename)
80
+ # Would use Gem.datadir, but https://github.com/rubygems/rubygems/issues/1673
81
+ JSON.parse(File.read(Gem.loaded_specs['alloy-kyc'].full_gem_path + "/data/#{filename}"))
82
+ end
83
+
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+
90
+ end
@@ -0,0 +1,61 @@
1
+ module Alloy
2
+ module KYC
3
+ module Backends
4
+ class Remote
5
+
6
+ attr_reader :bearer_token
7
+
8
+ def conn
9
+ @conn ||= Faraday.new(url: "#{Alloy::KYC.configuration.api_endpoint}")
10
+ end
11
+
12
+ def get_bearer_token
13
+ conn.basic_auth(Alloy::KYC.configuration.application_token, Alloy::KYC.configuration.application_secret)
14
+ response = conn.post("/oauth/bearer")
15
+ token_info = JSON.parse(response.body)
16
+ @bearer_token = BearerToken.new(token_info["access_token"], token_info["expires_in"])
17
+ end
18
+
19
+ def requires_bearer_token?
20
+ bearer_token.nil? || bearer_token.expired?
21
+ end
22
+
23
+ def set_auth_header
24
+ if requires_bearer_token?
25
+ conn.authorization("Bearer", get_bearer_token.token)
26
+ end
27
+ end
28
+
29
+ # domain methods
30
+ def create_evaluation(params)
31
+ post("/evaluations", params)
32
+ end
33
+
34
+ def submit_oow_responses(path, responses)
35
+ patch(path, responses)
36
+ end
37
+
38
+ def fork_evaluation(path)
39
+ post(path)
40
+ end
41
+
42
+ # http-level methods
43
+ def get(url, options={})
44
+ set_auth_header
45
+ conn.get(url, options)
46
+ end
47
+
48
+ def post(url, params={})
49
+ set_auth_header
50
+ conn.post(url, params)
51
+ end
52
+
53
+ def patch(url, params={})
54
+ set_auth_header
55
+ conn.patch(url, params)
56
+ end
57
+
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,16 @@
1
+ module Alloy
2
+ module KYC
3
+ class BearerToken
4
+ attr_accessor :token, :expires_at
5
+
6
+ def initialize(access_token, expires_in)
7
+ @token = access_token
8
+ @expires_at = Time.now + expires_in
9
+ end
10
+
11
+ def expired?
12
+ Time.now > expires_at
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ module Alloy
2
+ module KYC
3
+ class Configuration
4
+ attr_accessor :application_token
5
+ attr_accessor :application_secret
6
+ attr_accessor :api_endpoint
7
+ attr_accessor :backend
8
+
9
+ def initialize
10
+ @application_token = "dpDD6z4olOSI7N4fMCsAlKjFa7reBYhu"
11
+ @application_secret = "oJm3niQX1Pdy4z675kefEIKBgFn9tQ45"
12
+ @api_endpoint = "https://sandbox.alloy.co/v1"
13
+ @backend = Alloy::KYC::Backends::Remote.new
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,47 @@
1
+ module Alloy
2
+ module KYC
3
+ class Evaluation < OpenStruct
4
+
5
+ def self.create(params)
6
+ response = Alloy::KYC.configuration.backend.create_evaluation(params)
7
+ new(JSON.parse(response.body))
8
+ end
9
+
10
+ def initialize(response)
11
+ super(response)
12
+ self.raw_response = response
13
+ end
14
+
15
+ def success?
16
+ summary["result"] == "success" && status_code != 206
17
+ end
18
+
19
+ def partial_success?
20
+ summary["result"] == "success" && status_code == 206
21
+ end
22
+
23
+ def requires_oow?
24
+ !!self.required
25
+ end
26
+
27
+ # responses should be in the format:
28
+ # {answers: [
29
+ # {question_id: 1, answer_id: 2},
30
+ # {question_id: 2, answer_id: 4},
31
+ # ....
32
+ # ],
33
+ # name_first: "Charles",
34
+ # name_last: "Hearn"}
35
+ def submit_oow_responses(responses)
36
+ response = Alloy::KYC.configuration.backend.submit_oow_responses("/evaluations/#{self.evaluation_token}", responses)
37
+ self.class.new(JSON.parse(response.body))
38
+ end
39
+
40
+ def fork
41
+ response = Alloy::KYC.configuration.backend.fork_evaluation("/evaluations/#{self.evaluation_token}")
42
+ self.class.new(JSON.parse(response.body))
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,5 @@
1
+ module Alloy
2
+ module KYC
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,177 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: alloy-kyc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Doug Ramsay
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-04-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: vcr
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
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: webmock
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: byebug
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: faraday
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
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: json
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: Gem to wrap the Alloy.co API
126
+ email:
127
+ - doug@qedinvestors.com
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - ".gitignore"
133
+ - ".rspec"
134
+ - ".travis.yml"
135
+ - CHANGELOG.md
136
+ - Gemfile
137
+ - LICENSE.txt
138
+ - README.md
139
+ - Rakefile
140
+ - alloy-kyc.gemspec
141
+ - bin/console
142
+ - bin/setup
143
+ - data/fake_create_evaluations_response_requires_oow.json
144
+ - data/fake_create_evaluations_response_success.json
145
+ - data/fake_fork_response_success.json
146
+ - lib/alloy/kyc.rb
147
+ - lib/alloy/kyc/backends/mock.rb
148
+ - lib/alloy/kyc/backends/remote.rb
149
+ - lib/alloy/kyc/bearer_token.rb
150
+ - lib/alloy/kyc/configuration.rb
151
+ - lib/alloy/kyc/evaluation.rb
152
+ - lib/alloy/kyc/version.rb
153
+ homepage: https://github.com/qedinvestors/alloy-kyc
154
+ licenses:
155
+ - MIT
156
+ metadata: {}
157
+ post_install_message:
158
+ rdoc_options: []
159
+ require_paths:
160
+ - lib
161
+ required_ruby_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ required_rubygems_version: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - ">="
169
+ - !ruby/object:Gem::Version
170
+ version: '0'
171
+ requirements: []
172
+ rubyforge_project:
173
+ rubygems_version: 2.5.1
174
+ signing_key:
175
+ specification_version: 4
176
+ summary: Gem to wrap the Alloy.co API
177
+ test_files: []