LitleOnline 8.10.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.
- data/DESCRIPTION +5 -0
- data/LICENSE +22 -0
- data/README.md +69 -0
- data/Rakefile +92 -0
- data/SETUP.md +47 -0
- data/bin/Setup.rb +103 -0
- data/bin/sample_driver.rb +49 -0
- data/index.html +176 -0
- data/index.html.1 +176 -0
- data/lib/Checker.rb +56 -0
- data/lib/Communications.rb +85 -0
- data/lib/Configuration.rb +45 -0
- data/lib/LitleOnline.rb +52 -0
- data/lib/LitleOnlineRequest.rb +399 -0
- data/lib/LitleXmlMapper.rb +48 -0
- data/lib/Obj2xml.rb +37 -0
- data/lib/XMLFields.rb +378 -0
- data/test/certification/certTest1_base.rb +948 -0
- data/test/certification/certTest2_authenhanced.rb +571 -0
- data/test/certification/certTest3_authreversal.rb +184 -0
- data/test/certification/certTest4_echeck.rb +279 -0
- data/test/certification/certTest5_token.rb +222 -0
- data/test/certification/ts_all.rb +31 -0
- data/test/functional/test_auth.rb +135 -0
- data/test/functional/test_authReversal.rb +68 -0
- data/test/functional/test_capture.rb +71 -0
- data/test/functional/test_captureGivenAuth.rb +161 -0
- data/test/functional/test_credit.rb +154 -0
- data/test/functional/test_echeckCredit.rb +116 -0
- data/test/functional/test_echeckRedeposit.rb +78 -0
- data/test/functional/test_echeckSale.rb +157 -0
- data/test/functional/test_echeckVerification.rb +92 -0
- data/test/functional/test_forceCapture.rb +105 -0
- data/test/functional/test_sale.rb +198 -0
- data/test/functional/test_token.rb +102 -0
- data/test/functional/test_xmlfields.rb +403 -0
- data/test/functional/ts_all.rb +39 -0
- data/test/unit/test_Checker.rb +58 -0
- data/test/unit/test_LitleOnlineRequest.rb +288 -0
- data/test/unit/test_auth.rb +168 -0
- data/test/unit/test_authReversal.rb +41 -0
- data/test/unit/test_capture.rb +40 -0
- data/test/unit/test_captureGivenAuth.rb +108 -0
- data/test/unit/test_credit.rb +117 -0
- data/test/unit/test_echeckCredit.rb +45 -0
- data/test/unit/test_echeckRedeposit.rb +76 -0
- data/test/unit/test_echeckSale.rb +45 -0
- data/test/unit/test_echeckVerification.rb +75 -0
- data/test/unit/test_forceCapture.rb +122 -0
- data/test/unit/test_sale.rb +249 -0
- data/test/unit/test_token.rb +70 -0
- data/test/unit/test_xmlfields.rb +173 -0
- data/test/unit/ts_unit.rb +41 -0
- metadata +166 -0
data/index.html.1
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<!--[if lt IE 7 ]> <html lang="en" class="no-js ie6"> <![endif]-->
|
3
|
+
<!--[if IE 7 ]> <html lang="en" class="no-js ie7"> <![endif]-->
|
4
|
+
<!--[if IE 8 ]> <html lang="en" class="no-js ie8"> <![endif]-->
|
5
|
+
<!--[if IE 9 ]> <html lang="en" class="no-js ie9"> <![endif]-->
|
6
|
+
<!--[if (gt IE 9)|!(IE)]><!--> <html lang="en" class="no-js"><!--<![endif]-->
|
7
|
+
<head>
|
8
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
9
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
10
|
+
<title>Welcome to Grails</title>
|
11
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
12
|
+
<link rel="shortcut icon" href="/sandbox/static/images/favicon.ico" type="image/x-icon">
|
13
|
+
<link rel="apple-touch-icon" href="/sandbox/static/images/apple-touch-icon.png">
|
14
|
+
<link rel="apple-touch-icon" sizes="114x114" href="/sandbox/static/images/apple-touch-icon-retina.png">
|
15
|
+
<link rel="stylesheet" href="/sandbox/static/css/main.css" type="text/css">
|
16
|
+
<link rel="stylesheet" href="/sandbox/static/css/mobile.css" type="text/css">
|
17
|
+
|
18
|
+
<meta name="layout" content="main"/>
|
19
|
+
|
20
|
+
<style type="text/css" media="screen">
|
21
|
+
#status {
|
22
|
+
background-color: #eee;
|
23
|
+
border: .2em solid #fff;
|
24
|
+
margin: 2em 2em 1em;
|
25
|
+
padding: 1em;
|
26
|
+
width: 12em;
|
27
|
+
float: left;
|
28
|
+
-moz-box-shadow: 0px 0px 1.25em #ccc;
|
29
|
+
-webkit-box-shadow: 0px 0px 1.25em #ccc;
|
30
|
+
box-shadow: 0px 0px 1.25em #ccc;
|
31
|
+
-moz-border-radius: 0.6em;
|
32
|
+
-webkit-border-radius: 0.6em;
|
33
|
+
border-radius: 0.6em;
|
34
|
+
}
|
35
|
+
|
36
|
+
.ie6 #status {
|
37
|
+
display: inline; /* float double margin fix http://www.positioniseverything.net/explorer/doubled-margin.html */
|
38
|
+
}
|
39
|
+
|
40
|
+
#status ul {
|
41
|
+
font-size: 0.9em;
|
42
|
+
list-style-type: none;
|
43
|
+
margin-bottom: 0.6em;
|
44
|
+
padding: 0;
|
45
|
+
}
|
46
|
+
|
47
|
+
#status h1 {
|
48
|
+
text-transform: uppercase;
|
49
|
+
font-size: 1.1em;
|
50
|
+
margin: 0 0 0.3em;
|
51
|
+
}
|
52
|
+
|
53
|
+
#page-body {
|
54
|
+
margin: 2em 1em 1.25em 18em;
|
55
|
+
}
|
56
|
+
|
57
|
+
h2 {
|
58
|
+
margin-top: 1em;
|
59
|
+
margin-bottom: 0.3em;
|
60
|
+
font-size: 1em;
|
61
|
+
}
|
62
|
+
|
63
|
+
p {
|
64
|
+
margin: 0.25em 0;
|
65
|
+
}
|
66
|
+
|
67
|
+
#controller-list ul {
|
68
|
+
list-style-position: inside;
|
69
|
+
}
|
70
|
+
|
71
|
+
#controller-list li {
|
72
|
+
list-style-position: inside;
|
73
|
+
margin: 0.25em 0;
|
74
|
+
}
|
75
|
+
|
76
|
+
@media screen and (max-width: 480px) {
|
77
|
+
#status {
|
78
|
+
display: none;
|
79
|
+
}
|
80
|
+
|
81
|
+
#page-body {
|
82
|
+
margin: 0 1em 1em;
|
83
|
+
}
|
84
|
+
|
85
|
+
#page-body h1 {
|
86
|
+
margin-top: 0;
|
87
|
+
}
|
88
|
+
}
|
89
|
+
</style>
|
90
|
+
|
91
|
+
|
92
|
+
</head>
|
93
|
+
<body>
|
94
|
+
<div id="grailsLogo" role="banner"><a href="http://grails.org"><img src="/sandbox/static/images/grails_logo.png" alt="Grails"/></a></div>
|
95
|
+
|
96
|
+
<a href="#page-body" class="skip">Skip to content…</a>
|
97
|
+
<div id="status" role="complementary">
|
98
|
+
<h1>Application Status</h1>
|
99
|
+
<ul>
|
100
|
+
<li>App version: 0.1</li>
|
101
|
+
<li>Grails version: 2.0.0</li>
|
102
|
+
<li>Groovy version: 1.8.4</li>
|
103
|
+
<li>JVM version: 1.6.0_10</li>
|
104
|
+
<li>Reloading active: false</li>
|
105
|
+
<li>Controllers: 1</li>
|
106
|
+
<li>Domains: 8</li>
|
107
|
+
<li>Services: 2</li>
|
108
|
+
<li>Tag Libraries: 12</li>
|
109
|
+
</ul>
|
110
|
+
<h1>Installed Plugins</h1>
|
111
|
+
<ul>
|
112
|
+
|
113
|
+
<li>logging - 2.0.0</li>
|
114
|
+
|
115
|
+
<li>core - 2.0.0</li>
|
116
|
+
|
117
|
+
<li>i18n - 2.0.0</li>
|
118
|
+
|
119
|
+
<li>urlMappings - 2.0.0</li>
|
120
|
+
|
121
|
+
<li>groovyPages - 2.0.0</li>
|
122
|
+
|
123
|
+
<li>codecs - 2.0.0</li>
|
124
|
+
|
125
|
+
<li>servlets - 2.0.0</li>
|
126
|
+
|
127
|
+
<li>dataSource - 2.0.0</li>
|
128
|
+
|
129
|
+
<li>jquery - 1.7.1</li>
|
130
|
+
|
131
|
+
<li>resources - 1.1.5</li>
|
132
|
+
|
133
|
+
<li>controllers - 2.0.0</li>
|
134
|
+
|
135
|
+
<li>domainClass - 2.0.0</li>
|
136
|
+
|
137
|
+
<li>mimeTypes - 2.0.0</li>
|
138
|
+
|
139
|
+
<li>scaffolding - 2.0.0</li>
|
140
|
+
|
141
|
+
<li>hibernate - 2.0.0</li>
|
142
|
+
|
143
|
+
<li>filters - 2.0.0</li>
|
144
|
+
|
145
|
+
<li>validation - 2.0.0</li>
|
146
|
+
|
147
|
+
<li>converters - 2.0.0</li>
|
148
|
+
|
149
|
+
<li>services - 2.0.0</li>
|
150
|
+
|
151
|
+
</ul>
|
152
|
+
</div>
|
153
|
+
<div id="page-body" role="main">
|
154
|
+
<h1>Welcome to Grails</h1>
|
155
|
+
<p>Congratulations, you have successfully started your first Grails application! At the moment
|
156
|
+
this is the default page, feel free to modify it to either redirect to a controller or display whatever
|
157
|
+
content you may choose. Below is a list of controllers that are currently deployed in this application,
|
158
|
+
click on each to execute its default action:</p>
|
159
|
+
|
160
|
+
<div id="controller-list" role="navigation">
|
161
|
+
<h2>Available Controllers:</h2>
|
162
|
+
<ul>
|
163
|
+
|
164
|
+
<li class="controller"><a href="/sandbox/communicator/index">com.litle.sandbox.CommunicatorController</a></li>
|
165
|
+
|
166
|
+
</ul>
|
167
|
+
</div>
|
168
|
+
</div>
|
169
|
+
|
170
|
+
<div class="footer" role="contentinfo"></div>
|
171
|
+
<div id="spinner" class="spinner" style="display:none;">Loading…</div>
|
172
|
+
|
173
|
+
<script src="/sandbox/static/js/application.js" type="text/javascript" ></script>
|
174
|
+
|
175
|
+
</body>
|
176
|
+
</html>
|
data/lib/Checker.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (c) 2011 Litle & Co.
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person
|
5
|
+
obtaining a copy of this software and associated documentation
|
6
|
+
files (the "Software"), to deal in the Software without
|
7
|
+
restriction, including without limitation the rights to use,
|
8
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the
|
10
|
+
Software is furnished to do so, subject to the following
|
11
|
+
conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
18
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
20
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
21
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
22
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
23
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
=end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Used to Handle verification of Ruby Hash data
|
28
|
+
#
|
29
|
+
class Checker
|
30
|
+
#checks for empty,flagged and null hashes and deletes them
|
31
|
+
def Checker.purge_null(hash)
|
32
|
+
hash.each_key do |i|
|
33
|
+
if (hash[i] == nil or hash[i] =={} or hash[i] == 'throwFlag')
|
34
|
+
hash.delete(i)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
#checks if Required Fileds are missing and raises and error
|
40
|
+
def Checker.required_missing(hash)
|
41
|
+
hash.each_key do |i|
|
42
|
+
if hash[i] == 'REQUIRED'
|
43
|
+
raise "Missing Required Field: #{i}!!!!"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
#checks if one and only one field is filled out when given a choice between fields
|
49
|
+
def Checker.choice(hash)
|
50
|
+
hash = purge_null(hash)
|
51
|
+
if hash.length > 1
|
52
|
+
raise 'Entered an Invalid Amount of Choices for a Field, please only fill out one Choice!!!!'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (c) 2011 Litle & Co.
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person
|
5
|
+
obtaining a copy of this software and associated documentation
|
6
|
+
files (the "Software"), to deal in the Software without
|
7
|
+
restriction, including without limitation the rights to use,
|
8
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the
|
10
|
+
Software is furnished to do so, subject to the following
|
11
|
+
conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
18
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
20
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
21
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
22
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
23
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
=end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Used for all transmission to Litle over HTTP or HTTPS
|
28
|
+
# works with or without an HTTP proxy
|
29
|
+
#
|
30
|
+
# URL and proxy server settings are derived from the configuration file
|
31
|
+
#
|
32
|
+
class Communications
|
33
|
+
##For http or https post with or without a proxy
|
34
|
+
def Communications.http_post(post_data,config_hash)
|
35
|
+
|
36
|
+
#setup optional proxy
|
37
|
+
proxy_addr = (config_hash['proxy_addr'] or nil)
|
38
|
+
proxy_port = ((config_hash['proxy_port']).to_i or nil)
|
39
|
+
|
40
|
+
# setup https or http post
|
41
|
+
litle_url = (config_hash['url'] or 'https://cert.litle.com/vap/communicator/online')
|
42
|
+
uri = URI.parse(litle_url)
|
43
|
+
|
44
|
+
http_post = Net::HTTP::Post.new(uri.request_uri)
|
45
|
+
http_post.body = post_data
|
46
|
+
http_post['content-type'] = 'text/xml'
|
47
|
+
|
48
|
+
response_xml = ''
|
49
|
+
begin
|
50
|
+
proxy = Net::HTTP::Proxy(proxy_addr,proxy_port)
|
51
|
+
# See notes below on recommended time outs
|
52
|
+
proxy.start(uri.host, uri.port, :use_ssl => uri.scheme=='https', :read_timeout => config_hash['timeout']) do |http|
|
53
|
+
response_xml = http.request(http_post)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# validate response, only an HTTP 200 will work, redirects are not followed
|
58
|
+
case response_xml
|
59
|
+
when Net::HTTPOK
|
60
|
+
return response_xml.body
|
61
|
+
else
|
62
|
+
raise("Error with http http_post_request, code:" + response_xml.header.code)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
=begin
|
68
|
+
NOTES ON HTTP TIMEOUT
|
69
|
+
|
70
|
+
Litle & Co. optimizes our systems to ensure the return of responses as quickly as possible, some portions of the process are beyond our control.
|
71
|
+
The round-trip time of an Authorization can be broken down into three parts, as follows:
|
72
|
+
1. Transmission time (across the internet) to Litle & Co. and back to the merchant
|
73
|
+
2. Processing time by the authorization provider
|
74
|
+
3. Processing time by Litle
|
75
|
+
Under normal operating circumstances, the transmission time to and from Litle does not exceed 0.6 seconds
|
76
|
+
and processing overhead by Litle occurs in 0.1 seconds.
|
77
|
+
Typically, the processing time by the card association or authorization provider can take between 0.5 and 3 seconds,
|
78
|
+
but some percentage of transactions may take significantly longer.
|
79
|
+
|
80
|
+
Because the total processing time can vary due to a number of factors, Litle & Co. recommends using a minimum timeout setting of
|
81
|
+
60 seconds to accomodate Sale transactions and 30 seconds if you are not utilizing Sale tranactions.
|
82
|
+
|
83
|
+
These settings should ensure that you do not frequently disconnect prior to receiving a valid authorization causing dropped orders
|
84
|
+
and/or re-auths and duplicate auths.
|
85
|
+
=end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (c) 2011 Litle & Co.
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person
|
5
|
+
obtaining a copy of this software and associated documentation
|
6
|
+
files (the "Software"), to deal in the Software without
|
7
|
+
restriction, including without limitation the rights to use,
|
8
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the
|
10
|
+
Software is furnished to do so, subject to the following
|
11
|
+
conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
18
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
20
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
21
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
22
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
23
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
=end
|
25
|
+
|
26
|
+
require 'yaml'
|
27
|
+
|
28
|
+
#
|
29
|
+
# Loads the configuration from a file
|
30
|
+
#
|
31
|
+
class Configuration
|
32
|
+
def config
|
33
|
+
begin
|
34
|
+
if !(ENV['LITLE_CONFIG_DIR'].nil?)
|
35
|
+
config_file = ENV['LITLE_CONFIG_DIR'] + "/.litle_SDK_config.yml"
|
36
|
+
else
|
37
|
+
config_file = ENV['HOME'] + "/.litle_SDK_config.yml"
|
38
|
+
end
|
39
|
+
return YAML.load_file(config_file)
|
40
|
+
rescue
|
41
|
+
raise 'Cannot find the configuration file, ' + config_file + ', Please run Setup.rb first'
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
data/lib/LitleOnline.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (c) 2011 Litle & Co.
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person
|
5
|
+
obtaining a copy of this software and associated documentation
|
6
|
+
files (the "Software"), to deal in the Software without
|
7
|
+
restriction, including without limitation the rights to use,
|
8
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the
|
10
|
+
Software is furnished to do so, subject to the following
|
11
|
+
conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
18
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
20
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
21
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
22
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
23
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
=end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Header file containing required gems and ruby files
|
28
|
+
# Defines the Gem
|
29
|
+
#
|
30
|
+
require 'rubygems'
|
31
|
+
require 'xmlsimple'
|
32
|
+
require 'active_support/core_ext'
|
33
|
+
require 'net/http'
|
34
|
+
require 'xml-object'
|
35
|
+
require 'yaml'
|
36
|
+
require 'uri'
|
37
|
+
require 'net/https'
|
38
|
+
|
39
|
+
require_relative 'Communications'
|
40
|
+
require_relative 'Obj2xml'
|
41
|
+
require_relative 'LitleXmlMapper'
|
42
|
+
require_relative 'XMLFields'
|
43
|
+
require_relative 'Checker'
|
44
|
+
require_relative 'LitleOnlineRequest'
|
45
|
+
require_relative 'Configuration'
|
46
|
+
|
47
|
+
#allows attribute values to be in double quotes, required by Litle Server
|
48
|
+
REXML::Attribute.class_eval( %q^
|
49
|
+
def to_string
|
50
|
+
%Q[#@expanded_name="#{to_s().gsub(/"/, '"')}"]
|
51
|
+
end
|
52
|
+
^ )
|
@@ -0,0 +1,399 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (c) 2011 Litle & Co.
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person
|
5
|
+
obtaining a copy of this software and associated documentation
|
6
|
+
files (the "Software"), to deal in the Software without
|
7
|
+
restriction, including without limitation the rights to use,
|
8
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the
|
10
|
+
Software is furnished to do so, subject to the following
|
11
|
+
conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
18
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
20
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
21
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
22
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
23
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
=end
|
25
|
+
require_relative 'Configuration'
|
26
|
+
|
27
|
+
#
|
28
|
+
# This class does all the heavy lifting of mapping the Ruby hash into Litle XML format
|
29
|
+
# It also handles validation looking for missing or incorrect fields
|
30
|
+
#contains the methods to properly create each transaction type
|
31
|
+
#
|
32
|
+
class LitleOnlineRequest
|
33
|
+
def initialize
|
34
|
+
#load configuration data
|
35
|
+
@config_hash = Configuration.new.config
|
36
|
+
end
|
37
|
+
|
38
|
+
def authorization(hash_in)
|
39
|
+
hash_out = {
|
40
|
+
:litleTxnId => hash_in['litleTxnId'],
|
41
|
+
:orderId => required_field(hash_in['orderId']),
|
42
|
+
:amount =>required_field(hash_in['amount']),
|
43
|
+
:orderSource=>required_field(hash_in['orderSource']),
|
44
|
+
:customerInfo=>XMLFields.customerInfo(optional_field(hash_in['customerInfo'])),
|
45
|
+
:billToAddress=>XMLFields.contact(optional_field(hash_in['billToAddress'])),
|
46
|
+
:shipToAddress=>XMLFields.contact(optional_field(hash_in['shipToAddress'])),
|
47
|
+
:card=> XMLFields.cardType(optional_field(hash_in['card'])),
|
48
|
+
:paypal=>XMLFields.payPal(optional_field(hash_in['paypal'])),
|
49
|
+
:token=>XMLFields.cardTokenType(optional_field(hash_in['token'])),
|
50
|
+
:paypage=>XMLFields.cardPaypageType(optional_field(hash_in['paypage'])),
|
51
|
+
:billMeLaterRequest=>XMLFields.billMeLaterRequest(optional_field(hash_in['billMeLaterRequest'])),
|
52
|
+
:cardholderAuthentication=>XMLFields.fraudCheckType(optional_field(hash_in['cardholderAuthentication'])),
|
53
|
+
:processingInstructions=>XMLFields.processingInstructions(optional_field(hash_in['processingInstructions'])),
|
54
|
+
:pos=>XMLFields.pos(optional_field(hash_in['pos'])),
|
55
|
+
:customBilling=>XMLFields.customBilling(optional_field(hash_in['customBilling'])),
|
56
|
+
:taxBilling=>XMLFields.taxBilling(optional_field(hash_in['taxBilling'])),
|
57
|
+
:enhancedData=>XMLFields.enhancedData(optional_field(hash_in['enhancedData'])),
|
58
|
+
:amexAggregatorData=>XMLFields.amexAggregatorData(optional_field(hash_in['amexAggregatorData'])),
|
59
|
+
:allowPartialAuth=>hash_in['allowPartialAuth'],
|
60
|
+
:healthcareIIAS=>XMLFields.healthcareIIAS(optional_field(hash_in['healthcareIIAS'])),
|
61
|
+
:filtering=>XMLFields.filteringType(optional_field(hash_in['filtering'])),
|
62
|
+
:merchantData=>XMLFields.filteringType(optional_field(hash_in['merchantData'])),
|
63
|
+
:recyclingRequest=>XMLFields.recyclingRequestType(optional_field(hash_in['recyclingRequest']))
|
64
|
+
}
|
65
|
+
hash_out.merge!(get_common_attributes(hash_in))
|
66
|
+
Checker.purge_null(hash_out)
|
67
|
+
choice1= {'1'=>hash_out[:card],'2' =>hash_out[:paypal],'3'=>hash_out[:token],'4'=>hash_out[:paypage]}
|
68
|
+
Checker.choice(choice1)
|
69
|
+
Checker.required_missing(hash_out)
|
70
|
+
litleOnline_hash = build_full_hash(hash_in, {:authorization => hash_out})
|
71
|
+
Checker.required_missing(litleOnline_hash)
|
72
|
+
LitleXmlMapper.request(litleOnline_hash,@config_hash)
|
73
|
+
end
|
74
|
+
|
75
|
+
def sale(hash_in)
|
76
|
+
hash_out = {
|
77
|
+
:litleTxnId => hash_in['litleTxnId'],
|
78
|
+
:orderId =>required_field(hash_in['orderId']),
|
79
|
+
:amount =>required_field(hash_in['amount']),
|
80
|
+
:orderSource=>required_field(hash_in['orderSource']),
|
81
|
+
:customerInfo=>XMLFields.customerInfo(optional_field(hash_in['customerInfo'])),
|
82
|
+
:billToAddress=>XMLFields.contact(optional_field(hash_in['billToAddress'])),
|
83
|
+
:shipToAddress=>XMLFields.contact(optional_field(hash_in['shipToAddress'])),
|
84
|
+
:card=> XMLFields.cardType(optional_field(hash_in['card'])),
|
85
|
+
:paypal=>XMLFields.payPal(optional_field(hash_in['paypal'])),
|
86
|
+
:token=>XMLFields.cardTokenType(optional_field(hash_in['token'])),
|
87
|
+
:paypage=>XMLFields.cardPaypageType(optional_field(hash_in['paypage'])),
|
88
|
+
:billMeLaterRequest=>XMLFields.billMeLaterRequest(optional_field(hash_in['billMeLaterRequest'])),
|
89
|
+
:fraudCheck=>XMLFields.fraudCheckType(optional_field(hash_in['fraudCheck'])),
|
90
|
+
:cardholderAuthentication=>XMLFields.fraudCheckType(optional_field(hash_in['cardholderAuthentication'])),
|
91
|
+
:customBilling=>XMLFields.customBilling(optional_field(hash_in['customBilling'])),
|
92
|
+
:taxBilling=>XMLFields.taxBilling(optional_field(hash_in['taxBilling'])),
|
93
|
+
:enhancedData=>XMLFields.enhancedData(optional_field(hash_in['enhancedData'])),
|
94
|
+
:processingInstructions=>XMLFields.processingInstructions(optional_field(hash_in['processingInstructions'])),
|
95
|
+
:pos=>XMLFields.pos(optional_field(hash_in['pos'])),
|
96
|
+
:payPalOrderComplete=> hash_in['paypalOrderComplete'],
|
97
|
+
:payPalNotes=> hash_in['paypalNotesType'],
|
98
|
+
:amexAggregatorData=>XMLFields.amexAggregatorData(optional_field(hash_in['amexAggregatorData'])),
|
99
|
+
:allowPartialAuth=>hash_in['allowPartialAuth'],
|
100
|
+
:healthcareIIAS=>XMLFields.healthcareIIAS(optional_field(hash_in['healthcareIIAS'])),
|
101
|
+
:filtering=>XMLFields.filteringType(optional_field(hash_in['filtering'])),
|
102
|
+
:merchantData=>XMLFields.filteringType(optional_field(hash_in['merchantData'])),
|
103
|
+
:recyclingRequest=>XMLFields.recyclingRequestType(optional_field(hash_in['recyclingRequest']))
|
104
|
+
}
|
105
|
+
hash_out.merge!(get_common_attributes(hash_in))
|
106
|
+
Checker.purge_null(hash_out)
|
107
|
+
choice1= {'1'=>hash_out[:card],'2' =>hash_out[:paypal],'3'=>hash_out[:token],'4'=>hash_out[:paypage]}
|
108
|
+
choice2= {'1'=>hash_out[:fraudCheck],'2'=>hash_out[:cardholderAuthentication]}
|
109
|
+
Checker.choice(choice1)
|
110
|
+
Checker.choice(choice2)
|
111
|
+
Checker.required_missing(hash_out)
|
112
|
+
litleOnline_hash = build_full_hash(hash_in, {:sale => hash_out})
|
113
|
+
Checker.required_missing(litleOnline_hash)
|
114
|
+
LitleXmlMapper.request(litleOnline_hash,@config_hash)
|
115
|
+
end
|
116
|
+
|
117
|
+
def authReversal(hash_in)
|
118
|
+
hash_out = {
|
119
|
+
:litleTxnId => required_field(hash_in['litleTxnId']),
|
120
|
+
:amount =>hash_in['amount'],
|
121
|
+
:payPalNotes=>hash_in['payPalNotes'],
|
122
|
+
:actionReason=>hash_in['actionReason']
|
123
|
+
}
|
124
|
+
hash_out.merge!(get_common_attributes(hash_in))
|
125
|
+
Checker.purge_null(hash_out)
|
126
|
+
Checker.required_missing(hash_out)
|
127
|
+
litleOnline_hash = build_full_hash(hash_in, {:authReversal => hash_out})
|
128
|
+
Checker.required_missing(litleOnline_hash)
|
129
|
+
LitleXmlMapper.request(litleOnline_hash,@config_hash)
|
130
|
+
end
|
131
|
+
|
132
|
+
def credit(hash_in)
|
133
|
+
hash_out = {
|
134
|
+
:litleTxnId => (hash_in['litleTxnId']),
|
135
|
+
:orderId =>hash_in['orderId'],
|
136
|
+
:amount =>hash_in['amount'],
|
137
|
+
:orderSource=>hash_in['orderSource'],
|
138
|
+
:billToAddress=>XMLFields.contact(optional_field(hash_in['billToAddress'])),
|
139
|
+
:card=> XMLFields.cardType(optional_field(hash_in['card'])),
|
140
|
+
:paypal=>XMLFields.payPal(optional_field(hash_in['paypal'])),
|
141
|
+
:token=>XMLFields.cardTokenType(optional_field(hash_in['token'])),
|
142
|
+
:paypage=>XMLFields.cardPaypageType(optional_field(hash_in['paypage'])),
|
143
|
+
:customBilling=>XMLFields.customBilling(optional_field(hash_in['customBilling'])),
|
144
|
+
:taxBilling=>XMLFields.taxBilling(optional_field(hash_in['taxBilling'])),
|
145
|
+
:billMeLaterRequest=>XMLFields.billMeLaterRequest(optional_field(hash_in['billMeLaterRequest'])),
|
146
|
+
:enhancedData=>XMLFields.enhancedData(optional_field(hash_in['enhancedData'])),
|
147
|
+
:processingInstructions=>XMLFields.processingInstructions(optional_field(hash_in['processingInstructions'])),
|
148
|
+
:pos=>XMLFields.pos(optional_field(hash_in['pos'])),
|
149
|
+
:amexAggregatorData=>XMLFields.amexAggregatorData(optional_field(hash_in['amexAggregatorData'])),
|
150
|
+
:payPalNotes =>hash_in['payPalNotes']
|
151
|
+
}
|
152
|
+
hash_out.merge!(get_common_attributes(hash_in))
|
153
|
+
Checker.purge_null(hash_out)
|
154
|
+
choice1= {'1'=>hash_out[:card],'2' =>hash_out[:paypal],'3'=>hash_out[:token],'4'=>hash_out[:paypage]}
|
155
|
+
Checker.choice(choice1)
|
156
|
+
Checker.required_missing(hash_out)
|
157
|
+
litleOnline_hash = build_full_hash(hash_in, {:credit => hash_out})
|
158
|
+
Checker.purge_null(hash_out)
|
159
|
+
Checker.required_missing(litleOnline_hash)
|
160
|
+
LitleXmlMapper.request(litleOnline_hash,@config_hash)
|
161
|
+
end
|
162
|
+
|
163
|
+
def registerTokenRequest(hash_in)
|
164
|
+
hash_out = {
|
165
|
+
:orderId =>optional_field(hash_in['orderId']),
|
166
|
+
:accountNumber=>hash_in['accountNumber'],
|
167
|
+
:echeckForToken=>XMLFields.echeckForTokenType(optional_field(hash_in['echeckForToken'])),
|
168
|
+
:paypageRegistrationId=>hash_in['paypageRegistrationId']
|
169
|
+
}
|
170
|
+
hash_out.merge!(get_common_attributes(hash_in))
|
171
|
+
Checker.purge_null(hash_out)
|
172
|
+
choice1= {'1'=>hash_out[:accountNumber],'2' =>hash_out[:echeckForToken],'3'=>hash_out[:paypageRegistrationId]}
|
173
|
+
Checker.choice(choice1)
|
174
|
+
Checker.required_missing(hash_out)
|
175
|
+
litleOnline_hash = build_full_hash(hash_in, {:registerTokenRequest => hash_out})
|
176
|
+
Checker.required_missing(litleOnline_hash)
|
177
|
+
LitleXmlMapper.request(litleOnline_hash,@config_hash)
|
178
|
+
end
|
179
|
+
|
180
|
+
def forceCapture(hash_in)
|
181
|
+
hash_out = {
|
182
|
+
:orderId =>required_field(hash_in['orderId']),
|
183
|
+
:amount =>(hash_in['amount']),
|
184
|
+
:orderSource=>required_field(hash_in['orderSource']),
|
185
|
+
:billToAddress=>XMLFields.contact(optional_field(hash_in['billToAddress'])),
|
186
|
+
:card=> XMLFields.cardType(optional_field(hash_in['card'])),
|
187
|
+
:token=>XMLFields.cardTokenType(optional_field(hash_in['token'])),
|
188
|
+
:paypage=>XMLFields.cardPaypageType(optional_field(hash_in['paypage'])),
|
189
|
+
:customBilling=>XMLFields.customBilling(optional_field(hash_in['customBilling'])),
|
190
|
+
:taxBilling=>XMLFields.taxBilling(optional_field(hash_in['taxBilling'])),
|
191
|
+
:enhancedData=>XMLFields.enhancedData(optional_field(hash_in['enhancedData'])),
|
192
|
+
:processingInstructions=>XMLFields.processingInstructions(optional_field(hash_in['processingInstructions'])),
|
193
|
+
:pos=>XMLFields.pos(optional_field(hash_in['pos'])),
|
194
|
+
:amexAggregatorData=>XMLFields.amexAggregatorData(optional_field(hash_in['amexAggregatorData']))
|
195
|
+
}
|
196
|
+
hash_out.merge!(get_common_attributes(hash_in))
|
197
|
+
Checker.purge_null(hash_out)
|
198
|
+
choice1= {'1'=>hash_out[:card],'3'=>hash_out[:token],'4'=>hash_out[:paypage]}
|
199
|
+
Checker.choice(choice1)
|
200
|
+
Checker.required_missing(hash_out)
|
201
|
+
litleOnline_hash = build_full_hash(hash_in, {:forceCapture => hash_out})
|
202
|
+
Checker.required_missing(litleOnline_hash)
|
203
|
+
LitleXmlMapper.request(litleOnline_hash,@config_hash)
|
204
|
+
end
|
205
|
+
|
206
|
+
def capture(hash_in)
|
207
|
+
####TODO check partial
|
208
|
+
hash_out = {
|
209
|
+
'@partial'=>hash_in['partial'],
|
210
|
+
:litleTxnId => required_field(hash_in['litleTxnId']),
|
211
|
+
:amount =>(hash_in['amount']),
|
212
|
+
:enhancedData=>XMLFields.enhancedData(optional_field(hash_in['enhancedData'])),
|
213
|
+
:processingInstructions=>XMLFields.processingInstructions(optional_field(hash_in['processingInstructions'])),
|
214
|
+
:payPalOrderComplete=>hash_in['payPalOrderComplete'],
|
215
|
+
:payPalNotes =>hash_in['payPalNotes']
|
216
|
+
}
|
217
|
+
hash_out.merge!(get_common_attributes(hash_in))
|
218
|
+
Checker.purge_null(hash_out)
|
219
|
+
Checker.required_missing(hash_out)
|
220
|
+
litleOnline_hash = build_full_hash(hash_in, {:capture => hash_out})
|
221
|
+
Checker.required_missing(litleOnline_hash)
|
222
|
+
LitleXmlMapper.request(litleOnline_hash,@config_hash)
|
223
|
+
end
|
224
|
+
|
225
|
+
def captureGivenAuth(hash_in)
|
226
|
+
hash_out = {
|
227
|
+
:orderId =>required_field(hash_in['orderId']),
|
228
|
+
:authInformation=>XMLFields.authInformation(optional_field(hash_in['authInformation'])),
|
229
|
+
:amount =>required_field(hash_in['amount']),
|
230
|
+
:orderSource=>required_field(hash_in['orderSource']),
|
231
|
+
:billToAddress=>XMLFields.contact(optional_field(hash_in['billToAddress'])),
|
232
|
+
:shipToAddress=>XMLFields.contact(optional_field(hash_in['shipToAddress'])),
|
233
|
+
:card=> XMLFields.cardType(optional_field(hash_in['card'])),
|
234
|
+
:token=>XMLFields.cardTokenType(optional_field(hash_in['token'])),
|
235
|
+
:paypage=>XMLFields.cardPaypageType(optional_field(hash_in['paypage'])),
|
236
|
+
:customBilling=>XMLFields.customBilling(optional_field(hash_in['customBilling'])),
|
237
|
+
:taxBilling=>XMLFields.taxBilling(optional_field(hash_in['taxBilling'])),
|
238
|
+
:billMeLaterRequest=>XMLFields.billMeLaterRequest(optional_field(hash_in['billMeLaterRequest'])),
|
239
|
+
:enhancedData=>XMLFields.enhancedData(optional_field(hash_in['enhancedData'])),
|
240
|
+
:processingInstructions=>XMLFields.processingInstructions(optional_field(hash_in['processingInstructions'])),
|
241
|
+
:pos=>XMLFields.pos(optional_field(hash_in['pos'])),
|
242
|
+
:amexAggregatorData=>XMLFields.amexAggregatorData(optional_field(hash_in['amexAggregatorData']))
|
243
|
+
}
|
244
|
+
hash_out.merge!(get_common_attributes(hash_in))
|
245
|
+
Checker.purge_null(hash_out)
|
246
|
+
choice1= {'1'=>hash_out[:card],'3'=>hash_out[:token],'4'=>hash_out[:paypage]}
|
247
|
+
Checker.choice(choice1)
|
248
|
+
Checker.required_missing(hash_out)
|
249
|
+
litleOnline_hash = build_full_hash(hash_in, {:captureGivenAuth => hash_out})
|
250
|
+
Checker.required_missing(litleOnline_hash)
|
251
|
+
LitleXmlMapper.request(litleOnline_hash,@config_hash)
|
252
|
+
end
|
253
|
+
|
254
|
+
def echeckRedeposit(hash_in)
|
255
|
+
hash_out = {
|
256
|
+
:litleTxnId => required_field(hash_in['litleTxnId']),
|
257
|
+
:echeck=>XMLFields.echeckType(optional_field(hash_in['echeck'])),
|
258
|
+
:echeckToken=>XMLFields.echeckTokenType(optional_field(hash_in['echeckToken']))
|
259
|
+
}
|
260
|
+
hash_out.merge!(get_common_attributes(hash_in))
|
261
|
+
Checker.purge_null(hash_out)
|
262
|
+
choice1= {'1'=>hash_out[:echeck],'3'=>hash_out[:echeckToken]}
|
263
|
+
Checker.choice(choice1)
|
264
|
+
Checker.required_missing(hash_out)
|
265
|
+
litleOnline_hash = build_full_hash(hash_in, {:echeckRedeposit => hash_out})
|
266
|
+
Checker.required_missing(litleOnline_hash)
|
267
|
+
LitleXmlMapper.request(litleOnline_hash,@config_hash)
|
268
|
+
end
|
269
|
+
|
270
|
+
def echeckSale(hash_in)
|
271
|
+
hash_out = {
|
272
|
+
:litleTxnId => hash_in['litleTxnId'],
|
273
|
+
:orderId =>hash_in['orderId'],
|
274
|
+
:verify =>hash_in['verify'],
|
275
|
+
:amount =>hash_in['amount'],
|
276
|
+
:orderSource =>hash_in['orderSource'],
|
277
|
+
:billToAddress=>XMLFields.contact(optional_field(hash_in['billToAddress'])),
|
278
|
+
:shipToAddress=>XMLFields.contact(optional_field(hash_in['shipToAddress'])),
|
279
|
+
:echeck=>XMLFields.echeckType(optional_field(hash_in['echeck'])),
|
280
|
+
:echeckToken=>XMLFields.echeckTokenType(optional_field(hash_in['echeckToken'])),
|
281
|
+
:customBilling=>XMLFields.customBilling(optional_field(hash_in['customBilling'])),
|
282
|
+
}
|
283
|
+
hash_out.merge!(get_common_attributes(hash_in))
|
284
|
+
Checker.purge_null(hash_out)
|
285
|
+
choice1= {'1'=>hash_out[:echeck],'3'=>hash_out[:echeckToken]}
|
286
|
+
Checker.choice(choice1)
|
287
|
+
Checker.required_missing(hash_out)
|
288
|
+
litleOnline_hash = build_full_hash(hash_in, {:echeckSale => hash_out})
|
289
|
+
Checker.required_missing(litleOnline_hash)
|
290
|
+
LitleXmlMapper.request(litleOnline_hash,@config_hash)
|
291
|
+
end
|
292
|
+
|
293
|
+
def echeckCredit(hash_in)
|
294
|
+
hash_out = {
|
295
|
+
:litleTxnId => hash_in['litleTxnId'],
|
296
|
+
:orderId =>hash_in['orderId'],
|
297
|
+
:amount =>hash_in['amount'],
|
298
|
+
:orderSource =>hash_in['orderSource'],
|
299
|
+
:billToAddress=>XMLFields.contact(optional_field(hash_in['billToAddress'])),
|
300
|
+
:echeck=>XMLFields.echeckType(optional_field(hash_in['echeck'])),
|
301
|
+
:echeckToken=>XMLFields.echeckTokenType(optional_field(hash_in['echeckToken'])),
|
302
|
+
:customBilling=>XMLFields.customBilling(optional_field(hash_in['customBilling'])),
|
303
|
+
}
|
304
|
+
hash_out.merge!(get_common_attributes(hash_in))
|
305
|
+
Checker.purge_null(hash_out)
|
306
|
+
choice1= {'1'=>hash_out[:echeck],'3'=>hash_out[:echeckToken]}
|
307
|
+
Checker.choice(choice1)
|
308
|
+
Checker.required_missing(hash_out)
|
309
|
+
litleOnline_hash = build_full_hash(hash_in, {:echeckCredit => hash_out})
|
310
|
+
Checker.required_missing(litleOnline_hash)
|
311
|
+
LitleXmlMapper.request(litleOnline_hash,@config_hash)
|
312
|
+
end
|
313
|
+
|
314
|
+
def echeckVerification(hash_in)
|
315
|
+
hash_out = {
|
316
|
+
:litleTxnId => hash_in['litleTxnId'],
|
317
|
+
:orderId =>required_field(hash_in['orderId']),
|
318
|
+
:amount =>required_field(hash_in['amount']),
|
319
|
+
:orderSource =>required_field(hash_in['orderSource']),
|
320
|
+
:billToAddress=>XMLFields.contact(optional_field(hash_in['billToAddress'])),
|
321
|
+
:echeck=>XMLFields.echeckType(optional_field(hash_in['echeck'])),
|
322
|
+
:echeckToken=>XMLFields.echeckTokenType(optional_field(hash_in['echeckToken'])),
|
323
|
+
}
|
324
|
+
hash_out.merge!(get_common_attributes(hash_in))
|
325
|
+
Checker.purge_null(hash_out)
|
326
|
+
choice1= {'1'=>hash_out[:echeck],'3'=>hash_out[:echeckToken]}
|
327
|
+
Checker.choice(choice1)
|
328
|
+
Checker.required_missing(hash_out)
|
329
|
+
litleOnline_hash = build_full_hash(hash_in, {:echeckVerification => hash_out})
|
330
|
+
Checker.required_missing(litleOnline_hash)
|
331
|
+
LitleXmlMapper.request(litleOnline_hash,@config_hash)
|
332
|
+
end
|
333
|
+
|
334
|
+
def void(hash_in)
|
335
|
+
hash_out = {
|
336
|
+
:litleTxnId => required_field(hash_in['litleTxnId']),
|
337
|
+
:processingInstructions=>XMLFields.processingInstructions(optional_field(hash_in['processingInstructions']))
|
338
|
+
}
|
339
|
+
hash_out.merge!(get_common_attributes(hash_in))
|
340
|
+
Checker.purge_null(hash_out)
|
341
|
+
Checker.required_missing(hash_out)
|
342
|
+
litleOnline_hash = build_full_hash(hash_in, {:void => hash_out})
|
343
|
+
Checker.required_missing(litleOnline_hash)
|
344
|
+
LitleXmlMapper.request(litleOnline_hash,@config_hash)
|
345
|
+
end
|
346
|
+
|
347
|
+
private
|
348
|
+
|
349
|
+
def get_merchant_id(hash_in)
|
350
|
+
if (hash_in['merchantId'] == nil)
|
351
|
+
return @config_hash['currency_merchant_map']['DEFAULT']
|
352
|
+
else
|
353
|
+
return hash_in['merchantId']
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
def get_report_group(hash_in)
|
358
|
+
if (hash_in['reportGroup'] == nil)
|
359
|
+
return required_field(@config_hash['default_report_group'])
|
360
|
+
else
|
361
|
+
return hash_in['reportGroup']
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
def authentication(hash_in)
|
366
|
+
hash_out = {
|
367
|
+
:user =>required_field(@config_hash['user']),
|
368
|
+
:password =>required_field(@config_hash['password'])
|
369
|
+
}
|
370
|
+
Checker.required_missing(hash_out)
|
371
|
+
end
|
372
|
+
|
373
|
+
def required_field(value)
|
374
|
+
return (value or 'REQUIRED')
|
375
|
+
end
|
376
|
+
|
377
|
+
def optional_field(value)
|
378
|
+
return (value or ' ')
|
379
|
+
end
|
380
|
+
|
381
|
+
def build_full_hash(hash_in, merge_hash)
|
382
|
+
litleOnline_hash = {
|
383
|
+
"@version"=> required_field(@config_hash['version']),
|
384
|
+
"@xmlns"=> "http://www.litle.com/schema",
|
385
|
+
"@merchantId"=> get_merchant_id(hash_in),
|
386
|
+
:authentication => authentication(hash_in)
|
387
|
+
}
|
388
|
+
return litleOnline_hash.merge(merge_hash)
|
389
|
+
end
|
390
|
+
|
391
|
+
def get_common_attributes(hash_in)
|
392
|
+
return {
|
393
|
+
'@id' => hash_in['id'],
|
394
|
+
'@customerId' => hash_in['customerId'],
|
395
|
+
'@reportGroup' => get_report_group(hash_in)
|
396
|
+
}
|
397
|
+
end
|
398
|
+
|
399
|
+
end
|