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 +7 -0
- data/.gitignore +8 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +32 -0
- data/README.md +66 -0
- data/Rakefile +10 -0
- data/bin/console +11 -0
- data/bin/setup +8 -0
- data/lib/rubyplat/client.rb +77 -0
- data/lib/rubyplat/configuration.rb +30 -0
- data/lib/rubyplat/gateways/gateway.rb +29 -0
- data/lib/rubyplat/requests/check_balance.rb +37 -0
- data/lib/rubyplat/requests/payment_permission.rb +89 -0
- data/lib/rubyplat/requests/payment_request.rb +74 -0
- data/lib/rubyplat/requests/payment_status.rb +31 -0
- data/lib/rubyplat/requests/refill_info.rb +40 -0
- data/lib/rubyplat/responses/check_balance_response.rb +36 -0
- data/lib/rubyplat/responses/payment_permission_response.rb +10 -0
- data/lib/rubyplat/responses/payment_response.rb +9 -0
- data/lib/rubyplat/responses/payment_status_response.rb +31 -0
- data/lib/rubyplat/responses/refill_info_response.rb +15 -0
- data/lib/rubyplat/responses/response.rb +21 -0
- data/lib/rubyplat/signed_request.rb +20 -0
- data/lib/rubyplat/utils/parser.rb +19 -0
- data/lib/rubyplat/version.rb +3 -0
- data/lib/rubyplat.rb +42 -0
- data/rubyplat.gemspec +28 -0
- metadata +146 -0
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
data/.travis.yml
ADDED
data/Gemfile
ADDED
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
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,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,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
|
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: []
|