liquid-credit 0.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b80e2a750cc16da7817f4fa45b3b99f91737bdff
4
+ data.tar.gz: 24e06da146530d832988cb4c06ea77bd103d416f
5
+ SHA512:
6
+ metadata.gz: eedfaee400ce3a1d3e29ed4d5bb28436d6eacecd00b023571c7b6e72ae24f169f44f5638cee57fe890a867845c16d50abee9f2809d32aa2753b8fdc44bfd0de5
7
+ data.tar.gz: 38b7a7f111b09b6fd5883ee76952e8e715c509af3b053d216d93943d50db3309a28260f68cdaa896444ba9d38811c4c6c9c3f53c2d0380b8db40ab6755b2e88b
@@ -0,0 +1,4 @@
1
+ .bundle/
2
+ log/*.log
3
+ spec/keys
4
+ .env
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --color
2
+ --format doc
3
+ --tag ~skip
4
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,27 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Declare your gem's dependencies in liquid_credit.gemspec.
4
+ # Bundler will treat runtime dependencies like base dependencies, and
5
+ # development dependencies will be added by default to the :development group.
6
+ gemspec
7
+
8
+ # Declare any dependencies that are still in development here instead of in
9
+ # your gemspec. These might include edge Rails or gems from your path or
10
+ # Git. Remember to move these dependencies to your gemspec before releasing
11
+ # your gem to rubygems.org.
12
+
13
+ # To use a debugger
14
+ # gem 'byebug', group: [:development, :test]
15
+
16
+ group :development, :test do
17
+ gem "guard-rspec"
18
+ gem 'rspec-collection_matchers'
19
+ # gem 'rspec-its'
20
+ gem 'equivalent-xml'
21
+ end
22
+
23
+ gem 'savon', '~> 2.10.0'
24
+ gem 'builder', '~> 3.1'
25
+ gem 'dotenv'
26
+ gem 'excon'
27
+ gem 'httpi', git: 'https://github.com/savonrb/httpi.git'
@@ -0,0 +1,128 @@
1
+ GIT
2
+ remote: https://github.com/savonrb/httpi.git
3
+ revision: a56015b3b82da1424989dc4d0393a979ddfcdb9c
4
+ specs:
5
+ httpi (2.4.1)
6
+ rack
7
+ socksify
8
+
9
+ PATH
10
+ remote: .
11
+ specs:
12
+ liquid-credit (0.0.1)
13
+ builder (~> 3.1)
14
+ savon (~> 2.10)
15
+
16
+ GEM
17
+ remote: https://rubygems.org/
18
+ specs:
19
+ akami (1.3.1)
20
+ gyoku (>= 0.4.0)
21
+ nokogiri
22
+ builder (3.2.2)
23
+ celluloid (0.16.0)
24
+ timers (~> 4.0.0)
25
+ coderay (1.1.0)
26
+ diff-lcs (1.2.5)
27
+ dotenv (2.0.1)
28
+ equivalent-xml (0.6.0)
29
+ nokogiri (>= 1.4.3)
30
+ excon (0.45.3)
31
+ ffi (1.9.8)
32
+ formatador (0.2.5)
33
+ guard (2.12.5)
34
+ formatador (>= 0.2.4)
35
+ listen (~> 2.7)
36
+ lumberjack (~> 1.0)
37
+ nenv (~> 0.1)
38
+ notiffany (~> 0.0)
39
+ pry (>= 0.9.12)
40
+ shellany (~> 0.0)
41
+ thor (>= 0.18.1)
42
+ guard-compat (1.2.1)
43
+ guard-rspec (4.5.0)
44
+ guard (~> 2.1)
45
+ guard-compat (~> 1.1)
46
+ rspec (>= 2.99.0, < 4.0)
47
+ gyoku (1.3.1)
48
+ builder (>= 2.1.2)
49
+ hitimes (1.2.2)
50
+ listen (2.10.0)
51
+ celluloid (~> 0.16.0)
52
+ rb-fsevent (>= 0.9.3)
53
+ rb-inotify (>= 0.9)
54
+ lumberjack (1.0.9)
55
+ macaddr (1.7.1)
56
+ systemu (~> 2.6.2)
57
+ method_source (0.8.2)
58
+ mini_portile (0.6.2)
59
+ nenv (0.2.0)
60
+ nokogiri (1.6.6.2)
61
+ mini_portile (~> 0.6.0)
62
+ nori (2.6.0)
63
+ notiffany (0.0.6)
64
+ nenv (~> 0.1)
65
+ shellany (~> 0.0)
66
+ pry (0.10.1)
67
+ coderay (~> 1.1.0)
68
+ method_source (~> 0.8.1)
69
+ slop (~> 3.4)
70
+ rack (1.6.4)
71
+ rb-fsevent (0.9.4)
72
+ rb-inotify (0.9.5)
73
+ ffi (>= 0.5.0)
74
+ rspec (3.2.0)
75
+ rspec-core (~> 3.2.0)
76
+ rspec-expectations (~> 3.2.0)
77
+ rspec-mocks (~> 3.2.0)
78
+ rspec-collection_matchers (1.1.2)
79
+ rspec-expectations (>= 2.99.0.beta1)
80
+ rspec-core (3.2.3)
81
+ rspec-support (~> 3.2.0)
82
+ rspec-expectations (3.2.1)
83
+ diff-lcs (>= 1.2.0, < 2.0)
84
+ rspec-support (~> 3.2.0)
85
+ rspec-mocks (3.2.1)
86
+ diff-lcs (>= 1.2.0, < 2.0)
87
+ rspec-support (~> 3.2.0)
88
+ rspec-support (3.2.2)
89
+ savon (2.10.1)
90
+ akami (~> 1.2)
91
+ builder (>= 2.1.2)
92
+ gyoku (~> 1.2)
93
+ httpi (~> 2.3)
94
+ nokogiri (>= 1.4.0)
95
+ nori (~> 2.4)
96
+ uuid (~> 2.3.7)
97
+ wasabi (~> 3.4)
98
+ shellany (0.0.1)
99
+ slop (3.6.0)
100
+ socksify (1.7.0)
101
+ systemu (2.6.5)
102
+ thor (0.19.1)
103
+ timers (4.0.1)
104
+ hitimes
105
+ uuid (2.3.8)
106
+ macaddr (~> 1.0)
107
+ wasabi (3.5.0)
108
+ httpi (~> 2.0)
109
+ nokogiri (>= 1.4.2)
110
+
111
+ PLATFORMS
112
+ ruby
113
+
114
+ DEPENDENCIES
115
+ builder (~> 3.1)
116
+ bundler (~> 1.7)
117
+ dotenv
118
+ equivalent-xml
119
+ excon
120
+ guard-rspec
121
+ httpi!
122
+ liquid-credit!
123
+ rspec (~> 3.2)
124
+ rspec-collection_matchers
125
+ savon (~> 2.10.0)
126
+
127
+ BUNDLED WITH
128
+ 1.10.4
@@ -0,0 +1,18 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ # Note: The cmd option is now required due to the increasing number of ways
5
+ # rspec may be run, below are examples of the most common uses.
6
+ # * bundler: 'bundle exec rspec'
7
+ # * bundler binstubs: 'bin/rspec'
8
+ # * spring: 'bin/rsspec' (This will use spring if running and you have
9
+ # installed the spring binstubs per the docs)
10
+ # * zeus: 'zeus rspec' (requires the server to be started separetly)
11
+ # * 'just' rspec: 'rspec'
12
+ guard :rspec, cmd: "rspec" do
13
+ watch(%r{^spec/.+_spec\.rb$})
14
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
15
+ watch('spec/spec_helper.rb') { "spec" }
16
+
17
+ end
18
+
@@ -0,0 +1,20 @@
1
+ Copyright 2015 Drew Nichols
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,44 @@
1
+
2
+ # liquid-credit
3
+
4
+ liquid-credit is a ruby gem client for the Fico LiquidCredit API. It's currently a work in progress and supports only very limited API functionality.
5
+
6
+ [ ![Codeship Status for liftforward/liquid-credit](https://codeship.io/projects/22c1c960-42ab-0133-38f3-1eb5f82d52fc/status)](https://codeship.io/projects/103811)
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'liquid-credit'
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle install
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install liquid-credit
23
+
24
+ ## Usage
25
+
26
+ ### Configuration
27
+
28
+ TODO
29
+
30
+ ### Working with the API
31
+
32
+ TODO
33
+
34
+ ### Running integration suite
35
+
36
+ TODO
37
+
38
+ ## Contributing
39
+
40
+ 1. Fork it ( https://github.com/liftforward/liquid-credit/fork )
41
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
42
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
43
+ 4. Push to the branch (`git push origin my-new-feature`)
44
+ 5. Create a new Pull Request
@@ -0,0 +1,3 @@
1
+ = LiquidCredit
2
+
3
+ This project rocks and uses MIT-LICENSE.
@@ -0,0 +1,20 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new "spec:unit" do |t|
5
+ t.pattern = "spec/liquid_credit/**/*_spec.rb"
6
+ end
7
+
8
+ desc "Run RSpec integration examples"
9
+ RSpec::Core::RakeTask.new "spec:integration" do |t|
10
+ t.pattern = "spec/integration/**/*_spec.rb"
11
+ end
12
+
13
+ task :test do
14
+ Rake::Task["spec:unit"].invoke
15
+ Rake::Task["spec:integration"].invoke
16
+ end
17
+
18
+ task :default do
19
+ Rake::Task["test"].invoke
20
+ end
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'savon'
3
+
4
+ require File.dirname(__FILE__) + "/liquid_credit/version"
5
+ require File.dirname(__FILE__) + "/liquid_credit/config"
6
+ require File.dirname(__FILE__) + "/liquid_credit/client"
7
+ require File.dirname(__FILE__) + "/liquid_credit/base_response"
8
+ require File.dirname(__FILE__) + "/liquid_credit/lookup_business_response"
9
+ require File.dirname(__FILE__) + "/liquid_credit/obtain_decision_data_response"
@@ -0,0 +1,22 @@
1
+ module LiquidCredit
2
+ class BaseResponse
3
+ attr_reader :raw_response_xml
4
+
5
+ def initialize xml
6
+ @raw_response_xml= Nokogiri::XML(xml)
7
+ end
8
+
9
+
10
+ # base_response.xml= Nokogiri::XML(raw_response_xml.xpath("//lq:ObtainDecisionDataResult", "lq" => "http://www.liquidCredit.com/").text)
11
+
12
+ # def xml
13
+ # @xml ||= Nokogiri::XML(@parsed_xml.xpath("//lq:ObtainDecisionDataResult", "lq" => "http://www.liquidCredit.com/").text)
14
+ # end
15
+
16
+ def nori
17
+ @nori ||= Nori.new(:convert_tags_to => lambda { |tag| tag.snakecase.to_sym })
18
+ end
19
+ end
20
+ end
21
+
22
+
@@ -0,0 +1,173 @@
1
+ require 'savon'
2
+ require 'logger'
3
+
4
+ module LiquidCredit
5
+ class Client
6
+ attr_accessor :options, :credit_agency_auth
7
+
8
+
9
+ def initialize options = {}, credit_agency_auth = {}
10
+ configure_defaults
11
+ configure options, credit_agency_auth
12
+ end
13
+
14
+ def configure_defaults
15
+ self.options = {
16
+ wsdl: 'https://liquidcredit.cqa.ficoanalyticcloud.com/liquidcredit/liquidCredit.wsdl',
17
+ soap_version: 2,
18
+ ssl_cert: LiquidCredit::Config.ssl_cert,
19
+ ssl_cert_key: LiquidCredit::Config.ssl_cert_key,
20
+ basic_auth: [LiquidCredit::Config.basic_auth_user, LiquidCredit::Config.basic_auth_password],
21
+ logger: LiquidCredit::Config.logger
22
+ }
23
+
24
+ #TODO refactor this so that we can support D&B as well
25
+ self.credit_agency_auth = {
26
+ experian_bis_operator_initials: LiquidCredit::Config.experian_bis_operator_initials,
27
+ experian_bis_operator_sub_code: LiquidCredit::Config.experian_bis_operator_sub_code,
28
+ experian_bis_customer_id: LiquidCredit::Config.experian_bis_customer_id,
29
+ experian_bis_connection_username: LiquidCredit::Config.experian_bis_connection_username,
30
+ experian_bis_connection_password: LiquidCredit::Config.experian_bis_connection_password,
31
+ experian_bis_operator_initials: LiquidCredit::Config.experian_bis_operator_initials,
32
+ experian_bis_operator_sub_code: LiquidCredit::Config.experian_bis_operator_sub_code,
33
+ experian_con_connection_username: LiquidCredit::Config.experian_con_connection_username,
34
+ experian_con_connection_password: LiquidCredit::Config.experian_con_connection_password,
35
+ experian_con_preamble: LiquidCredit::Config.experian_con_preamble,
36
+ experian_con_operator_initials: LiquidCredit::Config.experian_con_operator_initials,
37
+ experian_con_subcode: LiquidCredit::Config.experian_con_subcode
38
+ }
39
+ end
40
+
41
+ def configure opts = {}, credit_agency_auth = {}
42
+ opts.keys.each do |k|
43
+ self.options[k] = options[k]
44
+ end
45
+
46
+ credit_agency_auth.keys.each do |k|
47
+ self.credit_agency_auth[k] = credit_agency_auth[k]
48
+ end
49
+
50
+ if self.options[:ssl_cert].class == String
51
+ self.options[:ssl_cert] = OpenSSL::X509::Certificate.new(self.options[:ssl_cert])
52
+ end
53
+
54
+ if self.options[:ssl_cert_key].class == String
55
+ self.options[:ssl_cert_key] = OpenSSL::PKey.read(self.options[:ssl_cert_key])
56
+ end
57
+ end
58
+
59
+ def client
60
+ @client ||= Savon.client(self.options)
61
+ end
62
+
63
+ def logger
64
+ client.globals[:logger]
65
+ end
66
+
67
+ def call operation, message
68
+ client.globals.headers({'Content-Type' => "application/soap+xml;charset=UTF-8;action=\"http://www.liquidCredit.com/#{operation.to_s.split('_').collect(&:capitalize).join}\""})
69
+
70
+ response = client.call operation, message
71
+ end
72
+
73
+ #todo ensure namespace matches and why is this necessary?
74
+ def wrap_message message
75
+ "<tns:inputPayload><![CDATA[#{message}]]></tns:inputPayload>"
76
+ end
77
+
78
+ def obtain_decision_data principals, business
79
+ message = wrap_message(obtain_decision_data_message_xml principals, business)
80
+ LiquidCredit::ObtainDecisionDataResponse.new self.call(:obtain_decision_data, message: message).to_s
81
+ end
82
+
83
+ def obtain_decision_data_message_xml principals, business, options = {}
84
+ builder = Builder::XmlMarkup.new(indent: 2)
85
+ #TODO determine how to handle submission_xref_id
86
+ #TODO parameterize product_category_id
87
+ builder.FI_LiquidCredit submission_xref_id: "456789321", product_category_id: "2200", customer_id:@credit_agency_auth[:experian_bis_customer_id] do
88
+ builder.loan_purpose options[:loan_purpose]
89
+ builder.principal_list do
90
+ principals.each_with_index do |principal, i|
91
+ builder.principal_info customer_xref_id: i do
92
+ builder.dataSourceList rawDataRequestFlag:"Y", printImageRequestFlag:"Y" do
93
+ #TODO split dataSource element into separate method
94
+ builder.dataSource priority: "primary",
95
+ code: "XPN",
96
+ score1Model: "I",
97
+ connectionUsername: @credit_agency_auth[:experian_con_connection_username],
98
+ connectionPassword: @credit_agency_auth[:experian_con_connection_password] do
99
+ builder.request do
100
+ builder.subscriber_id "#{@credit_agency_auth[:experian_con_preamble]}-#{@credit_agency_auth[:experian_con_operator_initials]}-#{@credit_agency_auth[:experian_con_subcode]}"
101
+ builder.permissible_purpose_code "02"
102
+ end
103
+ end
104
+ end
105
+ builder.first_name principal[:first_name]
106
+ builder.last_name principal[:last_name]
107
+ builder.SSN principal[:ssn]
108
+ builder.current_address do
109
+ builder.address principal[:current_address][:street]
110
+ builder.city principal[:current_address][:city]
111
+ builder.state principal[:current_address][:state]
112
+ builder.zip principal[:current_address][:zip]
113
+ end
114
+ end
115
+ end
116
+ end
117
+ builder.business_info business_xref_id:"123", scoring_model_suite_type:"700" do
118
+ builder.dataSourceList rawDataRequestFlag:"Y", printImageRequestFlag:"Y" do
119
+ builder.dataSource code:"XPB",
120
+ rptSelectionId: business[:rpt_selection_id],
121
+ connectionUsername:"#{@credit_agency_auth[:experian_bis_connection_username]}",
122
+ connectionPassword:"#{@credit_agency_auth[:experian_bis_connection_password]}" do
123
+ builder.request do
124
+ builder.business_subscriber_num "#{@credit_agency_auth[:experian_bis_operator_initials]}-#{@credit_agency_auth[:experian_bis_operator_sub_code]}"
125
+ end
126
+ end
127
+ end
128
+ builder.business_legal_name business[:name]
129
+ builder.business_address business[:street]
130
+ builder.business_city business[:city]
131
+ builder.business_state business[:state]
132
+ builder.business_zip business[:zip]
133
+ builder.business_phone business[:phone]
134
+ builder.fed_tax_id business[:tax_id]
135
+ end
136
+ end
137
+
138
+ builder.target!
139
+ end
140
+
141
+ def lookup_business business
142
+ message = wrap_message(lookup_business_message_xml business)
143
+ LiquidCredit::LookupBusinessResponse.new self.call(:lookup_business, message: message).to_s
144
+ end
145
+
146
+ def lookup_business_message_xml business
147
+ builder = Builder::XmlMarkup.new(indent: 2)
148
+
149
+ builder.FI_LiquidCredit submission_xref_id: "123", APIVersion: "2", customer_id:@credit_agency_auth[:experian_bis_customer_id] do
150
+ builder.business_info business_xref_id:"123" do
151
+ builder.dataSourceList rawDataRequestFlag:"Y" do
152
+ builder.dataSource code:"XPB",
153
+ connectionUsername:"#{@credit_agency_auth[:experian_bis_connection_username]}",
154
+ connectionPassword:"#{@credit_agency_auth[:experian_bis_connection_password]}" do
155
+ builder.request do
156
+ builder.business_subscriber_num "#{@credit_agency_auth[:experian_bis_operator_initials]}-#{@credit_agency_auth[:experian_bis_operator_sub_code]}"
157
+ end
158
+ end
159
+ end
160
+ builder.business_legal_name business[:name] unless business[:name].nil?
161
+ builder.business_address business[:street] unless business[:street].nil?
162
+ builder.business_city business[:city] unless business[:city].nil?
163
+ builder.business_state business[:state] unless business[:state].nil?
164
+ builder.business_zip business[:zip] unless business[:zip].nil?
165
+ builder.business_phone business[:phone] unless business[:phone].nil?
166
+ builder.fed_tax_id business[:tax_id] unless business[:tax_id].nil?
167
+ end
168
+ end
169
+
170
+ builder.target!
171
+ end
172
+ end
173
+ end