rubyplat 0.1.5

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
+ SHA256:
3
+ metadata.gz: 1c853ff96312da19bae67a827ac343ad139e4a895dbbd7af191932d7522c5ee6
4
+ data.tar.gz: 624b0d170470384c14b76f514daa7f3ef05cfedc6ffcf8829e2ff5845a411efa
5
+ SHA512:
6
+ metadata.gz: 9ef074e4634b521deb146d389a74eb70c2afd04cfb8472344699e2d156a325f6ac429baa58115b5ae4b0f26e8e1e3dc5a6c561684eaec967aef08409056afac4
7
+ data.tar.gz: 9ef1e382bb458c5c98efbbb53b89c231962a94d5c765381702a4160db30095d0a6863843a73a0f97f6eec1ac92c7a0d25f755fc8242ad32358510236f29cb32b
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.5.1
5
+ before_install: gem install bundler -v 1.16.1
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in rubyplat.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,32 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rubyplat (0.1.5)
5
+ cyberplat_pki_patched (~> 1.0, >= 1.0.1)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ coderay (1.1.2)
11
+ cyberplat_pki_patched (1.0.1)
12
+ ffi
13
+ ffi (1.9.23)
14
+ method_source (0.9.0)
15
+ minitest (5.11.3)
16
+ pry (0.11.3)
17
+ coderay (~> 1.1.0)
18
+ method_source (~> 0.9.0)
19
+ rake (10.5.0)
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ bundler (~> 1.16)
26
+ minitest (~> 5.0)
27
+ pry
28
+ rake (~> 10.0)
29
+ rubyplat!
30
+
31
+ BUNDLED WITH
32
+ 1.16.1
data/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # Rubyplat
2
+ Wrapper for cyberplat payment provider. Uses FFI to call Cyberpat Ipriv library for signing requests.
3
+
4
+ ## Installation
5
+
6
+ Add this line to your application's Gemfile:
7
+
8
+ ```ruby
9
+ gem 'rubyplat'
10
+ ```
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install rubyplat
19
+
20
+ ## Usage
21
+
22
+ ### Confiuration
23
+
24
+ In your initializer configure keys for signing and verifying requests
25
+
26
+ ```ruby
27
+ Rubyplat.configure do |config|
28
+ config.secret_key = '/path/to_key'
29
+ config.public_key = '/path/to_key'
30
+ config.secret_passphrase = 'secret'
31
+ config.public_passphrase = 123123
32
+ end
33
+ ```
34
+
35
+ Perform request
36
+
37
+ ```
38
+ client = Rubyplat::Client.new
39
+
40
+ params = {
41
+ sender: '123123',
42
+ receiver: '123123',
43
+ operator: '123123',
44
+ accept_keys: 123123,
45
+ date: Date.today,
46
+ session: SecureRandom.hex[0..20],
47
+ number: '12312312312',
48
+ amount: '300.30',
49
+ pay_tool: :foreign_card
50
+ }
51
+
52
+ client.pay_check(pay_params, 'https://ru-demo.cyberplat.com/cgi-bin/test_gate/utest_pay.cgi/es/es_pay.cgi')
53
+ # => #<Rubyplat::Responses::PaymentPermissionResponse:0x000
54
+ client.pay(pay_params, 'https://ru-demo.cyberplat.com/cgi-bin/test_gate/utest_pay.cgi/es/es_pay.cgi')
55
+ # => #<Rubyplat::Responses::PaymentResponse:0x000
56
+ ```
57
+
58
+ ## Development
59
+
60
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
61
+
62
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
63
+
64
+ ## Contributing
65
+
66
+ Bug reports and pull requests are welcome on GitHub at https://github.com/creepycheese/rubyplat.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "rubyplat"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ require "pry"
11
+ Pry.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
@@ -0,0 +1,77 @@
1
+ module Rubyplat
2
+ class Client
3
+ InvalidSignature = Class.new(StandardError)
4
+
5
+ # @param key [CyberplatPKI::Key] cyberplat secret key to sign request
6
+ # @param pubkey [CyberplatPKI::Key] cyberplat pubkey to verify request
7
+ def initialize(key=Rubyplat.config.key, pubkey=Rubyplat.config.pubkey)
8
+ @key, @pubkey = key, pubkey
9
+ end
10
+
11
+ # @param params [Hash] arguments to create request
12
+ # @option params [String] :sender sender of request
13
+ # @option params [String] :receiver request receiver
14
+ # @option params [String] :operator operator
15
+ # @option params [String] :date request date
16
+ # @option params [String] :session uniq session identifier non longer than 20
17
+ # @option params [String] :number phone number or payer's account number(can be blank)
18
+ # @option params [String] :account payer's identifier or payees service identifier. Can be blank.
19
+ # @option params [Float] :amount amount to be payed. example: 1234.12
20
+ # @param vendor_or_uri [String, Rubyplat::Gateways::Gateway] string or gateway for cyberplat
21
+ # @return [Rubyplat::Responses::PaymentPermissionResponse] response
22
+ # @return [Net::HTTPBadRequest] instance of bad request
23
+ # @raise [Rubyplat::Client::InvalidSignature] if the response signature is invalid
24
+ # raises error
25
+ def pay_check(params = {}, vendor_or_uri)
26
+ uri = vendor_or_uri.kind_of?(String) ? URI(vendor_or_uri) : vendor_or_uri.pay_check_uri
27
+ request = Rubyplat::Requests::PaymentPermission.new(params)
28
+ response = send_request(request, uri)
29
+
30
+ read_response(response, Rubyplat::Responses::PaymentPermissionResponse)
31
+ end
32
+
33
+ def pay(params = {}, vendor_or_uri)
34
+ uri = vendor_or_uri.kind_of?(String) ? URI(vendor_or_uri) : vendor_or_uri.pay_check_uri
35
+ request = Rubyplat::Requests::PaymentRequest.new(params)
36
+ response = send_request(request, uri)
37
+
38
+ read_response(response, Rubyplat::Responses::PaymentResponse)
39
+ end
40
+
41
+ def pay_status(params = {}, vendor_or_uri)
42
+ uri = vendor_or_uri.kind_of?(String) ? URI(vendor_or_uri) : vendor_or_uri.pay_check_uri
43
+ request = Rubyplat::Requests::PaymentStatus.new(params)
44
+ response = send_request(request, uri)
45
+
46
+ read_response(response, Rubyplat::Responses::PaymentStatusResponse)
47
+ end
48
+
49
+ private
50
+
51
+ attr_reader :pubkey, :key
52
+
53
+ def read_response(response, response_klass)
54
+ if response.code == '200'
55
+ raise InvalidSignature unless pubkey.verify(response.body)
56
+
57
+ response_klass.from_response_string(response.body)
58
+ else
59
+ response
60
+ end
61
+ end
62
+
63
+ # sends signed request and returns parsed cyberplat response
64
+ # request [#body] cyberplat request to be signed and sent
65
+ def send_request(request, uri)
66
+ signed_request_body = Rubyplat::SignedRequest.new(request).sign(key)
67
+
68
+ http = Net::HTTP.new(uri.host, uri.port)
69
+ http.use_ssl = true
70
+ header = { 'Content-Type': 'application/x-www-form-urlencoded' }
71
+ request = Net::HTTP::Post.new(uri.request_uri, header)
72
+ request.body = signed_request_body
73
+
74
+ response = http.request(request)
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,30 @@
1
+ module Rubyplat
2
+ # @attr_reader [String] secret_key secret key for signing requests
3
+ # @attr_reader [String] public_key public key for verifying requests
4
+ class Configuration
5
+ attr_reader :secret_key, :public_key
6
+ attr_accessor :secret_passphrase, :public_passphrase
7
+
8
+ # @param key_path [String] path to secret key
9
+ def secret_key=(key_path)
10
+ @secret_key = File.read(key_path)
11
+ end
12
+
13
+ # @param key_path [String] path to public key
14
+ def public_key=(key_path)
15
+ @public_key = File.read(key_path)
16
+ end
17
+
18
+ # secret key used for signing requests
19
+ # @return [CyberplatPKI::Key] an instance of key
20
+ def key
21
+ @key ||= CyberplatPKI::Key.new_private(secret_key, secret_passphrase)
22
+ end
23
+
24
+ # public key used for verifying requests
25
+ # @return [CyberplatPKI::Key] an instance of key
26
+ def pubkey
27
+ @pubkey ||= CyberplatPKI::Key.new_public(public_key, public_passphrase)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,29 @@
1
+ module Rubyplat
2
+ module Gateways
3
+ # Represents payment gateway for performing operations
4
+ #
5
+ class Gateway
6
+ def self.available
7
+ @available ||= [
8
+ ::Rubyplat::Gateways::Gateway.new(
9
+ 'Тройка (Московский Метрополитен и Мосгортранс)',
10
+ 3589,
11
+ 'https://service.cyberplat.ru/cgi-bin/tc/tc_pay_check.cgi/3589',
12
+ 'https://service.cyberplat.ru/cgi-bin/tc/tc_pay.cgi/3589',
13
+ 'https://service.cyberplat.ru/cgi-bin/tc/tc_pay_status.cgi'
14
+ )
15
+ ]
16
+ end
17
+
18
+ attr_reader :name, :number, :pay_check_uri, :pay_status_uri, :pay_uri
19
+
20
+ def initialize(name, number, pay_check_uri, pay_uri, pay_status_uri)
21
+ @name = name
22
+ @number = number
23
+ @pay_check_uri = URI(pay_check_uri)
24
+ @pay_uri = URI(pay_uri)
25
+ @pay_status_uri = URI(pay_status_uri)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,37 @@
1
+ module Rubyplat
2
+ module Requests
3
+ class CheckBalance
4
+
5
+ # @param [Hash] params arguments to create request
6
+ # @option [Integer] params :sender code for counterparty - sender
7
+ # @option [Integer] params :receiver code for receiver
8
+ # @option [Integer] params :operator receiver-operator
9
+ # @option [String] params :session session
10
+ # @option [String] params :accept_keys receiver-operator
11
+ #
12
+ def initialize(params = {})
13
+ @sender = params[:sender]
14
+ @receiver = params[:receiver]
15
+ @operator = params[:operator]
16
+ @accept_keys = params[:accept_keys]
17
+ @session = params[:session]
18
+ end
19
+
20
+ def body
21
+ body_parameters.compact.join("\r\n").encode(Encoding::WINDOWS_1251)
22
+ end
23
+
24
+ private
25
+
26
+ def body_parameters
27
+ [
28
+ "SD=#{@sender}",
29
+ "AP=#{@receiver}",
30
+ "OP=#{@operator}",
31
+ "SESSION=#{@session}",
32
+ "ACCEPT_KEYS=#{@accept_keys}"
33
+ ]
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,89 @@
1
+ module Rubyplat
2
+ module Requests
3
+ class PaymentPermission
4
+ InvalidPaytool = Class.new(StandardError)
5
+
6
+ # @param params [Hash] arguments to create request
7
+ # @option params [String] :sender sender of request
8
+ # @option params [String] :receiver request receiver
9
+ # @option params [String] :operator operator
10
+ # @option params [String] :date request date
11
+ # @option params [String] :session session
12
+ # @option params [String] :number phone number or payer's account number(can be blank)
13
+ # @option params [String] :account payer's identifier or payees service identifier. Can be blank.
14
+ # @option params [Float] :req_type if 1 -- simply check number without payment
15
+ # @option params [Float] :amount amount to be payed. example: 1234.12
16
+ # @option params [String] :term_id actual sender code(Only for MTS and Beeline)
17
+ # @option params [Bool] :no_route auto redirect sign
18
+ #
19
+ def initialize(params = {})
20
+ params = defaults.merge(params)
21
+
22
+ @sender = params[:sender]
23
+ @receiver = params[:receiver]
24
+ @operator = params[:operator]
25
+ @date = DateTime.parse((params[:date] || Time.now).to_s).strftime('%Y.%m.%d %H:%M:%S')
26
+ @session = params[:session]
27
+ @number = params[:number]
28
+ @account = params[:account]
29
+ @amount = params[:amount]
30
+ @req_type = params[:req_type]
31
+ @pay_tool = Rubyplat::PAYTOOL.fetch(params[:pay_tool]) { raise InvalidPaytool.new("Paytool может принимать значения #{PAYTOOL.keys}") }
32
+ @term_id = params[:term_id]
33
+ @comment = params[:comment]
34
+ @accept_keys = params[:accept_keys]
35
+ @no_route = params[:no_route]
36
+ @amount_all = params[:amount_all]
37
+ end
38
+
39
+ # @return [String] String representation of request
40
+ # @example
41
+ # @check_request = Rubyplat::Requests::Check.new(
42
+ # sender: 'sender',
43
+ # receiver: 'receiver',
44
+ # operator: 'operator',
45
+ # date: Time.now,
46
+ # session: 'sess',
47
+ # account: 'account',
48
+ # amount: 1234.42,
49
+ # req_type: false,
50
+ # term_id: '12345',
51
+ # comment: 'FooBar',
52
+ # accept_keys: '12345',
53
+ # pay_tool: :cash,
54
+ # no_route: true)
55
+ #
56
+ # @check_request.body
57
+ # #=> "SD=sender\r\nAP=receiver\r\nOP=operator\r\nDATE=2018.04.27 17:08:49\r\nSESSION=sess\r\nACCOUNT=account\r\nAMOUNT=1234.42\r\nREQ_TYPE=0\r\nPAY_TOOL=0\r\nTERM_ID=12345\r\nCOMMENT=FooBar\r\nACCEPT_KEYS=12345\r\nNO_ROUTE=1"
58
+ def body
59
+ body_parameters.compact.join("\r\n").encode(Encoding::WINDOWS_1251)
60
+ end
61
+
62
+ private
63
+
64
+ def defaults
65
+ { pay_tool: 0, no_route: false }
66
+ end
67
+
68
+ def body_parameters
69
+ [
70
+ "SD=#{@sender}",
71
+ "AP=#{@receiver}",
72
+ "OP=#{@operator}",
73
+ "DATE=#{@date}",
74
+ "SESSION=#{@session}",
75
+ @number && "NUMBER=#{@number}",
76
+ "ACCOUNT=#{@account}",
77
+ "AMOUNT=#{@amount}",
78
+ "REQ_TYPE=#{@req_type ? 1 : 0}",
79
+ "PAY_TOOL=#{@pay_tool}",
80
+ @term_id && "TERM_ID=#{@term_id}",
81
+ "COMMENT=#{@comment}",
82
+ "ACCEPT_KEYS=#{@accept_keys}",
83
+ "NO_ROUTE=#{@no_route ? 1 : 0}",
84
+ "AMOUNT_ALL=#{@amount_all}"
85
+ ]
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,74 @@
1
+ module Rubyplat
2
+ module Requests
3
+ class PaymentRequest
4
+
5
+ # @param params [Hash] arguments to create request
6
+ # @option params [String] :sender sender of request
7
+ # @option params [String] :receiver request receiver
8
+ # @option params [String] :operator operator
9
+ # @option params [String] :session session
10
+ # @option params [String] :number phone number or payer's account number(can be blank)
11
+ # @option params [String] :account payer's identifier or payees service identifier. Can be blank.
12
+ # @option params [Float] :amount amount to be payed. example: 1234.12
13
+ # @option params [Float] :amount_all amount to be charged. example: 1234.12
14
+ # @option params [Date] :date request date
15
+ # @option params [Float] :req_type amount to be payed. example: 1234.12
16
+ # @option params [Symbol] :pay_tool payment method [:cash, :local_card, :foreign_card]
17
+ # @option params [String] :term_id actual sender code(Only for MTS and Beeline)
18
+ # @option params [String] :comment payment comment
19
+ # @option params [String] :rrn uniq payment identifier
20
+ # @option params [String] :accept_keys serial number of key to sign request
21
+ # @option params [Bool] :no_route auto redirect sign
22
+ #
23
+ def initialize(params = {})
24
+ params = defaults.merge(params)
25
+
26
+ @sender = params[:sender]
27
+ @receiver = params[:receiver]
28
+ @operator = params[:operator]
29
+ @date = DateTime.parse((params[:date] || Time.now).to_s).strftime('%Y.%m.%d %H:%M:%S')
30
+ @session = params[:session]
31
+ @number = params[:number]
32
+ @account = params[:account]
33
+ @amount = params[:amount]
34
+ @pay_tool = Rubyplat::PAYTOOL.fetch(params[:paytool]) { nil }
35
+ @term_id = params[:term_id]
36
+ @comment = params[:comment]
37
+ @accept_keys = params[:accept_keys]
38
+ @no_route = params[:no_route]
39
+ @amount_all = params[:amount_all]
40
+ @rrn = params[:rrn]
41
+ end
42
+
43
+ def body
44
+ body_parameters.compact.join("\r\n").encode(Encoding::WINDOWS_1251)
45
+ end
46
+
47
+ private
48
+
49
+ def defaults
50
+ { pay_tool: 0, no_route: false }
51
+ end
52
+
53
+ def body_parameters
54
+ [
55
+ "SD=#{@sender}",
56
+ "AP=#{@receiver}",
57
+ "OP=#{@operator}",
58
+ "DATE=#{@date}",
59
+ "SESSION=#{@session}",
60
+ @number && "NUMBER=#{@number}",
61
+ "ACCOUNT=#{@account}",
62
+ "AMOUNT=#{@amount}",
63
+ "PAY_TOOL=#{@pay_tool}",
64
+ "TERM_ID=#{@term_id}",
65
+ "COMMENT=#{@comment}",
66
+ "ACCEPT_KEYS=#{@accept_keys}",
67
+ "NO_ROUTE=#{@no_route ? 1 : 0}",
68
+ "RRN=#{@rrn}",
69
+ "AMOUNT_ALL=#{@amount_all}"
70
+ ]
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,31 @@
1
+ module Rubyplat
2
+ module Requests
3
+ class PaymentStatus
4
+
5
+ # @param [Hash] params arguments to create request
6
+ # @option [String] params :session 1-20 symbols session identifier
7
+ # @option [String] params :transid 13-digits payment identifier for Cyberplat(not required)
8
+ # @option [String] params :accept_keys serial key number
9
+ #
10
+ def initialize(params = {})
11
+ @session = params[:session]
12
+ @transid = params[:transid]
13
+ @accept_keys = params[:accept_keys]
14
+ end
15
+
16
+ def body
17
+ body_parameters.compact.join("\r\n").encode(Encoding::WINDOWS_1251)
18
+ end
19
+
20
+ private
21
+
22
+ def body_parameters
23
+ [
24
+ "SESSION=#{@session}",
25
+ @transid && "TRANSID=#{@transid}",
26
+ "ACCEPT_KEYS=#{@accept_keys}"
27
+ ]
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,40 @@
1
+ module Rubyplat
2
+ module Requests
3
+ class RefillInfo
4
+
5
+ # @param [Hash] params arguments to create request
6
+ # @option [Integer] params :sender code for counterparty - sender
7
+ # @option [Integer] params :receiver code for receiver
8
+ # @option [Integer] params :operator receiver-operator
9
+ # @option [String] params :session session
10
+ # @option [String] params :accept_keys receiver-operator
11
+ # @option [String] params :on_date date refills requested on
12
+ #
13
+ def initialize(params = {})
14
+ @sender = params[:sender]
15
+ @receiver = params[:receiver]
16
+ @operator = params[:operator]
17
+ @accept_keys = params[:accept_keys]
18
+ @session = params[:session]
19
+ @on_date = DateTime.parse(params[:on_date].to_s).strftime('%Y%m%d')
20
+ end
21
+
22
+ def body
23
+ body_parameters.compact.join("\r\n").encode(Encoding::WINDOWS_1251)
24
+ end
25
+
26
+ private
27
+
28
+ def body_parameters
29
+ [
30
+ "SD=#{@sender}",
31
+ "AP=#{@receiver}",
32
+ "OP=#{@operator}",
33
+ "SESSION=#{@session}",
34
+ "ACCEPT_KEYS=#{@accept_keys}",
35
+ "ON_DATE=#{@on_date}"
36
+ ]
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,36 @@
1
+ module Rubyplat
2
+ module Responses
3
+ class CheckBalanceResponse < Response
4
+
5
+ def success?
6
+ error.to_i == 0
7
+ end
8
+
9
+ # REST field
10
+ # @return [Float] available amount for client
11
+ def rest_limit
12
+ Float(@rest)
13
+ end
14
+
15
+ # current amount of available funds for client.
16
+ # @return [Float] REST_WO_LIMIT
17
+ def available_limit
18
+ Float(@rest_wo_limit)
19
+ end
20
+
21
+ # amount of daily available funds
22
+ # @return [Float] AP_DAILY_LIMIT if set
23
+ # @return [nil] if not set
24
+ def daily_limit
25
+ @ap_daily_limit && Float(@ap_daily_limit)
26
+ end
27
+
28
+ # maximum amount be paid with single payment
29
+ # @return [Float] AP_DAILY_LIMIT if set
30
+ # @return [nil] if not set
31
+ def max_payment_limit
32
+ @ap_payment_limit && Float(@ap_payment_limit)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,10 @@
1
+ module Rubyplat
2
+ module Responses
3
+ class PaymentPermissionResponse < Response
4
+
5
+ def success?
6
+ result.to_i == 0 && error.to_i == 0
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module Rubyplat
2
+ module Responses
3
+ class PaymentResponse < Response
4
+ def success?
5
+ result.to_i == 0 && error.to_i == 0
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,31 @@
1
+ module Rubyplat
2
+ module Responses
3
+ class PaymentStatusResponse < Response
4
+ STATES = {
5
+ 1 => "payment_permission_sent",
6
+ 3 => "processing",
7
+ 7 => "completed"
8
+ }
9
+
10
+ def state
11
+ STATES[result.to_i]
12
+ end
13
+
14
+ def processing?
15
+ state == 'processing'
16
+ end
17
+
18
+ def payment_permission_sent?
19
+ state == 'payment_permission_sent'
20
+ end
21
+
22
+ def completed?
23
+ state == 'completed'
24
+ end
25
+
26
+ def success?
27
+ result.to_i == 7 && error.to_i == 0
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,15 @@
1
+ module Rubyplat
2
+ module Responses
3
+ class RefillInfoResponse < Response
4
+ def success?
5
+ result.to_i == 0 && error.to_i == 0
6
+ end
7
+
8
+ # UTF-8 representation of DATA field
9
+ # @return [String] refills info def decoded_data
10
+ def decoded_data
11
+ URI.unescape(@data).encode('UTF-8', 'Windows-1251')
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ module Rubyplat
2
+ module Responses
3
+ class Response
4
+ extend Rubyplat::Utils::Parser
5
+
6
+ def self.from_response_string(response)
7
+ new(parse(response))
8
+ end
9
+
10
+ # @param params [Hash] hash of params
11
+ def initialize(params = {})
12
+ @date = DateTime.parse(params.delete(:date)) if params[:date]
13
+
14
+ params.each do |k,v|
15
+ instance_variable_set("@#{k}", v)
16
+ self.class.class_eval { attr_reader k }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ module Rubyplat
2
+ class SignedRequest
3
+ # @param request [#body] request to be signed with Cyberplat Key
4
+ def initialize(request)
5
+ @request = request
6
+ end
7
+
8
+ # @param key [CyberplatPKI::Key] secret key to sign request
9
+ # @return [String] signed request body
10
+ def sign(key)
11
+ msg = 'inputmessage='
12
+ msg << URI.encode(key.sign(request.body).encode(Encoding::WINDOWS_1251))
13
+ msg
14
+ end
15
+
16
+ private
17
+
18
+ attr_reader :request
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ module Rubyplat
2
+ module Utils
3
+ module Parser
4
+
5
+ # @param response_body [String] response from cyberplat api
6
+ # @return [Hash] hash of key value hashes
7
+ def parse(response_body)
8
+ regex = /BEGIN\r\n(.*)END\r\n/m
9
+ body = response_body.match(regex)[1].scan(/(?<key>.*)=(?<value>.*)\r\n/)
10
+ params = {}
11
+ body.each do |param|
12
+ k,v = param
13
+ params[k.strip.downcase.to_sym] = v
14
+ end
15
+ params
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module Rubyplat
2
+ VERSION = "0.1.5"
3
+ end
data/lib/rubyplat.rb ADDED
@@ -0,0 +1,42 @@
1
+ require "rubyplat/version"
2
+ require 'cyberplat_pki'
3
+ require 'date'
4
+ require 'net/http'
5
+ require_relative 'rubyplat/utils/parser'
6
+ require_relative 'rubyplat/configuration'
7
+ require_relative 'rubyplat/signed_request'
8
+ require_relative 'rubyplat/client'
9
+
10
+ require_relative 'rubyplat/gateways/gateway'
11
+
12
+ require_relative 'rubyplat/requests/payment_permission'
13
+ require_relative 'rubyplat/requests/payment_request'
14
+ require_relative 'rubyplat/requests/payment_status'
15
+ require_relative 'rubyplat/requests/check_balance'
16
+ require_relative 'rubyplat/requests/refill_info'
17
+
18
+ require_relative 'rubyplat/responses/response'
19
+ require_relative 'rubyplat/responses/payment_permission_response'
20
+ require_relative 'rubyplat/responses/payment_response'
21
+ require_relative 'rubyplat/responses/payment_status_response'
22
+ require_relative 'rubyplat/responses/check_balance_response'
23
+ require_relative 'rubyplat/responses/refill_info_response'
24
+
25
+ module Rubyplat
26
+ extend self
27
+
28
+ InvalidPaytool = Class.new(StandardError)
29
+ PAYTOOL = {
30
+ cash: 0,
31
+ local_card: 1,
32
+ foreign_card: 2
33
+ }
34
+
35
+ def config
36
+ @config ||= Rubyplat::Configuration.new
37
+ end
38
+
39
+ def configure
40
+ yield config
41
+ end
42
+ end
data/rubyplat.gemspec ADDED
@@ -0,0 +1,28 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "rubyplat/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rubyplat"
8
+ spec.version = Rubyplat::VERSION
9
+ spec.authors = ["Evgeniy Burdaev"]
10
+ spec.email = ["inqify@gmail.com"]
11
+
12
+ spec.summary = %q{Gem for creating Cyberplat Payment System Requests}
13
+ spec.description = %q{Cyberplat wrapper}
14
+ spec.homepage = ""
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_runtime_dependency 'cyberplat_pki_patched', '~> 1.0', '>= 1.0.1'
24
+ spec.add_development_dependency "bundler", "~> 1.16"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "pry"
27
+ spec.add_development_dependency "minitest", "~> 5.0"
28
+ end
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rubyplat
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.5
5
+ platform: ruby
6
+ authors:
7
+ - Evgeniy Burdaev
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-05-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cyberplat_pki_patched
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.0.1
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.0.1
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.16'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.16'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '10.0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '10.0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: pry
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: minitest
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '5.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '5.0'
89
+ description: Cyberplat wrapper
90
+ email:
91
+ - inqify@gmail.com
92
+ executables: []
93
+ extensions: []
94
+ extra_rdoc_files: []
95
+ files:
96
+ - ".gitignore"
97
+ - ".travis.yml"
98
+ - Gemfile
99
+ - Gemfile.lock
100
+ - README.md
101
+ - Rakefile
102
+ - bin/console
103
+ - bin/setup
104
+ - lib/rubyplat.rb
105
+ - lib/rubyplat/client.rb
106
+ - lib/rubyplat/configuration.rb
107
+ - lib/rubyplat/gateways/gateway.rb
108
+ - lib/rubyplat/requests/check_balance.rb
109
+ - lib/rubyplat/requests/payment_permission.rb
110
+ - lib/rubyplat/requests/payment_request.rb
111
+ - lib/rubyplat/requests/payment_status.rb
112
+ - lib/rubyplat/requests/refill_info.rb
113
+ - lib/rubyplat/responses/check_balance_response.rb
114
+ - lib/rubyplat/responses/payment_permission_response.rb
115
+ - lib/rubyplat/responses/payment_response.rb
116
+ - lib/rubyplat/responses/payment_status_response.rb
117
+ - lib/rubyplat/responses/refill_info_response.rb
118
+ - lib/rubyplat/responses/response.rb
119
+ - lib/rubyplat/signed_request.rb
120
+ - lib/rubyplat/utils/parser.rb
121
+ - lib/rubyplat/version.rb
122
+ - rubyplat.gemspec
123
+ homepage: ''
124
+ licenses: []
125
+ metadata: {}
126
+ post_install_message:
127
+ rdoc_options: []
128
+ require_paths:
129
+ - lib
130
+ required_ruby_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ required_rubygems_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ requirements: []
141
+ rubyforge_project:
142
+ rubygems_version: 2.7.6
143
+ signing_key:
144
+ specification_version: 4
145
+ summary: Gem for creating Cyberplat Payment System Requests
146
+ test_files: []