dacom 1.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c4adad2f3b162567c090a3907b1579d4f12f4e2c
4
+ data.tar.gz: f2f49c2346b0b0ec1dc6bc96cce2ca87c0ffac86
5
+ SHA512:
6
+ metadata.gz: f6e49732dac73d2b1cb8eb8b2db41d4a04e9274fa332c7e1e21c894c1e1b460460b61a149530caf7bc434afed0a45d2cacbe4cdf53afc5cad0688ce930b1b8f6
7
+ data.tar.gz: a4bd33c0ae5a5a15c51f41337328c00574579c1866c2930c998b20e302ca27203c322d0b1b874c59bfea7f1a570dee1d06a8da97055c35601bd094e7153f5eb1
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.gem
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - 2.0.0
7
+ - 2.1.8
8
+ - 2.2.1
9
+ - 2.3.0
10
+ before_install: gem install bundler -v 1.11.2
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at costajob@gmail.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in dacom.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 costajob
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,68 @@
1
+ ## Table of Contents
2
+
3
+ * [Scope](#scope)
4
+ * [Payment process](#payment-process)
5
+ * [Client script](#client-script)
6
+ * [Collecting data](#collecting-data)
7
+ * [API](#api)
8
+ * [Configuration](#configuration)
9
+ * [Constructor](#constructor)
10
+ * [Response](#Response)
11
+ * [Catch all](#catch-all)
12
+ * [Constants](#constants)
13
+ * [Rollback](#rollback)
14
+ * [Report](#report)
15
+
16
+ ## Scope
17
+ This gem is a Ruby porting of the XPay client library used by the [Dacom LGD](http://lgdacom.net/) payment gateway for Korea.
18
+
19
+ ## Payment process
20
+ The LGD XPay client is used to generate some unique keys mandatory to complete the
21
+ payment process with LGD.
22
+
23
+ ### Client script
24
+ The payment work flow happens on LGD servers by including a [JavaScript](https://xpay.lgdacom.net/xpay/js/xpay_crossplatform.js) in the page that:
25
+ * reads the data generated by the ruby library and set some hidden fields of a form
26
+ * set the form action
27
+ * open an iframe windows pointing to the LGD platform
28
+ * submit the forms with parameters collected by the iframe
29
+
30
+ ### Collecting data
31
+ Once the payment is completed, the iframe is closed and some data retruned to the parent site.
32
+ These data has to be send via the Ruby XPay client and the response of the service has to be collected by Site.
33
+
34
+ ## API
35
+ The API of the client is pretty small. The library expose one single public method, called *tx*, used to communicate the data to LGD server.
36
+ The data are collected by using a hash object, then submitted as the form-data attribute.
37
+
38
+ ### Configuration
39
+ Some configuration, such as the merchant key, id and other options, are fetched by a YML file.
40
+ Some configuration keys are available for the test environment too.
41
+
42
+ ### Constructor
43
+ Several instance variables are instantiated at construction time:
44
+ * the data fetched by the configuration collaborator
45
+ * the hashed keys created by using the SHA1 digest
46
+ * the hash object used to set the request form data
47
+
48
+ ### Response
49
+ A response object collaborator is used and always returned by the library.
50
+ The data of the response are collected by parsing the JSON returned by LGD or by
51
+ rescuing from an error.
52
+ The object is always filled with a code and a message attributes.
53
+
54
+ ### Catch all
55
+ The library does not halt on exceptions, but on the higher ones (aka system failure).
56
+ This design is used to allow returning meaningful responses basing on the kind of errors raised (JSON parse, timeout, SSL error, etc).
57
+ All exceptions are wrapped by a general one, then rescued by the *tx* method.
58
+ I know using exceptions as control flow is not terrific, but i tried to mimic as much as possible the original behaviour of the PHP/Java versions.
59
+ To mitigate i log every error on a custom collaborator.
60
+
61
+ ### Constants
62
+ A set of constants are defined by an external module. They identifies the error codes to be used in case of exceptions and are set on the response object.
63
+
64
+ ### Rollback
65
+ In case of issues the library notifies LGD with a rollback request. The object subclass the Client one, since it needs to initialize the same hash keys.
66
+
67
+ ### Report
68
+ The same approach is used to report LGD about the failure. Both communications happens inside a separate thread of execution to have less impact on the system.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:spec) do |t|
5
+ t.libs << "spec"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['spec/**/*_spec.rb']
8
+ end
9
+
10
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'dacom'
5
+ require 'irb'
6
+ require 'irb/completion'
7
+
8
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/config/dacom.yml ADDED
@@ -0,0 +1,14 @@
1
+ url: "https://xpayclient.lgdacom.net/xpay/Gateway.do"
2
+ test_url: "https://xpayclient.lgdacom.net:7443/xpay/Gateway.do"
3
+ aux_url: "http://xpay.lgdacom.net:7080/xpay/Gateway.do"
4
+ server_id: <%= ENV.fetch("SERVER_ID") { "01" } %>
5
+ timeout: 60
6
+ verify_cert: false
7
+ verify_host: false
8
+ report_error: true
9
+ auto_rollback: true
10
+ mert_id: "lgdacomxpay"
11
+ mert_key: <%= ENV.fetch("MERT_KEY") { "live_key" } %>
12
+ test_mert_id: "tlgdacomxpay"
13
+ test_mert_key: <%= ENV.fetch("TEST_MERT_KEY") { "test_key" } %>
14
+ test_mode: true
data/dacom.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'dacom/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "dacom"
8
+ s.version = Dacom::VERSION
9
+ s.authors = ["costajob"]
10
+ s.email = ["costajob@gmail.com"]
11
+ s.summary = %q{A Ruby port of the Dacom (LGU+) XPay client library}
12
+ s.homepage = "https://github.com/costajob/dacom"
13
+ s.license = "MIT"
14
+ s.required_ruby_version = ">= 1.8.7"
15
+
16
+ s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ s.bindir = "exe"
18
+ s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_runtime_dependency "json"
22
+ s.add_development_dependency "bundler", "~> 1.11"
23
+ s.add_development_dependency "rake", "~> 10.0"
24
+ s.add_development_dependency "minitest", "~> 5.0"
25
+ s.add_development_dependency "rr"
26
+ end
data/lib/dacom.rb ADDED
@@ -0,0 +1,2 @@
1
+ require "dacom/version"
2
+ require "dacom/client"
@@ -0,0 +1,197 @@
1
+ require 'net/https'
2
+ require 'uri'
3
+ require 'openssl'
4
+ require 'json'
5
+ require 'logger'
6
+ require 'dacom/config'
7
+ require 'dacom/constants'
8
+ require 'dacom/response'
9
+
10
+ module Dacom
11
+ class Client
12
+ include Constants
13
+
14
+ LOGGER_PATH = File::expand_path("../../../log/dacom.log", __FILE__)
15
+
16
+ class ResponseError < StandardError; end
17
+ class HTTPCodeError < StandardError; end
18
+
19
+ attr_reader :response, :form_data
20
+
21
+ def initialize(options = {})
22
+ @config = options.fetch(:config) { Config::new }
23
+ @logger = options.fetch(:logger) { Logger::new(LOGGER_PATH) }
24
+ @mid = @config.merchant_id
25
+ @mert_key = @config.merchant_key
26
+ @auto_rollback = @config.auto_rollback
27
+ @report_error = @config.report_error
28
+ @endpoint = @config.url
29
+ @tx_id = gen_tx_id
30
+ @auth_code = gen_auth_code
31
+ @form_data = init_form_data
32
+ end
33
+
34
+ def tx
35
+ json = do_request
36
+ data = parse_response(json)
37
+ @response = Response::new(data)
38
+ @logger.info("response: #{@response}")
39
+ @response
40
+ rescue ResponseError => e
41
+ @logger.error("rescue from ResponseError - #{e.message} \n #{e.backtrace.join("\n")}")
42
+ rollback
43
+ report
44
+ @response
45
+ end
46
+
47
+ def set(k, v)
48
+ @form_data[k] = v
49
+ end
50
+
51
+ private
52
+
53
+ def rollback
54
+ return unless @auto_rollback
55
+ rollback_client = RollbackClient::new(:config => @config,
56
+ :parent_id => @tx_id,
57
+ :reason => rollback_reason)
58
+ Thread::new { rollback_client.tx }
59
+ end
60
+
61
+ def report
62
+ return unless @report_error
63
+ report_client = ReportClient::new(:config => @config,
64
+ :status => @response.code,
65
+ :message => @response.message)
66
+ Thread::new { report_client.tx }
67
+ end
68
+
69
+ def parse_response(json)
70
+ JSON::parse(json)
71
+ rescue JSON::ParserError => e
72
+ set_response_and_raise(LGD_ERR_JSON_DECODE, e)
73
+ end
74
+
75
+ def init_form_data
76
+ { "LGD_TXID" => @tx_id, "LGD_AUTHCODE" => @auth_code, "LGD_MID" => @mid }
77
+ end
78
+
79
+ def gen_tx_id
80
+ sha = OpenSSL::Digest::SHA1.new
81
+ sha.update(get_unique)
82
+ "#{tx_header}#{sha}"
83
+ end
84
+
85
+ def gen_auth_code
86
+ sha = OpenSSL::Digest::SHA1.new
87
+ sha.update("#{@tx_id}#{@mert_key}").to_s
88
+ end
89
+
90
+ def tx_header
91
+ "#{@mid}-#{@config.server_id}#{timestamp}"
92
+ end
93
+
94
+ def get_unique
95
+ "#{timestamp}#{rand_three_digits}"
96
+ end
97
+
98
+ def rand_three_digits
99
+ "%03d" % rand(1000)
100
+ end
101
+
102
+ def timestamp
103
+ Time.now.getutc.strftime("%Y%m%d%H%M%S")
104
+ end
105
+
106
+ def rollback_reason
107
+ return "Timeout" if @response.code == LGD_ERR_TIMEDOUT
108
+ return "HTTP #{@http_code}" if (500...599) === @http_code.to_i
109
+ @response.message
110
+ end
111
+
112
+ def do_request
113
+ req, http = prepare_http_client
114
+ @logger.info("request: #{@endpoint} - #{@form_data.inspect}")
115
+ res = http.request(req)
116
+ set_http_code(res.code)
117
+ res.body
118
+ rescue Timeout::Error => e
119
+ set_response_and_raise(LGD_ERR_TIMEDOUT, e)
120
+ rescue SocketError => e
121
+ set_response_and_raise(LGD_ERR_RESOLVE_HOST, e)
122
+ rescue OpenSSL::SSL::SSLError => e
123
+ set_response_and_raise(LGD_ERR_SSL, e)
124
+ rescue HTTPCodeError => e
125
+ set_response_and_raise("#{30000+@http_code}", e)
126
+ rescue StandardError => e
127
+ set_response_and_raise(LGD_ERR_CONNECT, e)
128
+ end
129
+
130
+ def set_response_and_raise(code, e)
131
+ @response = Response::new(:code => code, :message => e.message)
132
+ @logger.info("response: #{@response}")
133
+ @logger.error("rescue from #{e.class} - #{e.message} \n #{e.backtrace.join("\n")}")
134
+ raise ResponseError, e.message
135
+ end
136
+
137
+ def prepare_http_client
138
+ url = URI.parse(@endpoint)
139
+ req = Net::HTTP::Post.new(url.path)
140
+ req["User-Agent"] = LGD_USER_AGENT
141
+ req.set_form_data(@form_data)
142
+ http = Net::HTTP.new(url.host, url.port)
143
+ http.open_timeout = http.read_timeout = @config.timeout
144
+ if url.scheme == "https"
145
+ http.use_ssl = true
146
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER if @config.verify_peer?
147
+ end
148
+ [req, http]
149
+ end
150
+
151
+ def set_http_code(code)
152
+ @http_code = code.to_i
153
+ fail HTTPCodeError, "invalid HTTP code #{code}" unless http_code_valid?
154
+ end
155
+
156
+ def http_code_valid?
157
+ (200...300) === @http_code
158
+ end
159
+ end
160
+
161
+ class EventClient < Client
162
+ def initialize(options = {})
163
+ super(options)
164
+ @auto_rollback = false
165
+ @report_error = false
166
+ end
167
+ end
168
+
169
+ class RollbackClient < EventClient
170
+ def initialize(options = {})
171
+ @parent_id = options.fetch(:parent_id) { fail ArgumentError, "missing parent ID" }
172
+ @reason = options.fetch(:reason) { fail ArgumentError, "missing parent reason" }
173
+ super(options)
174
+ end
175
+
176
+ private
177
+
178
+ def init_form_data
179
+ super.merge({ "LGD_TXID" => @parent_id, "LGD_TXNAME" => "Rollback", "LGD_RB_TXID" => @tx_id, "LGD_RB_REASON" => @reason })
180
+ end
181
+ end
182
+
183
+ class ReportClient < EventClient
184
+ def initialize(options = {})
185
+ @status = options.fetch(:status) { fail ArgumentError, "missing status" }
186
+ @message = options.fetch(:message) { fail ArgumentError, "missing message" }
187
+ super(options)
188
+ @endpoint = @config.aux_url
189
+ end
190
+
191
+ private
192
+
193
+ def init_form_data
194
+ super.merge({ "LGD_TXNAME" => "Report", "LGD_STATUS" => @status, "LGD_MSG" => @message })
195
+ end
196
+ end
197
+ end
@@ -0,0 +1,54 @@
1
+ require 'yaml'
2
+ require 'erb'
3
+
4
+ module Dacom
5
+ class Config
6
+ CONFIG_PATH = File::expand_path("../../../config/dacom.yml", __FILE__)
7
+
8
+ def initialize(path = CONFIG_PATH)
9
+ @path = path
10
+ @config = fetch_config
11
+ end
12
+
13
+ %w[server_id timeout verify_cert verify_host auto_rollback report_error aux_url].each do |msg|
14
+ define_method(msg) do
15
+ @config.fetch(msg) { fail ArgumentError, "missing #{msg}"}
16
+ end
17
+ end
18
+
19
+ def url
20
+ return @config.fetch("test_url") if test_mode?
21
+ @config.fetch("url")
22
+ end
23
+
24
+ def merchant_id
25
+ return @config.fetch("test_mert_id") if test_mode?
26
+ @config.fetch("mert_id")
27
+ end
28
+
29
+ def merchant_key
30
+ return @config.fetch("test_mert_key") if test_mode?
31
+ @config.fetch("mert_key")
32
+ end
33
+
34
+ def platform
35
+ return "test".freeze if test_mode?
36
+ "service".freeze
37
+ end
38
+
39
+ def verify_peer?
40
+ verify_cert || verify_host
41
+ end
42
+
43
+ private
44
+
45
+ def test_mode?
46
+ @config.fetch("test_mode") { false }
47
+ end
48
+
49
+ def fetch_config
50
+ return {} unless File.exist?(@path)
51
+ YAML.load(ERB.new(File.read(@path)).result)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,39 @@
1
+ module Dacom
2
+ module Constants
3
+ extend self
4
+
5
+ def all
6
+ {
7
+ "lgd_user_agent" => "xpayclient (1.1.0.2/ruby)",
8
+ "lgd_log_fatal" => 0,
9
+ "lgd_log_error" => 1,
10
+ "lgd_log_warn" => 2,
11
+ "lgd_log_info" => 3,
12
+ "lgd_log_debug" => 4,
13
+ "lgd_err_no_home_dir" => "10001",
14
+ "lgd_err_no_mall_config" => "10002",
15
+ "lgd_err_no_lgdacom_config" => "10003",
16
+ "lgd_err_no_mid" => "10004",
17
+ "lgd_err_out_of_memory" => "10005",
18
+ "lgd_err_http_url" => "20001",
19
+ "lgd_err_resolve_host" => "20002",
20
+ "lgd_err_resolve_proxy" => "20003",
21
+ "lgd_err_connect" => "20004",
22
+ "lgd_err_write" => "20005",
23
+ "lgd_err_read" => "20006",
24
+ "lgd_err_send" => "20007",
25
+ "lgd_err_recv" => "20008",
26
+ "lgd_err_timedout" => "20009",
27
+ "lgd_err_ssl" => "20101",
28
+ "lgd_err_curl" => "20201",
29
+ "lgd_err_json_decode" => "40001"
30
+ }
31
+ end
32
+
33
+ def included(klass)
34
+ all.each do |k,v|
35
+ klass::const_set(k.upcase, v.freeze)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,25 @@
1
+ module Dacom
2
+ class Response
3
+ attr_reader :code, :message, :raw
4
+
5
+ SUCCESS_CODE = "0000".freeze
6
+
7
+ def initialize(data = {})
8
+ @code = data.fetch("LGD_RESPCODE") { data[:code] }
9
+ @message = data.fetch("LGD_RESPMSG") { data[:message] }
10
+ @raw = data.fetch("LGD_RESPONSE") { [] }
11
+ end
12
+
13
+ def data
14
+ @raw.first
15
+ end
16
+
17
+ def successful?
18
+ @code == SUCCESS_CODE
19
+ end
20
+
21
+ def to_s
22
+ %Q{<Dacom::Response:#{__id__}, code: "#{@code}", message: "#{@message}", successful: #{successful?}>}
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ module Dacom
2
+ VERSION = "1.0.0"
3
+ end
data/log/dacom.log ADDED
@@ -0,0 +1,2 @@
1
+ I, [2016-04-07T13:31:54.883968 #23521] INFO -- : request: https://xpayclient.lgdacom.net:7443/xpay/Gateway.do - {"LGD_TXID"=>"tlgdacomxpay-120160407113135592cebc48b96f77f16d43763d0bb23e1f3ab2f49", "LGD_AUTHCODE"=>"8e23c8ca9016286b7563b71f5771e80b7efdd081", "LGD_MID"=>"tlgdacomxpay"}
2
+ I, [2016-04-07T13:31:59.263917 #23521] INFO -- : response: <Dacom::Response:70217577404140, code: "XC01", message: "LGD_TXNAME 필드가 누락되었습니다.", successful: false>
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dacom
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - costajob
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-09-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.11'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.11'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rr
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description:
84
+ email:
85
+ - costajob@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".travis.yml"
92
+ - CODE_OF_CONDUCT.md
93
+ - Gemfile
94
+ - LICENSE.txt
95
+ - README.md
96
+ - Rakefile
97
+ - bin/console
98
+ - bin/setup
99
+ - config/dacom.yml
100
+ - dacom.gemspec
101
+ - lib/dacom.rb
102
+ - lib/dacom/client.rb
103
+ - lib/dacom/config.rb
104
+ - lib/dacom/constants.rb
105
+ - lib/dacom/response.rb
106
+ - lib/dacom/version.rb
107
+ - log/dacom.log
108
+ homepage: https://github.com/costajob/dacom
109
+ licenses:
110
+ - MIT
111
+ metadata: {}
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: 1.8.7
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubyforge_project:
128
+ rubygems_version: 2.5.1
129
+ signing_key:
130
+ specification_version: 4
131
+ summary: A Ruby port of the Dacom (LGU+) XPay client library
132
+ test_files: []