tochka_cyclops_api 0.3.0 → 0.4.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 +4 -4
- data/README.md +65 -8
- data/Rakefile +0 -4
- data/lib/tasks/methods.rake +11 -0
- data/lib/tochka_cyclops_api/data_processor.rb +44 -19
- data/lib/tochka_cyclops_api/generators/templates/tochka_cyclops_request_model_template.rb +1 -1
- data/lib/tochka_cyclops_api/generators/templates/tochka_cyclops_responses_migration_template.rb +1 -1
- data/lib/tochka_cyclops_api/methods.rb +198 -5
- data/lib/tochka_cyclops_api/request.rb +66 -31
- data/lib/tochka_cyclops_api/response.rb +27 -34
- data/lib/tochka_cyclops_api/result.rb +33 -0
- data/lib/tochka_cyclops_api/schemas/requests/activate_beneficiary.rb +22 -0
- data/lib/tochka_cyclops_api/schemas/requests/create_beneficiary_fl.rb +56 -0
- data/lib/tochka_cyclops_api/schemas/requests/create_beneficiary_ip.rb +22 -10
- data/lib/tochka_cyclops_api/schemas/requests/create_beneficiary_ul.rb +22 -10
- data/lib/tochka_cyclops_api/schemas/requests/deactivate_beneficiary.rb +22 -0
- data/lib/tochka_cyclops_api/schemas/requests/echo.rb +2 -0
- data/lib/tochka_cyclops_api/schemas/requests/get_beneficiary.rb +22 -0
- data/lib/tochka_cyclops_api/schemas/requests/list_beneficiary.rb +44 -0
- data/lib/tochka_cyclops_api/schemas/requests/update_beneficiary_fl.rb +51 -0
- data/lib/tochka_cyclops_api/schemas/requests/update_beneficiary_ip.rb +39 -0
- data/lib/tochka_cyclops_api/schemas/requests/update_beneficiary_ul.rb +38 -0
- data/lib/tochka_cyclops_api/schemas/responses/activate_beneficiary.rb +24 -0
- data/lib/tochka_cyclops_api/schemas/responses/create_beneficiary_fl.rb +24 -0
- data/lib/tochka_cyclops_api/schemas/responses/create_beneficiary_ip.rb +10 -1
- data/lib/tochka_cyclops_api/schemas/responses/create_beneficiary_ul.rb +9 -9
- data/lib/tochka_cyclops_api/schemas/responses/deactivate_beneficiary.rb +24 -0
- data/lib/tochka_cyclops_api/schemas/responses/echo.rb +1 -1
- data/lib/tochka_cyclops_api/schemas/responses/error.rb +5 -2
- data/lib/tochka_cyclops_api/schemas/responses/get_beneficiary.rb +48 -0
- data/lib/tochka_cyclops_api/schemas/responses/list_beneficiary.rb +38 -0
- data/lib/tochka_cyclops_api/schemas/responses/update_beneficiary_fl.rb +20 -0
- data/lib/tochka_cyclops_api/schemas/responses/update_beneficiary_ip.rb +20 -0
- data/lib/tochka_cyclops_api/schemas/responses/update_beneficiary_ul.rb +24 -0
- data/lib/tochka_cyclops_api/schemas/results/local_error.rb +0 -0
- data/lib/tochka_cyclops_api/test.rb +0 -0
- data/lib/tochka_cyclops_api/version.rb +1 -1
- data/lib/tochka_cyclops_api.rb +5 -2
- metadata +22 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36957c52f3476c825762fda41ec211a1a55d7eb15337c3eae48e32cb38d61419
|
4
|
+
data.tar.gz: d3d39943258ce772f1a8f949c5bcee9f1abb692d189775b67c0873d2ab98ebd4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '096c88b4842314462b00977f267448bb6a3ee4043dc0b3d0efd921806f14be7655d43122b2e476216df9775b93fdf2cc214d119f95177c80cc6dad3ab41a43a1'
|
7
|
+
data.tar.gz: 9ebfe7d51a013072ddfa6b6ba33dcb767262a93eb1f57fd4c59aa1147422cf4377bcbe1f2683625c6e2d7495b48b348f882c844781fabe8a7c9cb495c1e0a1d0
|
data/README.md
CHANGED
@@ -8,6 +8,7 @@ A simple way to interact with the ["Tochka" bank's api][api_source_page]
|
|
8
8
|
- [Installation](#installation)
|
9
9
|
- [Settings](#settings)
|
10
10
|
- [Usage](#usage)
|
11
|
+
- [Rake tasks](#rake)
|
11
12
|
|
12
13
|
## Getting started
|
13
14
|
|
@@ -16,19 +17,26 @@ A simple way to interact with the ["Tochka" bank's api][api_source_page]
|
|
16
17
|
Add this line to your application's Gemfile:
|
17
18
|
|
18
19
|
```sh
|
19
|
-
bundle add
|
20
|
+
bundle add tochka_cyclops_api
|
20
21
|
```
|
21
22
|
|
22
|
-
and run commands bellow to create
|
23
|
+
and run commands bellow to create models, migrations and the initializer:
|
23
24
|
|
24
25
|
```sh
|
25
26
|
rails generate tochka_cyclops_api:models
|
26
27
|
rails generate tochka_cyclops_api:initializer
|
27
28
|
```
|
28
29
|
|
30
|
+
to use rake tasks you should also add the following lines to Rakefile of your Rails project:
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
spec = Gem::Specification.find_by_name 'tochka_cyclops_api'
|
34
|
+
load "#{spec.gem_dir}/lib/tasks/methods.rake"
|
35
|
+
```
|
36
|
+
|
29
37
|
### Settings
|
30
38
|
|
31
|
-
You have to set the settings in the initializer file (_config/initializers/
|
39
|
+
You have to set the settings in the initializer file (_config/initializers/tochka_cyclops_api.rb_):
|
32
40
|
|
33
41
|
```ruby
|
34
42
|
# frozen_string_literal: true
|
@@ -50,11 +58,58 @@ TochkaCyclopsApi.send_request(method, data)
|
|
50
58
|
method - name of the method defined on the bank side point;
|
51
59
|
data - hash of the value required to fulfill the request.
|
52
60
|
|
53
|
-
|
61
|
+
There are special rake tasks to get information about available methods:
|
62
|
+
|
63
|
+
```sh
|
64
|
+
bundle exec rake methods:list
|
65
|
+
bundle exec rake methods:desc method=method_name
|
66
|
+
```
|
67
|
+
|
68
|
+
Examples
|
69
|
+
```sh
|
70
|
+
> bundle exec rake methods:list
|
71
|
+
# ** Invoke methods:list (first_time)
|
72
|
+
# ** Execute methods:list
|
73
|
+
# echo
|
74
|
+
# create_beneficiary_ul
|
75
|
+
# create_beneficiary_ip
|
76
|
+
# ...
|
77
|
+
|
78
|
+
> bundle exec rake methods:desc method=create_beneficiary_ul
|
79
|
+
# ** Invoke methods:desc (first_time)
|
80
|
+
# ** Execute methods:desc
|
81
|
+
# inn | mandatory | string
|
82
|
+
# nominal_account_code | optional | string
|
83
|
+
# nominal_account_bic | optional | string
|
84
|
+
# beneficiary_data | mandatory | {
|
85
|
+
# name | mandatory | string
|
86
|
+
# kpp | mandatory | string
|
87
|
+
# ogrn | optional | string
|
88
|
+
# }
|
89
|
+
#
|
90
|
+
# ================================================================================
|
91
|
+
#
|
92
|
+
# EXAMPLE
|
93
|
+
#
|
94
|
+
# {
|
95
|
+
# inn: '7743745038',
|
96
|
+
# nominal_account_code: '40702810338170022645',
|
97
|
+
# nominal_account_bic: '044525225',
|
98
|
+
# beneficiary_data: {
|
99
|
+
# name: 'ООО «ТК ИнжСтройКомплект»',
|
100
|
+
# kpp: '773401001',
|
101
|
+
# ogrn: '1097746324169'
|
102
|
+
# }
|
103
|
+
# }
|
104
|
+
```
|
105
|
+
|
106
|
+
Example of sending request:
|
54
107
|
```ruby
|
55
|
-
TochkaCyclopsApi.
|
56
|
-
|
57
|
-
|
108
|
+
TochkaCyclopsApi.send_request(
|
109
|
+
# Method contains the name of the TochkaCyclopsApi method
|
110
|
+
method: 'create_beneficiary_ul',
|
111
|
+
# Data is value for the "params" field of request body
|
112
|
+
data: {
|
58
113
|
inn: "7925930371",
|
59
114
|
nominal_account_code: "000000000000000000000",
|
60
115
|
nominal_account_bic: "0000000000",
|
@@ -62,7 +117,9 @@ TochkaCyclopsApi.send(
|
|
62
117
|
name: "ООО \"Рога и Копыта\"",
|
63
118
|
kpp: "246301001"
|
64
119
|
}
|
65
|
-
}
|
120
|
+
},
|
121
|
+
# Layer have to has one of the following values: :stage, :pre, :prod
|
122
|
+
layer: :stage
|
66
123
|
)
|
67
124
|
```
|
68
125
|
|
data/Rakefile
CHANGED
@@ -6,56 +6,81 @@ require 'securerandom'
|
|
6
6
|
require 'json'
|
7
7
|
|
8
8
|
require_relative 'request'
|
9
|
+
require_relative 'result'
|
9
10
|
require_relative 'schemas/requests/echo'
|
10
11
|
|
11
12
|
module TochkaCyclopsApi
|
12
13
|
# Module for input data validation and subsequent request invocation
|
13
|
-
|
14
|
-
def send_request(method
|
14
|
+
class DataProcessor
|
15
|
+
def self.send_request(method:, data:, layer: )
|
15
16
|
@method = method
|
16
17
|
@data = data
|
17
|
-
@
|
18
|
+
@layer = layer
|
19
|
+
@errors = {}
|
20
|
+
@url = url_for
|
21
|
+
@request_id = SecureRandom.uuid
|
22
|
+
schemas
|
23
|
+
validation = @request_schema&.call(@data.deep_symbolize_keys)
|
24
|
+
@validation_errors = validation&.errors.to_h
|
18
25
|
|
19
|
-
|
20
|
-
|
21
|
-
send_data
|
26
|
+
call
|
22
27
|
end
|
23
28
|
|
24
29
|
private
|
25
30
|
|
26
|
-
def
|
27
|
-
if
|
28
|
-
|
29
|
-
|
31
|
+
def self.call
|
32
|
+
@errors[:url] = "Layer you called for is not exist" if @url.nil?
|
33
|
+
@errors[:request_schema] = "Request schema for method #{@method} is not found" if @request_schema.nil?
|
34
|
+
@errors[:response_schema] = "Response schema for method #{@method} is not found" if @response_schema.nil?
|
35
|
+
|
36
|
+
@errors[:validation] = @validation_errors if @request_schemas.present?
|
37
|
+
|
38
|
+
if @errors.keys.any?
|
39
|
+
Result.failure(@errors)
|
40
|
+
else
|
41
|
+
TochkaCyclopsApi::Request.send_request(method: @method, body: body, url: @url)
|
30
42
|
end
|
43
|
+
end
|
31
44
|
|
32
|
-
|
45
|
+
def self.url_for
|
46
|
+
{
|
47
|
+
stage: 'https://stage.tochka.com/api/v1/cyclops',
|
48
|
+
pre: 'https://pre.tochka.com/api/v1/cyclops',
|
49
|
+
prod: 'https://api.tochka.com/api/v1/cyclops'
|
50
|
+
}.fetch(@layer, nil)
|
33
51
|
end
|
34
52
|
|
35
|
-
def
|
36
|
-
|
53
|
+
def self.schemas
|
54
|
+
@request_schema = request_schema
|
55
|
+
@response_schema = response_schema
|
37
56
|
end
|
38
57
|
|
39
|
-
def
|
58
|
+
def self.request_schema
|
40
59
|
require_relative "schemas/requests/#{@method}"
|
41
60
|
schema = ['TochkaCyclopsApi', 'Schemas', 'Requests', camel_case_method].join('::').constantize
|
42
61
|
|
43
62
|
schema.new
|
44
63
|
rescue => e
|
45
|
-
|
46
|
-
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.response_schema
|
68
|
+
require_relative "schemas/responses/#{@method}"
|
69
|
+
schema = ['TochkaCyclopsApi', 'Schemas', 'Responses', camel_case_method].join('::').constantize
|
70
|
+
rescue => e
|
71
|
+
nil
|
47
72
|
end
|
48
73
|
|
49
|
-
def camel_case_method
|
74
|
+
def self.camel_case_method
|
50
75
|
@method.split('_').map(&:capitalize).join
|
51
76
|
end
|
52
77
|
|
53
|
-
def body
|
78
|
+
def self.body
|
54
79
|
{
|
55
80
|
"jsonrpc": '2.0',
|
56
81
|
"method": @method,
|
57
82
|
"params": @data,
|
58
|
-
"id": @
|
83
|
+
"id": @request_id
|
59
84
|
}.to_json
|
60
85
|
end
|
61
86
|
end
|
@@ -1,9 +1,202 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'dry/schema'
|
4
|
+
|
5
|
+
Undefined = Dry::Schema::Undefined
|
6
|
+
|
7
|
+
module Types
|
8
|
+
include Dry.Types()
|
9
|
+
end
|
10
|
+
|
11
|
+
class DocCompiler
|
12
|
+
def visit(node)
|
13
|
+
meth, rest = node
|
14
|
+
public_send(:"visit_#{meth}", rest)
|
15
|
+
end
|
16
|
+
|
17
|
+
def visit_set(nodes)
|
18
|
+
nodes.map { |node| visit(node) }.flatten(1)
|
19
|
+
end
|
20
|
+
|
21
|
+
def visit_and(node)
|
22
|
+
left, right = node
|
23
|
+
[visit(left), visit(right)].compact
|
24
|
+
end
|
25
|
+
|
26
|
+
def visit_key(node)
|
27
|
+
name, rest = node
|
28
|
+
|
29
|
+
predicates = visit(rest).flatten
|
30
|
+
|
31
|
+
if predicates[0].is_a? Symbol
|
32
|
+
validations = predicate_description(predicates[0], predicates[1])
|
33
|
+
|
34
|
+
{ key: name, validations: validations }
|
35
|
+
else
|
36
|
+
{ key: name, validations: predicates }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def visit_implication(node)
|
41
|
+
_, right = node.map(&method(:visit))
|
42
|
+
right.merge(optional: true)
|
43
|
+
end
|
44
|
+
|
45
|
+
def visit_predicate(node)
|
46
|
+
name, args = node
|
47
|
+
|
48
|
+
return if name.equal?(:key?)
|
49
|
+
|
50
|
+
{ name => args.map(&:last).reject { |v| v.equal?(Dry::Schema::Undefined) } }
|
51
|
+
end
|
52
|
+
|
53
|
+
def predicate_description(name, args)
|
54
|
+
case name
|
55
|
+
when :str? then "string"
|
56
|
+
when :bool? then "true/false"
|
57
|
+
when :filled? then "filled"
|
58
|
+
when :int? then "integer"
|
59
|
+
when :gt? then "greater than #{args[0]}"
|
60
|
+
else
|
61
|
+
raise NotImplementedError, "#{name} not supported yet"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
3
66
|
module TochkaCyclopsApi
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
67
|
+
class Methods
|
68
|
+
METHODS = %w[
|
69
|
+
echo
|
70
|
+
create_beneficiary_ul
|
71
|
+
create_beneficiary_ip
|
72
|
+
create_beneficiary_fl
|
73
|
+
update_beneficiary_ul
|
74
|
+
update_beneficiary_ip
|
75
|
+
update_beneficiary_fl
|
76
|
+
get_beneficiary
|
77
|
+
list_beneficiary
|
78
|
+
activate_beneficiary
|
79
|
+
deactivate_beneficiary
|
80
|
+
]
|
81
|
+
|
82
|
+
DIVIDER = ["\n", "="*80, "\n"]
|
83
|
+
|
84
|
+
def self.get_method(method)
|
85
|
+
return unless method_exists? method
|
86
|
+
|
87
|
+
require_relative "schemas/requests/#{method}"
|
88
|
+
|
89
|
+
@method = method
|
90
|
+
|
91
|
+
define_schema_class
|
92
|
+
define_schema_ast
|
93
|
+
parse_schema_ast
|
94
|
+
@formatted_schema_ast = format_schema_ast
|
95
|
+
show_schema
|
96
|
+
|
97
|
+
puts @method.split('_').map(&:capitalize).join
|
98
|
+
puts @formatted_schema_ast
|
99
|
+
puts DIVIDER
|
100
|
+
puts ['EXAMPLE', "\n"]
|
101
|
+
puts @schema_class.const_get('EXAMPLE')
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
def self.method_exists?(method)
|
107
|
+
return true if method.in? METHODS
|
108
|
+
|
109
|
+
puts "Method #{method} is not found"
|
110
|
+
false
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.define_schema_class
|
114
|
+
@schema_class = [
|
115
|
+
"TochkaCyclopsApi",
|
116
|
+
"Schemas",
|
117
|
+
"Requests",
|
118
|
+
camel_case(@method)].join('::').constantize
|
119
|
+
end
|
120
|
+
|
121
|
+
def self.define_schema_ast
|
122
|
+
@schema_ast = @schema_class.new.schema.ast
|
123
|
+
end
|
124
|
+
|
125
|
+
def self.parse_schema_ast
|
126
|
+
compiler = DocCompiler.new
|
127
|
+
|
128
|
+
@schema_ast = compiler.visit(@schema_ast).map do |row|
|
129
|
+
key = row[:key]
|
130
|
+
validations = row[:validations]
|
131
|
+
optional = row[:optional] ? 'optional' : 'mandatory'
|
132
|
+
|
133
|
+
if validations.is_a? Array
|
134
|
+
validations = validations.map do |validation|
|
135
|
+
v_key = validation[:key]
|
136
|
+
v_validations = validation[:validations]
|
137
|
+
v_optional = validation[:optional] ? 'optional' : 'mandatory'
|
138
|
+
|
139
|
+
[v_key, v_optional, v_validations]
|
140
|
+
end
|
141
|
+
end
|
142
|
+
[key, optional, validations]
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.column_sizes(array)
|
147
|
+
sizes = []
|
148
|
+
3.times do |index|
|
149
|
+
size = array.map do |row|
|
150
|
+
next if row[index].is_a? Array
|
151
|
+
|
152
|
+
row[index].to_s.length
|
153
|
+
end
|
154
|
+
sizes << size.compact.max
|
155
|
+
end
|
156
|
+
sizes
|
157
|
+
end
|
158
|
+
|
159
|
+
def self.format_schema_ast(array = @schema_ast)
|
160
|
+
sizes = column_sizes(array)
|
161
|
+
array.map do |sub_array|
|
162
|
+
sub_array.each_with_index.map { |row, index| format_row(row, sizes[index]) }
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def self.format_row(row, indent)
|
167
|
+
if row.is_a? Array
|
168
|
+
format_schema_ast(row)
|
169
|
+
else
|
170
|
+
row.to_s.ljust(indent)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def self.show_schema
|
175
|
+
@formatted_schema_ast.map! do |row|
|
176
|
+
array = row.select { |element| element.is_a? Array }.last
|
177
|
+
if array.present?
|
178
|
+
max_first_element_size = array.map { |row| row[0].strip.to_s.length }.max
|
179
|
+
|
180
|
+
# 9 is size of 2 dividers (" | ") and 1 brace
|
181
|
+
row_indent = row[0].size + row[1].size + 7
|
182
|
+
|
183
|
+
# 2 is 2 spaces indent
|
184
|
+
array.map! do |row|
|
185
|
+
row[0] = row[0].rjust(row_indent + max_first_element_size + 2)
|
186
|
+
row.join(' | ')
|
187
|
+
end
|
188
|
+
|
189
|
+
array = ["{"] + array + ["}".rjust(row_indent)]
|
190
|
+
|
191
|
+
row[-1] = array.join("\n")
|
192
|
+
end
|
193
|
+
row.join(' | ')
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
|
198
|
+
def self.camel_case(string)
|
199
|
+
string.split('_').map(&:capitalize).join
|
200
|
+
end
|
201
|
+
end
|
9
202
|
end
|
@@ -6,53 +6,88 @@ require_relative 'response'
|
|
6
6
|
|
7
7
|
module TochkaCyclopsApi
|
8
8
|
# Module for sending requests to the bank's api
|
9
|
-
|
10
|
-
def self.
|
9
|
+
class Request
|
10
|
+
def self.send_request(body:, method:, url: )
|
11
11
|
@method = method
|
12
|
-
|
12
|
+
@body = body
|
13
|
+
@uri = URI(url)
|
14
|
+
@request_object = initialize_request_object
|
15
|
+
@post_request = initialize_post_request
|
16
|
+
@adapter = initialize_adapter
|
13
17
|
|
14
|
-
|
15
|
-
|
16
|
-
http.use_ssl = true
|
18
|
+
call
|
19
|
+
end
|
17
20
|
|
18
|
-
|
19
|
-
'sign-data' => signature(body),
|
20
|
-
'sign-thumbprint' => TochkaCyclopsApi.configuration.sign_thumbprint,
|
21
|
-
'sign-system' => TochkaCyclopsApi.configuration.sign_system,
|
22
|
-
'Content-Type' => 'application/pdf'
|
23
|
-
})
|
24
|
-
request.body = body
|
21
|
+
private
|
25
22
|
|
26
|
-
|
23
|
+
def self.call
|
24
|
+
get_response
|
25
|
+
response = handle_response
|
27
26
|
|
28
|
-
case response
|
29
|
-
when
|
30
|
-
|
31
|
-
TochkaCyclopsApi::Response.create(@request, response, method)
|
32
|
-
when (400..499)
|
33
|
-
-> { 'Our server error' }[]
|
27
|
+
case response[:status]
|
28
|
+
when :error
|
29
|
+
Result.failure(response[:data])
|
34
30
|
else
|
35
|
-
|
36
|
-
-> { 'Their server error' }[]
|
31
|
+
Response.new(request: @request_object, response: response[:data], method: @method)
|
37
32
|
end
|
38
33
|
end
|
39
34
|
|
40
|
-
def self.
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
base64_signature = Base64.strict_encode64(signature_key)
|
45
|
-
base64_signature.gsub("\n", '')
|
35
|
+
def self.initialize_adapter
|
36
|
+
adapter = Net::HTTP.new(@uri.host, @uri.port)
|
37
|
+
adapter.use_ssl = true
|
38
|
+
adapter
|
46
39
|
end
|
47
40
|
|
48
|
-
def self.
|
49
|
-
|
41
|
+
def self.initialize_request_object
|
42
|
+
TochkaCyclopsRequest.create(
|
50
43
|
method: @method,
|
51
|
-
body: body,
|
44
|
+
body: @body,
|
52
45
|
request_identifier: @id,
|
53
46
|
# idempotency_key:
|
54
47
|
status: 'initialized'
|
55
48
|
)
|
56
49
|
end
|
50
|
+
|
51
|
+
def self.initialize_post_request
|
52
|
+
post_request = Net::HTTP::Post.new(@uri, {
|
53
|
+
'sign-data' => signature,
|
54
|
+
'sign-thumbprint' => TochkaCyclopsApi.configuration.sign_thumbprint,
|
55
|
+
'sign-system' => TochkaCyclopsApi.configuration.sign_system,
|
56
|
+
'Content-Type' => 'application/json'
|
57
|
+
})
|
58
|
+
post_request.body = @body
|
59
|
+
post_request
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.get_response
|
63
|
+
@response = @adapter.request(@post_request)
|
64
|
+
rescue => e
|
65
|
+
@error = { request_error: e }
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.handle_response
|
69
|
+
return { status: :error, data: @error } if @error
|
70
|
+
|
71
|
+
status = case @response.code.to_i
|
72
|
+
when (200..299)
|
73
|
+
{
|
74
|
+
status: :ok,
|
75
|
+
data: @response
|
76
|
+
}
|
77
|
+
else
|
78
|
+
{
|
79
|
+
status: :error,
|
80
|
+
data: { request_error: @response }
|
81
|
+
}
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.signature
|
86
|
+
digest = OpenSSL::Digest.new('sha256')
|
87
|
+
private_key = OpenSSL::PKey::RSA.new(TochkaCyclopsApi.configuration.private_key)
|
88
|
+
signature_key = private_key.sign(digest, @body)
|
89
|
+
base64_signature = Base64.strict_encode64(signature_key)
|
90
|
+
base64_signature.gsub("\n", '')
|
91
|
+
end
|
57
92
|
end
|
58
93
|
end
|
@@ -1,63 +1,56 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'schemas/responses/
|
3
|
+
require_relative 'schemas/responses/error'
|
4
4
|
|
5
5
|
module TochkaCyclopsApi
|
6
6
|
# Class for processing the response received from the api bank
|
7
7
|
class Response
|
8
|
-
def self.create(request,
|
9
|
-
@method = method
|
8
|
+
def self.create(request: ,response: ,method:)
|
10
9
|
@request = request
|
11
|
-
@
|
12
|
-
parse
|
10
|
+
@method = method
|
11
|
+
@body = JSON.parse(response.body)
|
12
|
+
@response_schema = "TochkaCyclopsApi::Schemas::Responses::#{camel_case_method}".constantize
|
13
|
+
@error_schema = 'TochkaCyclopsApi::Schemas::Responses::Error'.constantize
|
13
14
|
|
14
|
-
|
15
|
-
response_struct: @response_struct,
|
16
|
-
result: @result
|
17
|
-
}
|
15
|
+
call
|
18
16
|
end
|
19
17
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
private
|
19
|
+
|
20
|
+
def self.call
|
21
|
+
@result = @body['result']
|
22
|
+
@error = @body['error']
|
23
|
+
|
24
|
+
if @error.present?
|
25
25
|
parse_error
|
26
|
+
else
|
27
|
+
parse_result
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
29
31
|
def self.parse_result
|
30
|
-
|
31
|
-
response_schema = schema || -> { "Schema for #{@method} is not found" }[]
|
32
|
+
return nil if @result.nil?
|
32
33
|
|
33
|
-
|
34
|
-
@request.update(result:
|
34
|
+
response = TochkaCyclopsResponse.create(body: @body, result: @result)
|
35
|
+
@request.update(result: response, status: 'success')
|
35
36
|
@result.deep_symbolize_keys if @result.is_a? Hash
|
36
|
-
|
37
|
+
response_struct = @response_schema.new(@result)
|
38
|
+
|
39
|
+
Result.success(response_struct)
|
37
40
|
end
|
38
41
|
|
39
42
|
def self.parse_error
|
40
|
-
|
41
|
-
require_relative 'schemas/responses/error'
|
42
|
-
response_schema = 'TochkaCyclopsApi::Schemas::Responses::Error'.constantize
|
43
|
+
return nil if @error.nil?
|
43
44
|
|
44
|
-
|
45
|
+
response = TochkaCyclopsError.create(
|
45
46
|
body: @body,
|
46
47
|
code: @error['code'],
|
47
48
|
message: @error['message']
|
48
49
|
)
|
50
|
+
@request.update(result: response, status: 'failure')
|
51
|
+
response_struct = @error_schema.new(@error.deep_symbolize_keys)
|
49
52
|
|
50
|
-
|
51
|
-
|
52
|
-
@response_struct = response_schema.new(@error.deep_symbolize_keys)
|
53
|
-
end
|
54
|
-
|
55
|
-
def self.schema
|
56
|
-
require_relative "schemas/responses/#{@method}"
|
57
|
-
"TochkaCyclopsApi::Schemas::Responses::#{camel_case_method}".constantize
|
58
|
-
rescue StandardError => e
|
59
|
-
@errors = { error: e.message }
|
60
|
-
false
|
53
|
+
Result.success(response_struct)
|
61
54
|
end
|
62
55
|
|
63
56
|
def self.camel_case_method
|