eport 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.
- data/README +0 -0
- data/lib/catalog_parser.rb +35 -0
- data/lib/eport.rb +67 -0
- data/lib/eport_request_plain_text.rb +52 -0
- data/lib/eport_result_plain_text.rb +47 -0
- data/lib/request.rb +41 -0
- metadata +67 -0
data/README
ADDED
File without changes
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class CatalogParser
|
2
|
+
attr_accessor :catalog
|
3
|
+
|
4
|
+
def initialize()
|
5
|
+
@catalog = { :v => [], :x => [], :e => [], :p => [] }
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
ITEM_SEPARATOR = "\r\n"
|
10
|
+
VALUE_SEPARATOR = "\t"
|
11
|
+
|
12
|
+
VALUES = {:x => [:version, :prev_version, :form_date, :money],
|
13
|
+
:v => [:id, :name],
|
14
|
+
:e => [:id, :provider_id, :name, :money_restriction, :price, :agent_max_value, :agent_value, :client_attributes, :client_attributes_regexp],
|
15
|
+
:p => [:body] }
|
16
|
+
|
17
|
+
|
18
|
+
def new_catalog(data)
|
19
|
+
ic = Iconv.new('UTF-8', 'WINDOWS-1251')
|
20
|
+
|
21
|
+
strings = data.split(ITEM_SEPARATOR)
|
22
|
+
strings[1..-1].each do |string|
|
23
|
+
values = string.split(VALUE_SEPARATOR)
|
24
|
+
type = ic.iconv(values[0])
|
25
|
+
key = type[1].to_sym
|
26
|
+
|
27
|
+
if ["+v", "+x", "+e", "+p"].include?(type)
|
28
|
+
hash = {}
|
29
|
+
VALUES[key].each_index{|index| hash[VALUES[key][index]] = ic.iconv(values[index+1]).to_s}
|
30
|
+
@catalog[key] << hash
|
31
|
+
end
|
32
|
+
end
|
33
|
+
@catalog
|
34
|
+
end
|
35
|
+
end
|
data/lib/eport.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require "iconv"
|
2
|
+
require "yaml"
|
3
|
+
|
4
|
+
class Eport
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
config_file = File.join(RAILS_ROOT, 'config', 'eport.yml')
|
8
|
+
@config = YAML.load(IO.read(config_file))
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_catalog
|
12
|
+
req = Request.new do |r|
|
13
|
+
r.point = @config[:eport][:point]
|
14
|
+
r.private_key_path = "#{RAILS_ROOT}/#{@config[:eport][:private_key_path]}"
|
15
|
+
|
16
|
+
r.host = @config[:eport][:host]
|
17
|
+
r.path = "/cp/dir"
|
18
|
+
r.body = ""
|
19
|
+
end
|
20
|
+
data = req.confirm
|
21
|
+
cp = CatalogParser.new
|
22
|
+
cp.new_catalog(data)
|
23
|
+
end
|
24
|
+
|
25
|
+
def do_refill_operation(operation_id, product_id, value, account)
|
26
|
+
req = Request.new do |r|
|
27
|
+
r.point = @config[:eport][:point]
|
28
|
+
r.private_key_path = "#{RAILS_ROOT}/#{@config[:eport][:private_key_path]}"
|
29
|
+
|
30
|
+
r.host = @config[:eport][:host]
|
31
|
+
r.path = "/cp/fe"
|
32
|
+
|
33
|
+
req = EportRequestPlainText.new
|
34
|
+
req.operation_type = "OPERATION"
|
35
|
+
req.operation_id = operation_id
|
36
|
+
req.product_id = product_id
|
37
|
+
req.value = value
|
38
|
+
req.account = account
|
39
|
+
r.body = req.body
|
40
|
+
end
|
41
|
+
ic = Iconv.new('UTF-8', 'WINDOWS-1251')
|
42
|
+
ic.iconv(req.confirm)
|
43
|
+
end
|
44
|
+
|
45
|
+
def confirm_refill_operation(operation_id, product_id, value, account)
|
46
|
+
req = Request.new do |r|
|
47
|
+
r.point = @config[:eport][:point]
|
48
|
+
r.private_key_path = "#{RAILS_ROOT}/#{@config[:eport][:private_key_path]}"
|
49
|
+
|
50
|
+
r.host = @config[:eport][:host]
|
51
|
+
r.path = "/cp/fe"
|
52
|
+
|
53
|
+
req = EportRequestPlainText.new
|
54
|
+
req.operation_type = "CONFIRM"
|
55
|
+
req.operation_id = operation_id
|
56
|
+
req.product_id = product_id
|
57
|
+
req.value = value
|
58
|
+
req.account = account
|
59
|
+
|
60
|
+
r.body = req.body
|
61
|
+
end
|
62
|
+
ic = Iconv.new('UTF-8', 'WINDOWS-1251')
|
63
|
+
ic.iconv(req.confirm)
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
class EportRequestPlainText
|
2
|
+
OPERATION_TYPES = [
|
3
|
+
"CHECK",
|
4
|
+
"OPERATION",
|
5
|
+
"CONFIRM",
|
6
|
+
"CANCEL"
|
7
|
+
]
|
8
|
+
|
9
|
+
STRING_SEPARATOR = "\r\n"
|
10
|
+
|
11
|
+
attr_accessor :operation_type, :operation_id, :product_id, :value, :account
|
12
|
+
|
13
|
+
def operation_type=(value)
|
14
|
+
if OPERATION_TYPES.include?(value.upcase)
|
15
|
+
@operation_type = value
|
16
|
+
else
|
17
|
+
raise ArgumentError, "Not supported operation type \"#{value}\""
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(&block)
|
22
|
+
@operation_type = nil
|
23
|
+
@operation_id = nil
|
24
|
+
@product_id = nil
|
25
|
+
@value = nil
|
26
|
+
@account = nil
|
27
|
+
|
28
|
+
if block
|
29
|
+
block.call
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def body
|
34
|
+
output = ""
|
35
|
+
output << @operation_type + STRING_SEPARATOR
|
36
|
+
output << key_value("id", @operation_id)
|
37
|
+
output << key_value("checkid", @operation_id)
|
38
|
+
output << key_value("product", @product_id)
|
39
|
+
output << key_value("value", @value)
|
40
|
+
output << key_value("account", @account)
|
41
|
+
output
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
def key_value(key, value)
|
46
|
+
"#{key}=#{value}#{STRING_SEPARATOR}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
#req = EportRequestPlainText.new
|
51
|
+
#req.operation_type = "OPERATION"
|
52
|
+
#puts req.body
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "iconv"
|
2
|
+
|
3
|
+
class EportResultPlainText
|
4
|
+
STRING_SEPARATOR = "\r\n"
|
5
|
+
|
6
|
+
KEY_VALUE_SEPARATOR = "="
|
7
|
+
|
8
|
+
attr_reader :code, :omsg, :cmsg, :pmsg, :card, :pin
|
9
|
+
|
10
|
+
def initialize(body = nil)
|
11
|
+
@code = nil
|
12
|
+
@omsg = nil
|
13
|
+
@cmsg = nil
|
14
|
+
@pmsg = nil
|
15
|
+
@card = nil
|
16
|
+
@pin = nil
|
17
|
+
|
18
|
+
unless body.nil?
|
19
|
+
parse(body)
|
20
|
+
else
|
21
|
+
raise ArgumentError, "Parameter named \"body\" must be not nil"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
def parse(body)
|
27
|
+
strings = body.strip.split(STRING_SEPARATOR)
|
28
|
+
strings[1..-1].each do |string|
|
29
|
+
key, value = string.split(KEY_VALUE_SEPARATOR)
|
30
|
+
case key
|
31
|
+
when "code"
|
32
|
+
@code = value
|
33
|
+
when "omsg"
|
34
|
+
@omsg = value
|
35
|
+
when "cmsg"
|
36
|
+
ic = Iconv.new('UTF-8', 'WINDOWS-1251')
|
37
|
+
@cmsg = ic.iconv(value)
|
38
|
+
when "pmsg"
|
39
|
+
@pmsg = value
|
40
|
+
when "card"
|
41
|
+
@card = value
|
42
|
+
when "pin"
|
43
|
+
@pin = value
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/request.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require "net/https"
|
3
|
+
|
4
|
+
|
5
|
+
class Request
|
6
|
+
attr_accessor :point, :private_key_path, :host, :path, :additional_headers, :body
|
7
|
+
|
8
|
+
def initialize(&block)
|
9
|
+
block.yield(self)
|
10
|
+
|
11
|
+
@headers = {
|
12
|
+
"Content-Type" => "text/plain; charset=Windows-1251",
|
13
|
+
"Content-Length" => @body.size.to_s,
|
14
|
+
"X-Eport-Auth" => "point=#{@point}; sign=\"#{signature(@body)}\"; encoding=\"hex\""
|
15
|
+
}.merge(additional_headers || {})
|
16
|
+
end
|
17
|
+
|
18
|
+
def confirm
|
19
|
+
http = Net::HTTP.new(@host, 443)
|
20
|
+
http.use_ssl = true
|
21
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
22
|
+
puts @headers.inspect
|
23
|
+
resp, data = http.post(@path, @body, @headers)
|
24
|
+
data
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def signature(text = nil, kind = "hex")
|
30
|
+
if text.nil?
|
31
|
+
raise ArgumentError, "Parameter named \"body\" must be not nil"
|
32
|
+
end
|
33
|
+
|
34
|
+
if @private_key_path.nil? || @private_key_path.empty?
|
35
|
+
raise ArgumentError, "No private key provided"
|
36
|
+
end
|
37
|
+
|
38
|
+
signature = `echo -n '#{text}' | openssl dgst -md5 -sign #{@private_key_path} -hex`.strip
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: eport
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Alexander Lomakin, Dmitry Andreev
|
13
|
+
autorequire: eport
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-04-27 00:00:00 +04:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description:
|
22
|
+
email: d.g.andreev@gmail.com
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files:
|
28
|
+
- README
|
29
|
+
files:
|
30
|
+
- lib/catalog_parser.rb
|
31
|
+
- lib/eport.rb
|
32
|
+
- lib/eport_request_plain_text.rb
|
33
|
+
- lib/eport_result_plain_text.rb
|
34
|
+
- lib/request.rb
|
35
|
+
- README
|
36
|
+
has_rdoc: true
|
37
|
+
homepage: ""
|
38
|
+
licenses: []
|
39
|
+
|
40
|
+
post_install_message:
|
41
|
+
rdoc_options: []
|
42
|
+
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
segments:
|
50
|
+
- 0
|
51
|
+
version: "0"
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
segments:
|
57
|
+
- 0
|
58
|
+
version: "0"
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
rubyforge_project:
|
62
|
+
rubygems_version: 1.3.6
|
63
|
+
signing_key:
|
64
|
+
specification_version: 3
|
65
|
+
summary: e-port.ru
|
66
|
+
test_files: []
|
67
|
+
|