visa_net_uy 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ad64233849757db1536cd45e307ff682508b665b
4
+ data.tar.gz: 624d3631474c34e995809dae1c77f9ddf444d7e0
5
+ SHA512:
6
+ metadata.gz: b89980a6947726cdb0ad86d3c9448095832a65b4fabdca6aff90867b14dd7a800aa5faf6f48b047ba4752e3e346be92c797ba6d1a26e48e26e4822f1f239ab38
7
+ data.tar.gz: c336e03d91225810cb9aae7d831d6ffe018dd1ae756c7a3ffbe700c46a91230aea3b85cfad27eccf1065d1541f54d36a201bafc92d38a59ff342d2e005db14bb
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in visa_net_uy.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 TODO: Write your name
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following 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 OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # VisaNetUy
2
+
3
+ VisaNet PHP PlugIn port for ruby.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'visa_net_uy'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install visa_net_uy
18
+
19
+ ## Usage
20
+
21
+ Initialize PlugIn
22
+
23
+ plugin = VisaNetUy::PlugIn.new do |p|
24
+ p.cipher_public_key = File.read 'ALIGNET.PHP.CRYPTO.PUBLIC.txt'
25
+ p.cipher_private_key = File.read 'MILLAVE.CIFRADO.PRIVADA.txt'
26
+ p.signature_public_key = File.read 'ALIGNET.PHP.SIGNATURE.PUBLIC.txt'
27
+ p.signature_private_key = File.read 'MILLAVE.TESTING.FIRMA.PRIVADA.txt'
28
+ p.iv = '0123456789ABCDEF'
29
+ end
30
+
31
+ Generate POST request parameters
32
+
33
+ plugin.vpos_request_params({
34
+ 'acquirerId' => '11',
35
+ 'commerceId' => '1111',
36
+ 'purchaseOperationNumber' => "111111",
37
+ 'purchaseAmount' => '10099',
38
+ 'purchaseCurrencyCode' => '858',
39
+ 'terminalCode' => 'VBV00111'})
40
+
41
+ Get response fields from VisaNet callback
42
+
43
+ plugin.vpos_response_fields(response)
44
+
45
+ ## Contributing
46
+
47
+ 1. Fork it ( https://github.com/andres99x/visa_net_uy/fork )
48
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
49
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
50
+ 4. Push to the branch (`git push origin my-new-feature`)
51
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ # Default directory to look in is `/specs`
5
+ # Run with `rake spec`
6
+ RSpec::Core::RakeTask.new(:spec) do |task|
7
+ task.rspec_opts = ['--color', '--format', 'progress']
8
+ end
9
+
10
+ task :default => :spec
11
+ task :test => :spec
@@ -0,0 +1,90 @@
1
+ require_relative 'encoder'
2
+ require 'openssl'
3
+
4
+ class VisaNetUy::Cipher
5
+ include VisaNetUy::Encoder
6
+
7
+ CIPHER_ALGORITHM = "DES-EDE3-CBC"
8
+
9
+ # Generates a session_key
10
+ def generate_session_key
11
+ # Generate random session key with 16 bytes length
12
+ OpenSSL::Random.random_bytes(16)
13
+ end
14
+
15
+ # Encrypt data using the public_key
16
+ def urlsafe_base64_asymmetric_encrypt(data, public_key)
17
+ # Load key
18
+ pkey = OpenSSL::PKey::RSA.new(public_key, nil)
19
+ raise 'Invalid public key.' unless pkey.public?
20
+
21
+ # Encrypt data
22
+ encrypted_data = pkey.public_encrypt(data)
23
+ # Encode encrypted data with custom Encoder
24
+ custom_base64_urlsafe_encode(encrypted_data)
25
+ end
26
+
27
+ # Decrypt data using the private_key
28
+ def urlsafe_base64_asymmetric_decrypt(urlsafe_base64_encrypted_data, private_key)
29
+ # Load key
30
+ pkey = OpenSSL::PKey::RSA.new(private_key, nil)
31
+ raise 'Invalid private key.' unless pkey.private?
32
+
33
+ # Decode encrypted data with custom decoding
34
+ encrypted_data = custom_base64_urlsafe_decode(urlsafe_base64_encrypted_data)
35
+ # Decrypt encrypted data
36
+ pkey.private_decrypt(encrypted_data)
37
+ end
38
+
39
+ # Encrypt data with key
40
+ def urlsafe_base64_symmetric_encrypt(data, key, iv)
41
+ raise 'Initialization Vector must have 16 hexadecimal characters.' unless iv.length == 16
42
+ raise 'Key must have 16 hexadecimal characters.' unless key.length == 16
43
+
44
+ bin_iv = [iv].pack('H*')
45
+ raise 'Initialization Vector is not valid, must contain only hexadecimal characters.' if bin_iv.empty?
46
+
47
+ # Appends first 8 Bytes to Key
48
+ key += key.byteslice(0,8)
49
+
50
+ # Create Cipher
51
+ cipher = OpenSSL::Cipher.new(CIPHER_ALGORITHM)
52
+ # Initialize cipher mode
53
+ cipher.encrypt
54
+ # Set initialization vector
55
+ cipher.iv = bin_iv
56
+ # Set key
57
+ cipher.key = key
58
+
59
+ # Encrypt data
60
+ encrypted_data = cipher.update(data) + cipher.final
61
+ # Encode data
62
+ custom_base64_urlsafe_encode(encrypted_data)
63
+ end
64
+
65
+ def urlsafe_base64_symmetric_decrypt(urlsafe_base64_encrypted_data, key, iv)
66
+ raise 'Initialization Vector must have 16 hexadecimal characters.' unless iv.length == 16
67
+ raise 'Key must have 16 hexadecimal characters.' unless key.length == 16
68
+
69
+ bin_iv = [iv].pack('H*')
70
+ raise 'Initialization Vector is not valid, must contain only hexadecimal characters.' if bin_iv.empty?
71
+
72
+ # Appends first 8 Bytes to Key
73
+ key += key.byteslice(0,8)
74
+
75
+ # Create Cipher
76
+ cipher = OpenSSL::Cipher.new(CIPHER_ALGORITHM)
77
+ # Initialize cipher mode
78
+ cipher.decrypt
79
+ # Set initialization vector
80
+ cipher.iv = bin_iv
81
+ # Set key
82
+ cipher.key = key
83
+
84
+ # Decode data
85
+ encrypted_data = custom_base64_urlsafe_decode(urlsafe_base64_encrypted_data)
86
+ # Decrypt data
87
+ data = cipher.update(encrypted_data) + cipher.final
88
+ end
89
+
90
+ end
@@ -0,0 +1,15 @@
1
+ require "base64"
2
+
3
+ module VisaNetUy
4
+ module Encoder
5
+ # Encodes to URLSafe Base64 and replaces = with .
6
+ def custom_base64_urlsafe_encode(data)
7
+ Base64.urlsafe_encode64(data).gsub('=','.')
8
+ end
9
+
10
+ # Decodes from URLSafe Base64 and replaces . with =
11
+ def custom_base64_urlsafe_decode(encoded_data)
12
+ Base64.urlsafe_decode64(encoded_data.gsub('.','='))
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,76 @@
1
+ class VisaNetUy::PlugIn
2
+
3
+ attr_accessor :cipher_public_key, :cipher_private_key, :signature_public_key, :signature_private_key, :iv
4
+
5
+ def initialize(options = {})
6
+ unless block_given?
7
+ options.each do |key, value|
8
+ send(:"#{key}=", value)
9
+ end
10
+ else
11
+ yield(self)
12
+ end
13
+ end
14
+
15
+ def vpos_request_params(fields)
16
+ request_params = {}
17
+
18
+ # Check for required fields
19
+ fields.include?('acquirerId') ? (request_params['IDACQUIRER'] = fields['acquirerId']) : (raise "Misssing acquirerId field.")
20
+ fields.include?('commerceId') ? (request_params['IDCOMMERCE'] = fields['commerceId']) : (raise "Misssing commerceId field.")
21
+
22
+ # Generate XML from fields
23
+ xml = xmler.generate(fields)
24
+
25
+ # Generate SessionKey
26
+ session_key = cipher.generate_session_key
27
+
28
+ # Generate digital signature
29
+ urlsafe_base64_signature = signer.generate_urlsafe_base64_signature(xml, signature_private_key)
30
+ request_params['DIGITALSIGN'] = urlsafe_base64_signature
31
+
32
+ # Cipher XML
33
+ urlsafe_base64_encrypted_xml = cipher.urlsafe_base64_symmetric_encrypt(xml, session_key, iv)
34
+ request_params['XMLREQ'] = urlsafe_base64_encrypted_xml
35
+
36
+ # Cipher SessionKey
37
+ urlsafe_base64_encrypted_session_key = cipher.urlsafe_base64_asymmetric_encrypt(session_key, cipher_public_key)
38
+ request_params['SESSIONKEY'] = urlsafe_base64_encrypted_session_key
39
+
40
+ request_params
41
+ end
42
+
43
+ def vpos_response_fields(response)
44
+ # Check for required fields
45
+ response.include?('SESSIONKEY') ? (session_key = response['SESSIONKEY']) : (raise "Misssing SESSIONKEY.")
46
+ response.include?('XMLRES') ? (xmlres = response['XMLRES']) : (raise "Misssing XMLRES.")
47
+ response.include?('DIGITALSIGN') ? (digital_sing = response['DIGITALSIGN']) : (raise "Misssing DIGITALSIGN.")
48
+
49
+ # Decrypt Session Key
50
+ session_key = cipher.urlsafe_base64_asymmetric_decrypt(session_key, cipher_private_key)
51
+
52
+ # Decrypt XML
53
+ xml = cipher.urlsafe_base64_symmetric_decrypt(xmlres, session_key, iv)
54
+
55
+ # Verify Signature
56
+ raise 'Invalid Signature.' unless signer.verify_urlsafe_base64_signature(xml, digital_sing, signature_public_key)
57
+
58
+ # Parse XML
59
+ xmler.parse(xml)
60
+ end
61
+
62
+ protected
63
+
64
+ def xmler
65
+ @xmler ||= VisaNetUy::Xmler.new
66
+ end
67
+
68
+ def cipher
69
+ @cipher ||= VisaNetUy::Cipher.new
70
+ end
71
+
72
+ def signer
73
+ @signer ||= VisaNetUy::Signer.new
74
+ end
75
+
76
+ end
@@ -0,0 +1,42 @@
1
+ require_relative 'encoder'
2
+ require 'openssl'
3
+
4
+ class VisaNetUy::Signer
5
+ include VisaNetUy::Encoder
6
+
7
+ DIGEST_ALGORITHM = 'SHA1'
8
+
9
+ # Generates an urlsafe_base64_signature
10
+ def generate_urlsafe_base64_signature(data, private_key)
11
+ # Load Keys
12
+ pkey = OpenSSL::PKey::RSA.new(private_key, nil)
13
+ raise 'Invalid private key.' unless pkey.private?
14
+
15
+ # Create Digester
16
+ digest = OpenSSL::Digest.new(DIGEST_ALGORITHM)
17
+
18
+ # Generate Signature
19
+ signature = pkey.sign(digest, data)
20
+ raise 'RSA signing unsuccessful.' unless signature
21
+
22
+ # Encode Signature with custom Encoder
23
+ custom_base64_urlsafe_encode(signature)
24
+ end
25
+
26
+ # Verifies an urlsafe_base64_signature
27
+ def verify_urlsafe_base64_signature(data, urlsafe_base64_signature, public_key)
28
+ # Load Key
29
+ pkey = OpenSSL::PKey::RSA.new(public_key, nil)
30
+ raise 'Invalid public key.' unless pkey.public?
31
+
32
+ # Decode Signature with custom decoding
33
+ signature = custom_base64_urlsafe_decode(urlsafe_base64_signature)
34
+
35
+ # Create Digester
36
+ digest = OpenSSL::Digest.new(DIGEST_ALGORITHM)
37
+
38
+ # Vefify Signature
39
+ pkey.public_key.verify(digest, signature, data)
40
+ end
41
+
42
+ end
@@ -0,0 +1,3 @@
1
+ module VisaNetUy
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,71 @@
1
+ require "rexml/document"
2
+
3
+ # Monkey Patching
4
+ module REXML
5
+ class XMLDecl
6
+
7
+ private
8
+ # Force to use double-quotation as attribute delimiter and downcase encoding name for XMLDecl
9
+ def content(enc)
10
+ rv = "version=\"#@version\""
11
+ rv << " encoding=\"#{enc.downcase}\"" if @writeencoding || enc !~ /\Autf-8\z/i
12
+ rv << " standalone=\"#@standalone\"" if @standalone
13
+ rv
14
+ end
15
+
16
+ end
17
+ end
18
+
19
+ class VisaNetUy::Xmler
20
+ include REXML
21
+
22
+ VERSION = '1.0'
23
+ Encoding = 'ISO-8859-1'
24
+ ROOT_NAME = 'VPOSTransaction1.2'
25
+
26
+ def generate(fields)
27
+ fields_temp = {}
28
+
29
+ dom = Document.new
30
+ dom << XMLDecl.new(VERSION, Encoding)
31
+
32
+ root = Element.new(ROOT_NAME)
33
+ dom << root
34
+
35
+ fields.each_pair do |field, value|
36
+ if VisaNetUy::VALID_FIELDS.include? field
37
+ fields_temp[field] = value
38
+ else
39
+ raise "#{field} is not a valid field."
40
+ end
41
+ end
42
+
43
+ fields_temp.each_pair do |field, value|
44
+ element = Element.new(field)
45
+ element.text = value
46
+
47
+ root << element
48
+ end
49
+
50
+ xml = ''
51
+ dom.write(xml)
52
+
53
+ xml
54
+ end
55
+
56
+ def parse(xml)
57
+ fields = {}
58
+
59
+ dom = Document.new(xml)
60
+ root = dom.root
61
+
62
+ return fields unless root.name == ROOT_NAME
63
+
64
+ root.elements.each do |child|
65
+ fields[child.name] = child.get_text
66
+ end
67
+
68
+ fields
69
+ end
70
+
71
+ end
@@ -0,0 +1,82 @@
1
+ require "visa_net_uy/encoder"
2
+ require "visa_net_uy/cipher"
3
+ require "visa_net_uy/plug_in"
4
+ require "visa_net_uy/signer"
5
+ require "visa_net_uy/version"
6
+ require "visa_net_uy/xmler"
7
+
8
+ module VisaNetUy
9
+
10
+ VALID_FIELDS = [
11
+ 'acquirerId',
12
+ 'commerceId',
13
+ 'purchaseCurrencyCode',
14
+ 'purchaseIPAddress',
15
+ 'purchaseAmount',
16
+ 'purchaseOperationNumber',
17
+ 'billingAddress',
18
+ 'billingCity',
19
+ 'billingState',
20
+ 'billingCountry',
21
+ 'billingZIP',
22
+ 'billingPhone',
23
+ 'billingEMail',
24
+ 'billingFirstName',
25
+ 'billingLastName',
26
+ 'language',
27
+ 'commerceMallId',
28
+ 'terminalCode',
29
+ 'tipAmount',
30
+ 'HTTPSessionId',
31
+ 'shippingAddress',
32
+ 'shippingCity',
33
+ 'shippingState',
34
+ 'shippingCountry',
35
+ 'shippingZIP',
36
+ 'shippingPhone',
37
+ 'shippingEMail',
38
+ 'shippingFirstName',
39
+ 'shippingLastName',
40
+ 'reserved1',
41
+ 'reserved2',
42
+ 'reserved3',
43
+ 'reserved4',
44
+ 'reserved5',
45
+ 'reserved6',
46
+ 'reserved7',
47
+ 'reserved8',
48
+ 'reserved9',
49
+ 'reserved10',
50
+ 'reserved11',
51
+ 'reserved12',
52
+ 'reserved13',
53
+ 'reserved14',
54
+ 'reserved15',
55
+ 'reserved16',
56
+ 'reserved17',
57
+ 'reserved18',
58
+ 'reserved19',
59
+ 'reserved20',
60
+ 'reserved21',
61
+ 'reserved22',
62
+ 'reserved23',
63
+ 'reserved24',
64
+ 'reserved25',
65
+ 'reserved26',
66
+ 'reserved27',
67
+ 'reserved28',
68
+ 'reserved29',
69
+ 'reserved30',
70
+ 'reserved31',
71
+ 'reserved32',
72
+ 'reserved33',
73
+ 'reserved34',
74
+ 'reserved35',
75
+ 'reserved36',
76
+ 'reserved37',
77
+ 'reserved38',
78
+ 'reserved39',
79
+ 'reserved40'
80
+ ]
81
+
82
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'VisaNetUy::PlugIn' do
4
+
5
+ pending 'Testing Pending'
6
+
7
+ end
@@ -0,0 +1 @@
1
+ require 'visa_net_uy'
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'visa_net_uy/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'visa_net_uy'
8
+ spec.version = VisaNetUy::VERSION
9
+ spec.date = '2010-04-28'
10
+ spec.summary = "VisaNet PlugIn for ruby!"
11
+ spec.description = "VisaNet PHP PlugIn port for ruby."
12
+ spec.authors = ["Andres Pache", "TopTierLabs"]
13
+ spec.email = 'apache90@gmail.com'
14
+ spec.homepage = 'https://github.com/andres99x/visa_net_uy'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.6"
23
+ spec.add_development_dependency "rake"
24
+ spec.add_development_dependency "rspec"
25
+ end
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: visa_net_uy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Andres Pache
8
+ - TopTierLabs
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2010-04-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.6'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.6'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ description: VisaNet PHP PlugIn port for ruby.
57
+ email: apache90@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - lib/visa_net_uy.rb
68
+ - lib/visa_net_uy/cipher.rb
69
+ - lib/visa_net_uy/encoder.rb
70
+ - lib/visa_net_uy/plug_in.rb
71
+ - lib/visa_net_uy/signer.rb
72
+ - lib/visa_net_uy/version.rb
73
+ - lib/visa_net_uy/xmler.rb
74
+ - spec/lib/visa_net_uy/plug_in_spec.rb
75
+ - spec/spec_helper.rb
76
+ - visa_net_uy.gemspec
77
+ homepage: https://github.com/andres99x/visa_net_uy
78
+ licenses:
79
+ - MIT
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.2.2
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: VisaNet PlugIn for ruby!
101
+ test_files:
102
+ - spec/lib/visa_net_uy/plug_in_spec.rb
103
+ - spec/spec_helper.rb