union-pay-ruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4037db1f24d696ebeccbfcf631c6773df3a05ea6
4
+ data.tar.gz: 1f83b46a4a570fd61e925ce0ecceb9dc7ff8a073
5
+ SHA512:
6
+ metadata.gz: 3161c7cb14f848716e35067feded3e14fe35b2fb6ee4addf677d450a46831955593a318a5a3720c4337572a9361a899cfaaca6b42d20a118e67bef6098dff3d1
7
+ data.tar.gz: 66829e9cb7d7956360496b586128e85e69727b451dc5852fcdc492a619b2e86ef98a3c62c12f7b3f889244dfc90b823c56b881859a2008ae8b5c68a3a5e35593
@@ -0,0 +1,24 @@
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
23
+
24
+ config/unionpay.yml
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in union-pay-ruby.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 mangege
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.
@@ -0,0 +1,29 @@
1
+ # Union::Pay::Ruby
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'union-pay-ruby'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install union-pay-ruby
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( https://github.com/[my-github-username]/union-pay-ruby/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create a new Pull Request
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new
5
+ task :default => :spec
@@ -0,0 +1 @@
1
+ require 'union-pay/up'
@@ -0,0 +1,10 @@
1
+ module UnionPay
2
+ module Core
3
+ autoload :Signer, 'union-pay/core/signer'
4
+ autoload :Config, 'union-pay/core/config'
5
+ autoload :Utils, 'union-pay/core/utils'
6
+ autoload :HttpClient, 'union-pay/core/http_client'
7
+ autoload :Response, 'union-pay/core/response'
8
+ autoload :Logger, 'union-pay/core/logger'
9
+ end
10
+ end
@@ -0,0 +1,32 @@
1
+ require 'erb'
2
+ require 'yaml'
3
+
4
+ module UnionPay
5
+ module Core
6
+ class Config
7
+ attr_reader :config
8
+ def initialize(config)
9
+ @config = config
10
+ end
11
+
12
+ def self.read_config_file(file_name)
13
+ erb = ERB.new(File.read(file_name))
14
+ erb.filename = file_name
15
+ YAML.load(erb.result)
16
+ end
17
+
18
+
19
+ def self.mobile_config(file_name, env='development')
20
+ config = read_config_file(file_name)['mobile'][env]
21
+ config = Utils.key_to_sym(config)
22
+ new(config)
23
+ end
24
+
25
+ %w[trade_url query_url merchant_id secret_key back_end_url front_end_url enable_log net_log_class].each do |att_name|
26
+ define_method(att_name.to_sym)do
27
+ @config[att_name.to_sym]
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,26 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+
4
+ module UnionPay
5
+ module Core
6
+ class HttpClient
7
+ include ::UnionPay::Core::Logger
8
+
9
+ def initialize(url, params, config)
10
+ @uri = URI(url)
11
+ @params = params
12
+ @config = config
13
+ end
14
+
15
+ def post
16
+ httpResp = Net::HTTP.post_form(@uri, @params)
17
+ net_log(@params, httpResp.body)
18
+ Response.new(httpResp.body, @config)
19
+ end
20
+
21
+ def self.post(url, params, config)
22
+ self.new(url, params, config).post
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ require 'logger'
2
+
3
+ module UnionPay
4
+ module Core
5
+ module Logger
6
+ def net_log(req, resp, notice=false)
7
+ return unless @config.enable_log
8
+ @net_log ||= Object.const_get(@config.net_log_class).new
9
+ @net_log.log(req, resp, notice)
10
+ end
11
+
12
+ class NetLog
13
+ def initialize
14
+ if defined?(Rails)
15
+ @logger = Rails.logger
16
+ else
17
+ @logger = ::Logger.new(STDOUT)
18
+ end
19
+ end
20
+
21
+ def log(req, resp, notice=false)
22
+ @logger.info("unionpay req: #{req.inspect} -- resp: #{resp.inspect} -- notice:#{notice.inspect}")
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,51 @@
1
+ require 'cgi'
2
+
3
+ module UnionPay
4
+ module Core
5
+ class Response
6
+ attr_reader :body
7
+
8
+ def initialize(resp, config)
9
+ if resp.is_a?(String)
10
+ @body = parse_query(resp)
11
+ else
12
+ @raw_body = ::UnionPay::Core::Utils.key_to_sym(resp)
13
+ @body = @raw_body.dup
14
+ decode_reserved!(@body)
15
+ end
16
+ @config = config
17
+ end
18
+
19
+ def success?
20
+ sign_valid? && @body[:respCode] == '00'
21
+ end
22
+
23
+ def sign_valid?
24
+ Signer.md5_sign(@raw_body, @config.secret_key) == @raw_body[:signature]
25
+ end
26
+
27
+ def [](key)
28
+ @body[key]
29
+ end
30
+
31
+ def inspect
32
+ @body.inspect
33
+ end
34
+
35
+ private
36
+ def parse_query(query_string)
37
+ h = CGI.parse(query_string)
38
+ @raw_body = Hash[h.collect{|k, v| v.size <= 1 ? [k.to_sym, v.first] : [k.to_sym, v]}]
39
+ h = @raw_body.dup
40
+ decode_reserved!(h)
41
+ h
42
+ end
43
+
44
+ def decode_reserved!(params)
45
+ params.each do |k, v|
46
+ params[k] = UnionPay::Core::Utils.decode_reserved(v) if k.to_s =~ /Reserved$/
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,22 @@
1
+ require 'digest/md5'
2
+
3
+ module UnionPay
4
+ module Core
5
+ class Signer
6
+ def self.md5_sign(params, secret_key)
7
+ params = Utils.key_to_sym(params)
8
+ params.delete(:signMethod)
9
+ params.delete(:signature)
10
+ str = params.sort.collect{|k, v| "#{k}=#{v}"}.join('&')
11
+ Digest::MD5.hexdigest("#{str}&#{Digest::MD5.hexdigest(secret_key)}")
12
+ end
13
+
14
+ def self.sign!(params, secret_key=nil)
15
+ params = params.delete_if{|k, v| v.nil? || (v.respond_to?(:empty?) && v.empty? )}
16
+ params[:signature] = self.md5_sign(params, secret_key)
17
+ params[:signMethod] = 'MD5'
18
+ params
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,30 @@
1
+ require 'uri'
2
+
3
+ module UnionPay
4
+ module Core
5
+ class Utils
6
+ class << self
7
+ def key_to_sym(kv)
8
+ kv.inject({}){|memo, (k,v)| memo[k.to_sym] = v; memo}
9
+ end
10
+
11
+ def check_hash_keys!(hash, *keys)
12
+ keys.flatten.each do |key|
13
+ raise ArgumentError.new("Unknown key: #{key.inspect}") unless hash.has_key?(key)
14
+ end
15
+ end
16
+
17
+ def encode_reserved(kv)
18
+ "{#{URI.encode_www_form(kv)}}"
19
+ end
20
+
21
+ def decode_reserved(str)
22
+ return str unless str.is_a?(String)
23
+ result = URI.decode_www_form(str[1..-2])
24
+ result = Hash[result]
25
+ key_to_sym(result)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,6 @@
1
+ module UnionPay
2
+ module Mobile
3
+ autoload :Client, 'union-pay/mobile/client'
4
+ autoload :TradeTypes, 'union-pay/mobile/trade_types'
5
+ end
6
+ end
@@ -0,0 +1,107 @@
1
+ require 'union-pay/core'
2
+
3
+ module UnionPay
4
+ module Mobile
5
+ class Client
6
+ include ::UnionPay::Core::Logger
7
+
8
+ attr_reader :config
9
+
10
+ # trade_url, query_url, merchant_id, back_end_url, front_end_url, secret_key
11
+ def initialize(config_or_file)
12
+ if config_or_file.is_a?(String)
13
+ @config = ::UnionPay::Core::Config.mobile_config(config_or_file)
14
+ else
15
+ @config = config_or_file
16
+ end
17
+ end
18
+
19
+ # 默认为人民币
20
+ # 金额填原始值就行, 比如100元,传100过来就行
21
+ def consume(other_params)
22
+ UnionPay::Core::Utils.check_hash_keys!(other_params, [:orderTime, :orderNumber, :orderAmount])
23
+
24
+ params = default_params
25
+ params = params.merge(other_params)
26
+ params = params.merge({
27
+ transType: '01',
28
+ orderTime: conver_time(other_params[:orderTime]),
29
+ orderAmount: conver_amount(other_params[:orderAmount])
30
+ })
31
+ trade(params)
32
+ end
33
+
34
+ def undo(other_params)
35
+ undo_and_refund(other_params.merge({transType: '31'}))
36
+ end
37
+
38
+ def refund(other_params)
39
+ undo_and_refund(other_params.merge({transType: '04'}))
40
+ end
41
+
42
+ def async_notice(params)
43
+ net_log(nil, params, true)
44
+ ::UnionPay::Core::Response.new(params, @config)
45
+ end
46
+
47
+ def query(other_params)
48
+ UnionPay::Core::Utils.check_hash_keys!(other_params, [:transType, :orderTime, :orderNumber])
49
+ params = default_params
50
+ params = params.merge(other_params)
51
+ params[:orderTime] = conver_time(other_params[:orderTime])
52
+ call_api(@config.query_url, params)
53
+ end
54
+
55
+ protected
56
+ def default_params
57
+ @_default_params ||= {
58
+ version: '1.0.0',
59
+ charset: 'UTF-8',
60
+ merId: @config.merchant_id,
61
+ backEndUrl: @config.back_end_url,
62
+ frontEndUrl: @config.front_end_url,
63
+ }
64
+ end
65
+
66
+ def trade(params)
67
+ call_api(@config.trade_url, params)
68
+ end
69
+
70
+ def call_api(path, params)
71
+ encode_reserved!(params)
72
+ ::UnionPay::Core::Signer.sign!(params, @config.secret_key)
73
+ ::UnionPay::Core::HttpClient.post(path, params, @config)
74
+ end
75
+
76
+ private
77
+ def undo_and_refund(other_params)
78
+ UnionPay::Core::Utils.check_hash_keys!(other_params, [:orderTime, :orderNumber, :qn, :orderAmount])
79
+ params = default_params
80
+ params = params.merge(other_params)
81
+ params = params.merge({
82
+ orderTime: conver_time(other_params[:orderTime]),
83
+ orderAmount: conver_amount(other_params[:orderAmount])
84
+ })
85
+ trade(params)
86
+ end
87
+
88
+ def conver_amount(amount)
89
+ (amount * 100).ceil
90
+ end
91
+
92
+ def conver_time(dt)
93
+ if dt.respond_to?(:strftime)
94
+ dt.strftime('%Y%m%d%H%M%S')
95
+ else
96
+ dt
97
+ end
98
+ end
99
+
100
+ def encode_reserved!(params)
101
+ params.each do |k, v|
102
+ params[k] = UnionPay::Core::Utils.encode_reserved(v) if k.to_s =~ /Reserved$/
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,5 @@
1
+ module UnionPay
2
+ autoload :VERSION, 'union-pay/version'
3
+ autoload :Core, 'union-pay/core'
4
+ autoload :Mobile, 'union-pay/mobile'
5
+ end
@@ -0,0 +1,3 @@
1
+ module UnionPay
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,19 @@
1
+ mobile:
2
+ m_default: &m_default
3
+ trade_url: 'http://202.101.25.178:8080/gateway/merchant/trade'
4
+ query_url: 'http://202.101.25.178:8080/gateway/merchant/query'
5
+ merchant_id: '880000000001633'
6
+ secret_key: 'GPi84MrogMoImegtOd0lmqEVLPGotgwR'
7
+ back_end_url: 'http://www.qq.com/back_end_url'
8
+ front_end_url: 'http://www.qq.com/front_end_url'
9
+ enable_log: false
10
+ net_log_class: UnionPay::Core::Logger::NetLog
11
+
12
+ development:
13
+ <<: *m_default
14
+
15
+ test:
16
+ <<: *m_default
17
+
18
+ production:
19
+ <<: *m_default
@@ -0,0 +1,19 @@
1
+ mobile:
2
+ m_default: &m_default
3
+ trade_url: 'http://222.66.233.198:8080/gateway/merchant/trade'
4
+ query_url: 'http://222.66.233.198:8080/gateway/merchant/query'
5
+ merchant_id: '880000000000000'
6
+ secret_key: '123456'
7
+ back_end_url: 'http://www.qq.com/back_end_url'
8
+ front_end_url: 'http://www.qq.com/front_end_url'
9
+ enable_log: false
10
+ net_log_class: UnionPay::Core::Logger::NetLog
11
+
12
+ development:
13
+ <<: *m_default
14
+
15
+ test:
16
+ <<: *m_default
17
+
18
+ production:
19
+ <<: *m_default
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe UnionPay::Core::Config do
4
+ it "读取文件" do
5
+ expect(UnionPay::Core::Config.read_config_file('spec/config/unionpay.yml')).to be_include('mobile')
6
+ end
7
+
8
+ it "mobile config" do
9
+ mc = UnionPay::Core::Config.mobile_config('spec/config/unionpay.yml')
10
+ expect(mc.trade_url).to be_true
11
+ end
12
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ include UnionPay::Core
4
+
5
+ describe Signer do
6
+ it "返回签名" do
7
+ params = {key1: 2, key3: 1, key2: 5}
8
+ expect(Signer.md5_sign(params, 'abc')).to eq('6ded5f60164343a7721eae2947d503c3')
9
+ end
10
+
11
+ it "signMethod和signature不参与签名" do
12
+ params = {key1: 2, key3: 1, key2: 5, signMethod: 'MD5', signature: '321'}
13
+ Signer.sign!(params, 'abc')
14
+ expect(params[:signature]).to eq('6ded5f60164343a7721eae2947d503c3')
15
+ end
16
+
17
+ it "value为空的不参与签名" do
18
+ params = {key1: 2, key3: 1, key2: 5, key4: '', key5: nil}
19
+ Signer.sign!(params, 'abc')
20
+ expect(params[:signature]).to eq('6ded5f60164343a7721eae2947d503c3')
21
+ end
22
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe UnionPay::Core::Utils do
4
+ it "encode_reserved" do
5
+ result = UnionPay::Core::Utils.encode_reserved({a: 1, b: '2='})
6
+ expect(result).to eq('{a=1&b=2%3D}')
7
+ end
8
+
9
+ it "decode_reserved" do
10
+ result = UnionPay::Core::Utils.decode_reserved('{a=1&b=2%3D}')
11
+ expect(result).to eq({a: '1', b: '2='})
12
+ end
13
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ include UnionPay::Mobile
4
+
5
+ describe Client do
6
+ before(:each) do
7
+ @client = Client.new('spec/config/unionpay.yml')
8
+ end
9
+
10
+ it "创建消费订单成功" do
11
+ params = {
12
+ orderTime: Time.now,
13
+ orderNumber: Time.now.to_i,
14
+ orderAmount: 100
15
+ }
16
+ resp = @client.consume(params)
17
+ expect(resp.success?).to be_true
18
+ end
19
+
20
+ it "消费订单的异步通知" do
21
+ msg = {"orderTime"=>"20140603120329", "settleDate"=>"0602", "orderNumber"=>"eb2a20002be770f948dbce6341f6c0ba40af9d9c", "exchangeRate"=>"0", "signature"=>"ea315b1cc406c2b2c6caa3cf49c60a5b", "settleCurrency"=>"156", "signMethod"=>"MD5", "transType"=>"01", "respCode"=>"00", "charset"=>"UTF-8", "sysReserved"=>"{traceTime=0603120329&acqCode=00215800&traceNumber=094215}", "version"=>"1.0.0", "settleAmount"=>"37800", "transStatus"=>"00", "merId"=>"880000000001633", "qn"=>"201406031203290942151"}
22
+ resp = @client.async_notice(msg)
23
+ expect(resp.success?).to be_true
24
+ end
25
+
26
+ it "透传信息应该原样返回" do
27
+ params = {
28
+ orderTime: Time.now,
29
+ orderNumber: Time.now.to_i,
30
+ orderAmount: 100,
31
+ reqReserved: {order_id: 1}
32
+ }
33
+ resp = @client.consume(params)
34
+ expect(resp[:reqReserved][:order_id]).to eq('1')
35
+ end
36
+
37
+ it "查询" do
38
+ params = {
39
+ orderTime: Time.now,
40
+ orderNumber: Time.now.to_i,
41
+ orderAmount: 100,
42
+ reqReserved: {order_id: 1}
43
+ }
44
+ @client.consume(params)
45
+
46
+ resp = @client.query({orderTime: params[:orderTime], orderNumber: params[:orderNumber], transType: '01'})
47
+ expect(resp[:respCode]).to be_true
48
+ end
49
+ end
@@ -0,0 +1,18 @@
1
+ require 'union-pay-ruby'
2
+ # This file was generated by the `rspec --init` command. Conventionally, all
3
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
4
+ # Require this file using `require "spec_helper"` to ensure that it is only
5
+ # loaded once.
6
+ #
7
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
8
+ RSpec.configure do |config|
9
+ config.treat_symbols_as_metadata_keys_with_true_values = true
10
+ config.run_all_when_everything_filtered = true
11
+ config.filter_run :focus
12
+
13
+ # Run specs in random order to surface order dependencies. If you find an
14
+ # order dependency and want to debug it, you can fix the order by providing
15
+ # the seed, which is printed after each run.
16
+ # --seed 1234
17
+ config.order = 'random'
18
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'union-pay/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "union-pay-ruby"
8
+ spec.version = UnionPay::VERSION
9
+ spec.authors = ["mangege"]
10
+ spec.email = ["mr.mangege@gmail.com"]
11
+ spec.summary = %q{UPOP and UPMP SDK}
12
+ spec.description = %q{UPOP and UPMP SDK}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: union-pay-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - mangege
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: UPOP and UPMP SDK
56
+ email:
57
+ - mr.mangege@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/union-pay-ruby.rb
68
+ - lib/union-pay/core.rb
69
+ - lib/union-pay/core/config.rb
70
+ - lib/union-pay/core/http_client.rb
71
+ - lib/union-pay/core/logger.rb
72
+ - lib/union-pay/core/response.rb
73
+ - lib/union-pay/core/signer.rb
74
+ - lib/union-pay/core/utils.rb
75
+ - lib/union-pay/mobile.rb
76
+ - lib/union-pay/mobile/client.rb
77
+ - lib/union-pay/up.rb
78
+ - lib/union-pay/version.rb
79
+ - spec/config/unionpay.yml
80
+ - spec/config/unionpay.yml.example
81
+ - spec/core/config_spec.rb
82
+ - spec/core/signer_spec.rb
83
+ - spec/core/utils_spec.rb
84
+ - spec/mobile/client_spec.rb
85
+ - spec/spec_helper.rb
86
+ - union-pay-ruby.gemspec
87
+ homepage: ''
88
+ licenses:
89
+ - MIT
90
+ metadata: {}
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 2.2.2
108
+ signing_key:
109
+ specification_version: 4
110
+ summary: UPOP and UPMP SDK
111
+ test_files:
112
+ - spec/config/unionpay.yml
113
+ - spec/config/unionpay.yml.example
114
+ - spec/core/config_spec.rb
115
+ - spec/core/signer_spec.rb
116
+ - spec/core/utils_spec.rb
117
+ - spec/mobile/client_spec.rb
118
+ - spec/spec_helper.rb