BankValInt 0.0.2
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/LICENSE +27 -0
- data/README +82 -0
- data/Rakefile +46 -0
- data/lib/BankValInternational.rb +326 -0
- data/test/bv_int_test.rb +238 -0
- metadata +72 -0
data/LICENSE
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
== BankValInt
|
2
|
+
|
3
|
+
Copyright (c) 2010, Unified Software
|
4
|
+
All rights reserved.
|
5
|
+
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
8
|
+
* Redistributions of source code must retain the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer.
|
10
|
+
* Redistributions in binary form must reproduce the above copyright
|
11
|
+
notice, this list of conditions and the following disclaimer in the
|
12
|
+
documentation and/or other materials provided with the distribution.
|
13
|
+
* Neither the name of the <organization> nor the
|
14
|
+
names of its contributors may be used to endorse or promote products
|
15
|
+
derived from this software without specific prior written permission.
|
16
|
+
|
17
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
18
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20
|
+
DISCLAIMED. IN NO EVENT SHALL UNIFIED SOFTWARE BE LIABLE FOR ANY
|
21
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
|
data/README
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
== BankValInt
|
2
|
+
== Unified Software
|
3
|
+
|
4
|
+
==SYNOPSIS (GetABA)
|
5
|
+
|
6
|
+
require 'rubygems' #using uppercase letters may load the file more than once which will cause 'already set constant' warnings
|
7
|
+
require 'bankvalinternational'
|
8
|
+
|
9
|
+
obj = BankValInternational::GetABA.new
|
10
|
+
ans = obj.bankval_int_getaba('json','123456789','abcd123','12345')
|
11
|
+
|
12
|
+
==Description
|
13
|
+
|
14
|
+
This Gem controls the calling of REST web services from Unified Software's International Bank Validation services.
|
15
|
+
It will transparently call Unified's back up servers in the unlikely event of any issues with the main servers.
|
16
|
+
The services which can be used from this Gem are:
|
17
|
+
|
18
|
+
[IBANValidate]Full IBAN number validation in accordance with ECBS standards.
|
19
|
+
|
20
|
+
object = BankValInternational::GetIBAN.new
|
21
|
+
method = object.bankval_int_ibanval(format,iban,userid,pin)
|
22
|
+
|
23
|
+
|
24
|
+
[getABAdetails]Full Routing number validation using the latest Routing Numbers Database.
|
25
|
+
|
26
|
+
object = BankValInternational::GetABA.new
|
27
|
+
method = object.bankval_int_getaba(format,aba,userid,pin)
|
28
|
+
|
29
|
+
|
30
|
+
[GetBankDetails2]Full validation of SWIFT BIC codes using the latest SWIFT BIC directory.
|
31
|
+
|
32
|
+
object = BankValInternational::GetSWIFT.new
|
33
|
+
method = object.bankval_int_getswift(format,swiftbic,userid,pin)
|
34
|
+
|
35
|
+
==Including the Gem
|
36
|
+
|
37
|
+
To allow the usage of this gem you must have RubyGems installed. To check if you have,
|
38
|
+
open a command prompt (win) or console window (*nix) and type 'gem'. If RubyGems is installed
|
39
|
+
you will see a help message. If it isn't a command unrecognised message will appear.
|
40
|
+
|
41
|
+
To install RubyGems please refer to :
|
42
|
+
|
43
|
+
http://docs.rubygems.org/read/chapter/3
|
44
|
+
|
45
|
+
Once Rubygems is installed you can install the BankValInt gem from Rubygems.org by either;
|
46
|
+
|
47
|
+
*searching for BankValInt from within your IDE (e.g. in netbeans tool>RubyGems)
|
48
|
+
|
49
|
+
*opening a command prompt (win) or a console window (*nix) and typing 'gem install BankValInt'
|
50
|
+
|
51
|
+
Once the BankValInt gem is installed on your system it can be included in your code by adding the following two lines:
|
52
|
+
|
53
|
+
require 'rubygems'
|
54
|
+
require 'BankValInt'
|
55
|
+
|
56
|
+
==Calling the services
|
57
|
+
|
58
|
+
To call the services simply create an instance of the relevant class (as shown in the description above) and call
|
59
|
+
the exposed method (again as shown above)
|
60
|
+
|
61
|
+
==Parameters
|
62
|
+
|
63
|
+
The required parameters for the services are as follows:
|
64
|
+
|
65
|
+
1. Format:: the response format (either xml, json or csv)
|
66
|
+
|
67
|
+
2. IBAN/ABA/SWIFTBIC:: the IBAN to be validated
|
68
|
+
|
69
|
+
3. UserID:: available from www.unifiedsoftware.co.uk
|
70
|
+
|
71
|
+
4. PIN:: available from www.unifiedsoftware.co.uk
|
72
|
+
|
73
|
+
The parameters must be passed in the order shown
|
74
|
+
|
75
|
+
==Method Returns
|
76
|
+
|
77
|
+
The methods will return the web services response as a string formatted in either xml, json, or csv depending on the format parameter
|
78
|
+
|
79
|
+
==BankValInternational Ruby Gem
|
80
|
+
|
81
|
+
==Unified Software 2010
|
82
|
+
==www.unifiedsoftware.co.uk
|
data/Rakefile
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
#BankValInt Rake file
|
2
|
+
#
|
3
|
+
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'rake'
|
7
|
+
require 'rake/clean'
|
8
|
+
require 'rake/gempackagetask'
|
9
|
+
require 'rake/rdoctask'
|
10
|
+
require 'rake/testtask'
|
11
|
+
require 'spec/rake/spectask'
|
12
|
+
|
13
|
+
spec = Gem::Specification.new do |s|
|
14
|
+
s.name = 'BankValInt'
|
15
|
+
s.version = '0.0.2'
|
16
|
+
s.has_rdoc = true
|
17
|
+
s.extra_rdoc_files = ['README', 'LICENSE']
|
18
|
+
s.summary = 'Module containing classes to handle calls to Unified Software\'s International Bank Validation REST web services'
|
19
|
+
s.description = s.summary + " BankValInternational Services catered for by this module are getABAdetails, ibanValidate and getBankDetails2"
|
20
|
+
s.author = 'Alec Evans, Unified Software'
|
21
|
+
s.email = 'support@unifiedsoftware.co.uk'
|
22
|
+
s.homepage = 'http://www.unifiedsoftware.co.uk'
|
23
|
+
s.files = %w(LICENSE README Rakefile) + Dir.glob("{bin,lib,spec,test}/**/*")
|
24
|
+
s.require_path = "lib"
|
25
|
+
s.bindir = "bin"
|
26
|
+
s.license = "LICENSE"
|
27
|
+
end
|
28
|
+
|
29
|
+
Rake::GemPackageTask.new(spec) do |p|
|
30
|
+
p.gem_spec = spec
|
31
|
+
p.need_tar = true
|
32
|
+
p.need_zip = true
|
33
|
+
end
|
34
|
+
|
35
|
+
Rake::RDocTask.new do |rdoc|
|
36
|
+
files =['README', 'LICENSE', 'lib/**/*.rb']
|
37
|
+
rdoc.rdoc_files.add(files)
|
38
|
+
rdoc.main = "README" # page to start on
|
39
|
+
rdoc.title = "BankValInt Docs"
|
40
|
+
rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder
|
41
|
+
rdoc.options << '--line-numbers'
|
42
|
+
end
|
43
|
+
|
44
|
+
Rake::TestTask.new do |t|
|
45
|
+
t.test_files = FileList['test/**/*.rb']
|
46
|
+
end
|
@@ -0,0 +1,326 @@
|
|
1
|
+
#=BankValInternational
|
2
|
+
#
|
3
|
+
#==Unified Software
|
4
|
+
#
|
5
|
+
#Module containing classes to handle calls to Unified Sotware's
|
6
|
+
#BankValInternational web services
|
7
|
+
#
|
8
|
+
#*[BankValInternational::GetIBAN] Which handles calls to _IBANValidate_
|
9
|
+
#
|
10
|
+
#*[BankValInternational::GetSWIFT] Which handles calls to <i>GetBankDetails2</i>
|
11
|
+
#
|
12
|
+
#*[BankValInternational::GetABA] Which handles calls to _getABAdetails_
|
13
|
+
#
|
14
|
+
module BankValInternational
|
15
|
+
require 'net/https'
|
16
|
+
require 'uri'
|
17
|
+
|
18
|
+
#=BankValInternational::GetIban
|
19
|
+
#
|
20
|
+
#Class to control calls to _IBANValidate_
|
21
|
+
#
|
22
|
+
#=Synopsis
|
23
|
+
#
|
24
|
+
# requires 'BankValInternational'
|
25
|
+
#
|
26
|
+
# @obj1 = BankValInternational::GetIBAN.new
|
27
|
+
# @ans = obj1.bankval_int_ibanval('json','AN_IBAN_NUMBER','userID','PINNo')
|
28
|
+
#
|
29
|
+
class BankValInternational::GetIBAN
|
30
|
+
@userid
|
31
|
+
@pin
|
32
|
+
@iban
|
33
|
+
@format
|
34
|
+
@service_url
|
35
|
+
|
36
|
+
#Method to control calls to _IBANValidate_
|
37
|
+
#
|
38
|
+
#==Parameters
|
39
|
+
#1.Return Format:: must be either 'json', 'xml' or 'csv'
|
40
|
+
#2.Iban Number:: the number for validation
|
41
|
+
#3.UserId:: can obtained from http://www.unifiedsoftware.co.uk/freetrial/free-trial-home.html
|
42
|
+
#4.PIN:: can obtained from http://www.unifiedsoftware.co.uk/freetrial/free-trial-home.html
|
43
|
+
#
|
44
|
+
#The parameters *must* be passed in the order shown above
|
45
|
+
#
|
46
|
+
#==Returns
|
47
|
+
#The response from the webservice is returned as a string in either:
|
48
|
+
#*XML format
|
49
|
+
#*json format
|
50
|
+
#*csv format
|
51
|
+
#depending on the Return Format Parameter passed in
|
52
|
+
#
|
53
|
+
def bankval_int_ibanval(*args)
|
54
|
+
@format = args[0].downcase
|
55
|
+
@iban = args[1]
|
56
|
+
@userid = args[2]
|
57
|
+
@pin = args[3]
|
58
|
+
if args.size !=4
|
59
|
+
return "ERROR - not enough parameters supplied"
|
60
|
+
end
|
61
|
+
format_validation
|
62
|
+
if @error_string != nil
|
63
|
+
format_error_string
|
64
|
+
return @error_string
|
65
|
+
end
|
66
|
+
build_req_url
|
67
|
+
return "#{BankValInternational::GoValidate.new.validate(@service_url)}"
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
#method to build the base request url for the REST call
|
73
|
+
def build_req_url()
|
74
|
+
@service_url = "bankvalint/ibanvalidator/userid/#{@userid}/pin/#{@pin}/iban/#{@iban}/#{@format}/"
|
75
|
+
end
|
76
|
+
def format_validation
|
77
|
+
@error_string = nil
|
78
|
+
if @format !~ /^json$|^xml$|^csv$/
|
79
|
+
@error_string = "INVALID - Result Format"
|
80
|
+
elsif @iban !~ /^[A-Z,0-9]{1,34}$/
|
81
|
+
@error_string = "INVALID - FORMAT"
|
82
|
+
elsif @pin !~ /^[0-9]{5}$/
|
83
|
+
@error_string = "ERROR - Invalid User ID/PIN"
|
84
|
+
elsif @userid !~ /^[a-zA-Z\-_][a-zA-Z][a-zA-Z]*\D\d\d\d$/
|
85
|
+
@error_string = "ERROR - Invalid User ID/PIN"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def format_error_string()
|
90
|
+
if @format == 'xml'
|
91
|
+
@error_string = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><iban><result>" + @error_string + "</result></iban>"
|
92
|
+
elsif @format == 'json'
|
93
|
+
@error_string = "{\"result\":\"" + @error_string + "\"}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
#=BankValInternational::GetSWIFT
|
100
|
+
#
|
101
|
+
#Class to control calls to <i>getBankDetails2</i>
|
102
|
+
#
|
103
|
+
#=Synopsis
|
104
|
+
#
|
105
|
+
# requires 'BankValInternational'
|
106
|
+
#
|
107
|
+
# @obj1 = BankValInternational::GetSWIFT.new
|
108
|
+
# @ans = obj1.bankval_int_get_swift('xml','A_SWIFT_BIC','userID','PINNo')
|
109
|
+
#
|
110
|
+
class BankValInternational::GetSWIFT
|
111
|
+
@userid
|
112
|
+
@pin
|
113
|
+
@swiftbic
|
114
|
+
@format
|
115
|
+
@service_url
|
116
|
+
|
117
|
+
#Method to control calls to _getBankDetails2_
|
118
|
+
#
|
119
|
+
#==Parameters
|
120
|
+
#1.Return Format:: must be either 'json', 'xml' or 'csv'
|
121
|
+
#2.Swift BIC Number:: the number for validation
|
122
|
+
#3.UserId:: can obtained from http://www.unifiedsoftware.co.uk/freetrial/free-trial-home.html
|
123
|
+
#4.PIN:: can obtained from http://www.unifiedsoftware.co.uk/freetrial/free-trial-home.html
|
124
|
+
#
|
125
|
+
#The parameters *must* be passed in the order shown above
|
126
|
+
#
|
127
|
+
#==Returns
|
128
|
+
#The response from the webservice is returned as a string in either:
|
129
|
+
#*XML format
|
130
|
+
#*json format
|
131
|
+
#*csv format
|
132
|
+
#depending on the Return Format Parameter passed in
|
133
|
+
#
|
134
|
+
def bankval_int_getswift(*args)
|
135
|
+
@format = args[0].downcase
|
136
|
+
@swiftbic = args[1]
|
137
|
+
@userid = args[2]
|
138
|
+
@pin = args[3]
|
139
|
+
if args.size !=4
|
140
|
+
return "ERROR - not enough parameters supplied"
|
141
|
+
end
|
142
|
+
format_validation
|
143
|
+
if @error_string != nil
|
144
|
+
format_error_string
|
145
|
+
return @error_string
|
146
|
+
end
|
147
|
+
build_req_url
|
148
|
+
return "#{BankValInternational::GoValidate.new.validate(@service_url)}"
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
#method to build the base request url for the REST call
|
154
|
+
def build_req_url()
|
155
|
+
@service_url = "bankvalint/bankdetails2/userid/#{@userid}/pin/#{@pin}/swiftbic/#{@swiftbic}/#{@format}/"
|
156
|
+
end
|
157
|
+
def format_validation
|
158
|
+
@error_string = nil
|
159
|
+
if @format !~ /^json$|^xml$|^csv$/
|
160
|
+
@error_string = "INVALID - Result Format"
|
161
|
+
elsif @swiftbic !~ /^[A-Z,0-9]{8}$/
|
162
|
+
@error_string = "INVALID"
|
163
|
+
elsif @pin !~ /^[0-9]{5}$/
|
164
|
+
@error_string = "ERROR - Invalid User ID/PIN"
|
165
|
+
elsif @userid !~ /^[a-zA-Z\-_][a-zA-Z][a-zA-Z]*\D\d\d\d$/
|
166
|
+
@error_string = "ERROR - Invalid User ID/PIN"
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def format_error_string()
|
171
|
+
if @format == 'xml'
|
172
|
+
@error_string = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><swiftbic><result>" + @error_string + "</result><bic></bic><name1></name1><name2></name2><name3></name3><address1></address1><address2></address2><address3></address3><address4></address4><location></location><country></country></swiftbic>"
|
173
|
+
elsif @format == 'json'
|
174
|
+
@error_string = "{\"result\":\"" + @error_string + "\",\"bic\":\"\",\"name1\":\"\",\"name2\":\"\",\"name3\":\"\",\"address1\":\"\",\"address2\":\"\",\"address3\":\"\",\"address4\":\"\",\"location\":\"\",\"country\":\"\"}"
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
#=BankValInternational::GetABA
|
181
|
+
#
|
182
|
+
#Class to control calls to _getABAdetails_
|
183
|
+
#
|
184
|
+
#=Synopsis
|
185
|
+
#
|
186
|
+
# requires 'BankValInternational'
|
187
|
+
#
|
188
|
+
# @obj1 = BankValInternational::GetABA.new
|
189
|
+
# @ans = obj1.bankval_int_ibanval('json','AN_ABA','userID','PINNo')
|
190
|
+
#
|
191
|
+
class BankValInternational::GetABA
|
192
|
+
@userid
|
193
|
+
@pin
|
194
|
+
@aba
|
195
|
+
@format
|
196
|
+
@service_url
|
197
|
+
|
198
|
+
#Method to control calls to _getABAdetails_
|
199
|
+
#
|
200
|
+
#==Parameters
|
201
|
+
#1.Return Format:: must be either 'json', 'xml' or 'csv'
|
202
|
+
#2.ABA Number:: the number for validation
|
203
|
+
#3.UserId:: can obtained from http://www.unifiedsoftware.co.uk/freetrial/free-trial-home.html
|
204
|
+
#4.PIN:: can obtained from http://www.unifiedsoftware.co.uk/freetrial/free-trial-home.html
|
205
|
+
#
|
206
|
+
#The parameters *must* be passed in the order shown above
|
207
|
+
#
|
208
|
+
#==Returns
|
209
|
+
#The response from the webservice is returned as a string in either:
|
210
|
+
#*XML format
|
211
|
+
#*json format
|
212
|
+
#*csv format
|
213
|
+
#depending on the Return Format Parameter passed in
|
214
|
+
#
|
215
|
+
def bankval_int_getaba(*args)
|
216
|
+
@format = args[0].downcase
|
217
|
+
@aba = args[1]
|
218
|
+
@userid = args[2]
|
219
|
+
@pin = args[3]
|
220
|
+
if args.size !=4
|
221
|
+
return "ERROR - not enough parameters supplied"
|
222
|
+
end
|
223
|
+
format_validation
|
224
|
+
if @error_string != nil
|
225
|
+
format_error_string
|
226
|
+
return @error_string
|
227
|
+
end
|
228
|
+
build_req_url
|
229
|
+
return "#{BankValInternational::GoValidate.new.validate(@service_url)}"
|
230
|
+
end
|
231
|
+
|
232
|
+
private
|
233
|
+
|
234
|
+
#method to build the base request url for the REST call
|
235
|
+
def build_req_url()
|
236
|
+
@service_url = "bankvalint/abadetails/userid/#{@userid}/pin/#{@pin}/aba/#{@aba}/#{@format}/"
|
237
|
+
end
|
238
|
+
|
239
|
+
def format_validation()
|
240
|
+
@error_string = nil
|
241
|
+
if @format !~ /^json$|^xml$|^csv$/
|
242
|
+
@error_string = "INVALID - Result Format"
|
243
|
+
elsif @aba !~ /^[0-9]{9}$/
|
244
|
+
@error_string = "INVALID"
|
245
|
+
elsif @pin !~ /^[0-9]{5}$/
|
246
|
+
@error_string = "ERROR - Invalid User ID/PIN"
|
247
|
+
elsif @userid !~ /^[a-zA-Z\-_][a-zA-Z][a-zA-Z]*\D\d\d\d$/
|
248
|
+
@error_string = "ERROR - Invalid User ID/PIN"
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
def format_error_string()
|
253
|
+
if @format == 'xml'
|
254
|
+
@error_string = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><aba><result>" + @error_string + "</result><routingnumber></routingnumber><bankname></bankname><bankaddress></bankaddress><city></city><state></state><zipcode></zipcode><telephone></telephone><areacode></areacode><fips></fips><timezone></timezone><dst></dst><latitude></latitude><longitude></longitude><msa></msa><pmsa></pmsa><county></county></aba>"
|
255
|
+
elsif @format == 'json'
|
256
|
+
@error_string = "{\"result\":\"" + @error_string + "\",\"routingnumber\":\"\",\"bankname\":\"\",\"bankaddress\":\"\",\"city\":\"\",\"state\":\"\",\"zipcode\":\"\",\"telephone\":\"\",\"areacode\":\"\",\"fips\":\"\",\"timezone\":\"\",\"dst\":\"\",\"latitude\":\"\",\"longitude\":\"\",\"msa\":\"\",\"pmsa\":\"\",\"county\":\"\"}"
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
#=BankValInternational::GoValidate
|
262
|
+
#
|
263
|
+
#Class to make calls to Unified Softwares web services
|
264
|
+
#
|
265
|
+
#
|
266
|
+
class BankValInternational::GoValidate
|
267
|
+
@base_url
|
268
|
+
|
269
|
+
#Method to make REST web service calls and return response
|
270
|
+
#if call to the main data centre fails the back up method is called
|
271
|
+
#to make a call to the back up data centre
|
272
|
+
#
|
273
|
+
#==Parameters
|
274
|
+
#1. Serv_url is the services part of the URL for the REST call
|
275
|
+
#
|
276
|
+
#==Returns
|
277
|
+
#The response from the web service in requested format (XML,JSON or CSV)
|
278
|
+
#
|
279
|
+
#
|
280
|
+
def validate(ser_url)
|
281
|
+
@base_url = "https://www.unifiedsoftware.co.uk/services/"
|
282
|
+
uriobj = URI.parse(@base_url)
|
283
|
+
full_path = uriobj.path + ser_url
|
284
|
+
conn = Net::HTTP.new(uriobj.host, uriobj.port)
|
285
|
+
conn.use_ssl = true
|
286
|
+
conn.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
287
|
+
begin
|
288
|
+
webresponse = conn.get2(URI.encode(full_path))
|
289
|
+
rescue Exception => err
|
290
|
+
webresponse = failover(ser_url)
|
291
|
+
end
|
292
|
+
if webresponse == nil
|
293
|
+
return "Unknown Error-Check Local Network"
|
294
|
+
end
|
295
|
+
return webresponse.body
|
296
|
+
end
|
297
|
+
|
298
|
+
#Method to make backup REST web service calls and return response
|
299
|
+
#if call to the main data centre fails this method is called
|
300
|
+
#to make a call to the back up data centre
|
301
|
+
#
|
302
|
+
#==Parameters
|
303
|
+
#1. Serv_url is the services part of the URL for the REST call
|
304
|
+
#
|
305
|
+
#==Returns
|
306
|
+
#The response from the web service as a string in requested format (XML,JSON or CSV)
|
307
|
+
#or..
|
308
|
+
#error message in case of error
|
309
|
+
#
|
310
|
+
def failover(ser_url)
|
311
|
+
@base_url = "https://www.unifiedservices.co.uk/services/"
|
312
|
+
uriobj = URI.parse(@base_url)
|
313
|
+
full_path = uriobj.path + ser_url
|
314
|
+
conn = Net::HTTP.new(uriobj.host, uriobj.port)
|
315
|
+
conn.use_ssl = true
|
316
|
+
conn.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
317
|
+
begin
|
318
|
+
webresponse = conn.get2(URI.encode(full_path))
|
319
|
+
rescue Exception => err
|
320
|
+
return "Network Error" + err
|
321
|
+
end
|
322
|
+
return webresponse
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
end
|
data/test/bv_int_test.rb
ADDED
@@ -0,0 +1,238 @@
|
|
1
|
+
#internal gem test suite for BankValInternational
|
2
|
+
|
3
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
require 'BankValInternational'
|
7
|
+
require 'rexml/document'
|
8
|
+
require 'rubygems'
|
9
|
+
require 'json'
|
10
|
+
|
11
|
+
class BvIntGetAbaTest < Test::Unit::TestCase
|
12
|
+
@obj
|
13
|
+
def setup
|
14
|
+
@obj = BankValInternational::GetABA.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_return_validation_aba
|
18
|
+
#test1_1 'J-Son' is rejected as invalid result format
|
19
|
+
assert_match /INVALID - Result Format/,@obj.bankval_int_getaba('J-Son','12345678','abcd123','12345')
|
20
|
+
#tests 1_2 to 1_4 test that 'json','xml','csv' are not rejected as invalis result formats
|
21
|
+
assert_no_match /INVALID - Result Format/,@obj.bankval_int_getaba('json','12345678','abcd123','12345')
|
22
|
+
assert_no_match /INVALID - Result Format/,@obj.bankval_int_getaba('xml','12345678','abcd123','12345')
|
23
|
+
assert_no_match /INVALID - Result Format/,@obj.bankval_int_getaba('csv','12345678','abcd123','12345')
|
24
|
+
#test1_5 tests that csv is returned as the first part of the string will be 'INVALID'
|
25
|
+
assert_match /^INVALID/,@obj.bankval_int_getaba('csv','12345678','abcd123','12345')
|
26
|
+
#test1_6 tests 'json' fails the csv test5
|
27
|
+
assert_no_match /^INVALID/,@obj.bankval_int_getaba('json','12345678','abcd123','12345')
|
28
|
+
#test1_7 tests xml is returned as no parseError will be raised
|
29
|
+
assert_nothing_raised{
|
30
|
+
REXML::Document.new(@obj.bankval_int_getaba('xml','12345678','abcd123','12345')).root.name
|
31
|
+
}
|
32
|
+
#test1_8 tests 'json' fails this xml parse i.e. json doesn't return xml
|
33
|
+
assert_raise (NoMethodError){
|
34
|
+
REXML::Document.new(@obj.bankval_int_getaba('json','12345678','abcd123','12345')).root.name
|
35
|
+
}
|
36
|
+
#test1_9 tests 'csv' fails xml parse i.e. csv doesn't return xml
|
37
|
+
assert_raise (NoMethodError){
|
38
|
+
REXML::Document.new(@obj.bankval_int_getaba('csv','12345678','abcd123','12345')).root.name
|
39
|
+
}
|
40
|
+
#test1_10 tests 'xml' doesn't return json as parse error is raised
|
41
|
+
assert_raise (JSON::ParserError) {
|
42
|
+
JSON[@obj.bankval_int_getaba('xml','12345678','abcd123','12345')]
|
43
|
+
}
|
44
|
+
#test1_11 tests 'csv' doesn't return json
|
45
|
+
assert_raise (JSON::ParserError) {
|
46
|
+
JSON[@obj.bankval_int_getaba('csv','12345678','abcd123','12345')]
|
47
|
+
}
|
48
|
+
#test1_12 tests ''json' returns valid (parsable) json
|
49
|
+
assert_nothing_raised{
|
50
|
+
JSON[@obj.bankval_int_getaba('json','12345678','abcd123','12345')]
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_aba_number_validation
|
55
|
+
#test2_1 check under sized aba is rejected (invalid userid/pin would error first on server)
|
56
|
+
assert_match /^\{"result":"INVALID","routingnumber"/, @obj.bankval_int_getaba('json','12345678','abcd123','12345')
|
57
|
+
#test2_2 check oversized aba is rejected
|
58
|
+
assert_match /^\{"result":"INVALID","routingnumber"/, @obj.bankval_int_getaba('json','1234567890','abcd123','12345')
|
59
|
+
#test2_3 check leading alpha is rejected
|
60
|
+
assert_match /^\{"result":"INVALID","routingnumber"/, @obj.bankval_int_getaba('json','l12345678','abcd123','12345')
|
61
|
+
#test2_4 check trailing alpha is rejected
|
62
|
+
assert_match /^\{"result":"INVALID","routingnumber"/, @obj.bankval_int_getaba('json','12345678g','abcd123','12345')
|
63
|
+
#test2_5 check embedded alpha is rejected
|
64
|
+
assert_match /^\{"result":"INVALID","routingnumber"/, @obj.bankval_int_getaba('json','1234S5678','abcd123','12345')
|
65
|
+
#test2_6 check correct size passes (error will be ID/PIN from server)
|
66
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN","routingnumber"/, @obj.bankval_int_getaba('json','123456789','abcd123','12345')
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_userid_validation #test with wireshark as well as returns are identical from server and client validation
|
70
|
+
#test3_1 too short user id 2nd element
|
71
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN","routingnumber"/, @obj.bankval_int_getaba('json','123456789','abcd12','12345')
|
72
|
+
#test3_2 too long user id 2nd element
|
73
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN","routingnumber"/, @obj.bankval_int_getaba('json','123456789','abcd1234','12345')
|
74
|
+
#test3_3 too short first element
|
75
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN","routingnumber"/, @obj.bankval_int_getaba('json','123456789','ab123','12345')
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_pin #test with wireshark as well (look for client hellos these will match each call to either server)
|
79
|
+
#test4_1 too short
|
80
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN","routingnumber"/, @obj.bankval_int_getaba('json','123456789','abcd012','1234')
|
81
|
+
#test4_2 too long
|
82
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN","routingnumber"/, @obj.bankval_int_getaba('json','123456789','abcd123','123456')
|
83
|
+
#test4_3 bad chars
|
84
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN","routingnumber"/, @obj.bankval_int_getaba('json','123456789','abcd123','12{45') end
|
85
|
+
end
|
86
|
+
|
87
|
+
class BvIntGetSWIFTTest < Test::Unit::TestCase
|
88
|
+
@obj
|
89
|
+
def setup
|
90
|
+
@obj = BankValInternational::GetSWIFT.new
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_return_validation_aba
|
94
|
+
#test1_1 'J-Son' is rejected as invalid result format
|
95
|
+
assert_match /INVALID - Result Format/,@obj.bankval_int_getswift('J-Son','ABICAB99K','abcd123','12345')
|
96
|
+
#tests 1_2 to 1_4 test that 'json','xml','csv' are not rejected as invalis result formats
|
97
|
+
assert_no_match /INVALID - Result Format/,@obj.bankval_int_getswift('json','ABICAB99K','abcd123','12345')
|
98
|
+
assert_no_match /INVALID - Result Format/,@obj.bankval_int_getswift('xml','ABICAB99K','abcd123','12345')
|
99
|
+
assert_no_match /INVALID - Result Format/,@obj.bankval_int_getswift('csv','ABICAB99K','abcd123','12345')
|
100
|
+
#test1_5 tests that csv is returned as the first part of the string will be 'INVALID'
|
101
|
+
assert_match /^INVALID/,@obj.bankval_int_getswift('csv','ABICAB9','abcd123','12345')
|
102
|
+
#test1_6 tests 'json' fails the csv test5
|
103
|
+
assert_no_match /^INVALID/,@obj.bankval_int_getswift('json','ABICAB99K','abcd123','12345')
|
104
|
+
#test1_7 tests xml is returned as no parseError will be raised
|
105
|
+
assert_nothing_raised{
|
106
|
+
REXML::Document.new(@obj.bankval_int_getswift('xml','ABICAB99K','abcd123','12345')).root.name
|
107
|
+
}
|
108
|
+
#test1_8 tests 'json' fails this xml parse i.e. json doesn't return xml
|
109
|
+
assert_raise (NoMethodError){
|
110
|
+
REXML::Document.new(@obj.bankval_int_getswift('json','ABICAB99K','abcd123','12345')).root.name
|
111
|
+
}
|
112
|
+
#test1_9 tests 'csv' fails xml parse i.e. csv doesn't return xml
|
113
|
+
assert_raise (NoMethodError){
|
114
|
+
REXML::Document.new(@obj.bankval_int_getswift('csv','ABICAB99K','abcd123','12345')).root.name
|
115
|
+
}
|
116
|
+
#test1_10 tests 'xml' doesn't return json as parse error is raised
|
117
|
+
assert_raise (JSON::ParserError) {
|
118
|
+
JSON[@obj.bankval_int_getswift('xml','ABICAB99K','abcd123','12345')]
|
119
|
+
}
|
120
|
+
#test1_11 tests 'csv' doesn't return json
|
121
|
+
assert_raise (JSON::ParserError) {
|
122
|
+
JSON[@obj.bankval_int_getswift('csv','ABICAB99K','abcd123','12345')]
|
123
|
+
}
|
124
|
+
#test1_12 tests ''json' returns valid (parsable) json
|
125
|
+
assert_nothing_raised{
|
126
|
+
JSON[@obj.bankval_int_getswift('json','ABICAB99K','abcd123','12345')]
|
127
|
+
}
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_iban_number_validation
|
131
|
+
#test2_1 check under sized IBAN is rejected (invalid userid/pin would error first on server)
|
132
|
+
assert_match /^\{"result":"INVALID","bic"/, @obj.bankval_int_getswift('json','ABICAB9','abcd123','12345')
|
133
|
+
#test2_2 check oversized bic is rejected
|
134
|
+
assert_match /^\{"result":"INVALID","bic"/, @obj.bankval_int_getswift('json','ABICAB9990','abcd123','12345')
|
135
|
+
#test2_3 check leading special char is rejected
|
136
|
+
assert_match /^\{"result":"INVALID","bic"/, @obj.bankval_int_getswift('json','?BICAB99','abcd123','12345')
|
137
|
+
#test2_4 check trailing special char is rejected
|
138
|
+
assert_match /^\{"result":"INVALID","bic"/, @obj.bankval_int_getswift('json','ABICAB9)','abcd123','12345')
|
139
|
+
#test2_5 check embedded special char is rejected
|
140
|
+
assert_match /^\{"result":"INVALID","bic"/, @obj.bankval_int_getswift('json','ABIC@B99','abcd123','12345')
|
141
|
+
#test2_6 check correct size passes (error will be ID/PIN from server)
|
142
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN","bic"/, @obj.bankval_int_getswift('json','ABIBAB99','abcd123','12345')
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_userid_validation #test with wireshark as well as returns are identical from server and client validation
|
146
|
+
#test3_1 too short user id 2nd element
|
147
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN","bic"/, @obj.bankval_int_getswift('json','ABICAB99','abcd12','12345')
|
148
|
+
#test3_2 too long user id 2nd element
|
149
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN","bic"/, @obj.bankval_int_getswift('json','ABICAB99','abcd1234','12345')
|
150
|
+
#test3_3 too short first element
|
151
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN","bic"/, @obj.bankval_int_getswift('json','ABICAB99','ab123','12345')
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_pin #test with wireshark as well (look for client hellos these will match each call to either server)
|
155
|
+
#test4_1 too short
|
156
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN","bic"/, @obj.bankval_int_getswift('json','ABICAB99','abcd012','1234')
|
157
|
+
#test4_2 too long
|
158
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN","bic"/, @obj.bankval_int_getswift('json','ABICAB99','abcd123','123456')
|
159
|
+
#test4_3 bad chars
|
160
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN","bic"/, @obj.bankval_int_getswift('json','ABICAB99','abcd123','12{45')
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
class BvIntGetIBANTest < Test::Unit::TestCase
|
165
|
+
@obj
|
166
|
+
def setup
|
167
|
+
@obj = BankValInternational::GetIBAN.new
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_return_validation_iban
|
171
|
+
#test1_1 'J-Son' is rejected as invalid result format
|
172
|
+
assert_match /INVALID - Result Format/,@obj.bankval_int_ibanval('J-Son','ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789','abcd123','12345')
|
173
|
+
#tests 1_2 to 1_4 test that 'json','xml','csv' are not rejected as invalis result formats
|
174
|
+
assert_no_match /INVALID - Result Format/,@obj.bankval_int_ibanval('json','ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789','abcd123','12345')
|
175
|
+
assert_no_match /INVALID - Result Format/,@obj.bankval_int_ibanval('xml','ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789','abcd123','12345')
|
176
|
+
assert_no_match /INVALID - Result Format/,@obj.bankval_int_ibanval('csv','ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789','abcd123','12345')
|
177
|
+
#test1_5 tests that csv is returned as the first part of the string will be 'INVALID'
|
178
|
+
assert_match /^INVALID/,@obj.bankval_int_ibanval('csv','ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789','abcd123','12345')
|
179
|
+
#test1_6 tests 'json' fails the csv test5
|
180
|
+
assert_no_match /^INVALID/,@obj.bankval_int_ibanval('json','ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789','abcd123','12345')
|
181
|
+
#test1_7 tests xml is returned as no parseError will be raised
|
182
|
+
assert_nothing_raised{
|
183
|
+
REXML::Document.new(@obj.bankval_int_ibanval('xml','ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789','abcd123','12345')).root.name
|
184
|
+
}
|
185
|
+
#test1_8 tests 'json' fails this xml parse i.e. json doesn't return xml
|
186
|
+
assert_raise (NoMethodError){
|
187
|
+
REXML::Document.new(@obj.bankval_int_ibanval('json','ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789','abcd123','12345')).root.name
|
188
|
+
}
|
189
|
+
#test1_9 tests 'csv' fails xml parse i.e. csv doesn't return xml
|
190
|
+
assert_raise (NoMethodError){
|
191
|
+
REXML::Document.new(@obj.bankval_int_ibanval('csv','ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789','abcd123','12345')).root.name
|
192
|
+
}
|
193
|
+
#test1_10 tests 'xml' doesn't return json as parse error is raised
|
194
|
+
assert_raise (JSON::ParserError) {
|
195
|
+
JSON[@obj.bankval_int_ibanval('xml','ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789','abcd123','12345')]
|
196
|
+
}
|
197
|
+
#test1_11 tests 'csv' doesn't return json
|
198
|
+
assert_raise (JSON::ParserError) {
|
199
|
+
JSON[@obj.bankval_int_ibanval('csv','ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789','abcd123','12345')]
|
200
|
+
}
|
201
|
+
#test1_12 tests ''json' returns valid (parsable) json
|
202
|
+
assert_nothing_raised{
|
203
|
+
JSON[@obj.bankval_int_ibanval('json','ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789','abcd123','12345')]
|
204
|
+
}
|
205
|
+
end
|
206
|
+
|
207
|
+
def test_iban_number_validation
|
208
|
+
#test2_1 check oversized iban is rejected
|
209
|
+
assert_match /^\{"result":"INVALID - FORMAT"/, @obj.bankval_int_ibanval('json','ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789','abcd123','12345')
|
210
|
+
#test2_2 check leading special char is rejected
|
211
|
+
assert_match /^\{"result":"INVALID - FORMAT"/, @obj.bankval_int_ibanval('json','*ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567','abcd123','12345')
|
212
|
+
#test2_3 check trailing special char is rejected
|
213
|
+
assert_match /^\{"result":"INVALID - FORMAT"/, @obj.bankval_int_ibanval('json','ABCDEFGHIJKLMNOPQRSTUVWXYZ123:','abcd123','12345')
|
214
|
+
#test2_4 check embedded special char is rejected
|
215
|
+
assert_match /^\{"result":"INVALID - FORMAT"/, @obj.bankval_int_ibanval('json','SJKDFHJKSGHKJDFGH&&KLFJGDKLFJF','abcd123','12345')
|
216
|
+
#test2_5 check correct size passes (error will be ID/PIN from server)
|
217
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN"/, @obj.bankval_int_ibanval('json','ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678','abcd123','12345')
|
218
|
+
end
|
219
|
+
|
220
|
+
def test_userid_validation #test with wireshark as well as returns are identical from server and client validation
|
221
|
+
#test3_1 too short user id 2nd element
|
222
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN"/, @obj.bankval_int_ibanval('json','ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678','abcd12','12345')
|
223
|
+
#test3_2 too long user id 2nd element
|
224
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN"/, @obj.bankval_int_ibanval('json','ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678','abcd1234','12345')
|
225
|
+
#test3_3 too short first element
|
226
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN"/, @obj.bankval_int_ibanval('json','ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678','ab123','12345')
|
227
|
+
end
|
228
|
+
|
229
|
+
def test_pin #test with wireshark as well (look for client hellos these will match each call to either server)
|
230
|
+
#test4_1 too short
|
231
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN"/, @obj.bankval_int_ibanval('json','ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678','abcd012','1234')
|
232
|
+
#test4_2 too long
|
233
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN"/, @obj.bankval_int_ibanval('json','ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678','abcd123','123456')
|
234
|
+
#test4_3 bad chars
|
235
|
+
assert_match /^\{"result":"ERROR - Invalid User ID\/PIN"/, @obj.bankval_int_ibanval('json','ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678','abcd123','12{45')
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: BankValInt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Alec Evans, Unified Software
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-07-29 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: Module containing classes to handle calls to Unified Software's International Bank Validation REST web services BankValInternational Services catered for by this module are getABAdetails, ibanValidate and getBankDetails2
|
23
|
+
email: support@unifiedsoftware.co.uk
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files:
|
29
|
+
- README
|
30
|
+
- LICENSE
|
31
|
+
files:
|
32
|
+
- LICENSE
|
33
|
+
- README
|
34
|
+
- Rakefile
|
35
|
+
- lib/BankValInternational.rb
|
36
|
+
- test/bv_int_test.rb
|
37
|
+
has_rdoc: true
|
38
|
+
homepage: http://www.unifiedsoftware.co.uk
|
39
|
+
licenses:
|
40
|
+
- LICENSE
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options: []
|
43
|
+
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
hash: 3
|
52
|
+
segments:
|
53
|
+
- 0
|
54
|
+
version: "0"
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 3
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
version: "0"
|
64
|
+
requirements: []
|
65
|
+
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.3.7
|
68
|
+
signing_key:
|
69
|
+
specification_version: 3
|
70
|
+
summary: Module containing classes to handle calls to Unified Software's International Bank Validation REST web services
|
71
|
+
test_files: []
|
72
|
+
|