ya_kassa 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c80ebe1b2e82dffcbeb7aa6710d04db208b8b7f1bd306ca0b1e51fb1a5340d3
4
- data.tar.gz: fa4edd57516cc1d406bbb4de54dd5e50b6f10fb1be05cf95baaf110530c4930d
3
+ metadata.gz: a57071f97b498ff3f0f4c21aa12ba4f27f60d7f7297af544414b662be9cafb8f
4
+ data.tar.gz: ba2d2273b056ccf382e46d51f561bfd72c1e38cd92563877c3bfca6023df6064
5
5
  SHA512:
6
- metadata.gz: '0826265dbc970d3a00c0ed091d27a59fc08798920c2749ccde615c8df4b4b54c71d10ab0a98b68a8f48b89331116a62ea4dc01168c68928f236f31f0268f337d'
7
- data.tar.gz: d5935c3d0f49cf9c8c247429ffa115d0db92a48816067e2d7019c619093c9a50ba24888c1f957f3affc3370942042fe295b7d15f5856599974a7b2f7f07fe4f2
6
+ metadata.gz: dce827177a2b419ea89dbb9af5b492af60e570f7bcf5b52df05655de629755d23e480853ffaae45ba8bea4b29af0d8a730ad94594a29115df4914e2230fe19ca
7
+ data.tar.gz: 4cc3d67f140eb9849df90d2ac084dbe6fe6d329a9aec053a36e0d50fe0a3686cac0d154f2c5e14c05546cf8cae3abcd2ebf4cd9dc92257c59d5039d9779975d3
data/.gitignore CHANGED
@@ -9,3 +9,4 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+ *.gem
@@ -0,0 +1,57 @@
1
+ module YaKassa
2
+ module V3
3
+ class BaseRequest
4
+ extend Concerns::Attributable
5
+ include Concerns::Validatable
6
+
7
+ attr_reader :response
8
+
9
+ def initialize(idempotence_key, params = {})
10
+ @params = params
11
+ @idempotence_key = idempotence_key
12
+ @response = nil
13
+ end
14
+
15
+ def create
16
+ return errors unless valid?
17
+ send_request
18
+ end
19
+
20
+ def body
21
+ { }
22
+ end
23
+
24
+ private
25
+
26
+ def send_request
27
+ resp = api_client.request
28
+ raise resp.inspect unless resp[:body].present?
29
+ @response = JSON.parse(resp[:body])
30
+ end
31
+
32
+ def api_client_post
33
+ Client::Post.new(url, body.to_json, @idempotence_key)
34
+ end
35
+
36
+ def api_client_get
37
+ Client::Get.new(router.payment_status_url)
38
+ end
39
+
40
+ def api_client
41
+ raise 'Method not implemented'
42
+ end
43
+
44
+ def url
45
+ raise 'Method not implemented'
46
+ end
47
+
48
+ def router
49
+ Router.new(payment_id: @params[:payment_id])
50
+ end
51
+
52
+ def class_validator
53
+ 'Base'
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,13 @@
1
+ module YaKassa
2
+ module V3
3
+ class BaseResponse
4
+ extend Concerns::Attributable
5
+
6
+ attr_reader :params
7
+
8
+ def initialize(params = {})
9
+ @params = params
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,55 @@
1
+ module YaKassa
2
+ module V3
3
+ module Client
4
+ class Base
5
+ attr_reader :url, :body, :idempotence_key
6
+
7
+ def initialize(url, body = nil, idempotence_key = nil)
8
+ @url = url
9
+ @body = body
10
+ @idempotence_key = idempotence_key
11
+ end
12
+
13
+ def request
14
+ response = send
15
+ { code: response.code, body: response_body(response), headers: response.headers}
16
+ end
17
+
18
+ protected
19
+
20
+ def response_body(response)
21
+ response.body
22
+ end
23
+
24
+ def send
25
+ raise 'Not implemented method'
26
+ end
27
+
28
+ def auth
29
+ { username: shop_id, password: secret_key }
30
+ end
31
+
32
+ def idempotence?
33
+ @idempotence_key.present?
34
+ end
35
+
36
+ def headers
37
+ {
38
+ 'Content-Type' => 'application/json',
39
+ 'Idempotence-Key' => @idempotence_key
40
+ }
41
+ end
42
+
43
+ private
44
+
45
+ def shop_id
46
+ Rails.application.credentials[:yandex_kassa][:shop_id]
47
+ end
48
+
49
+ def secret_key
50
+ Rails.application.credentials[:yandex_kassa][:secret_key]
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,17 @@
1
+ module YaKassa
2
+ module V3
3
+ module Client
4
+ class Get < Base
5
+ protected
6
+
7
+ def response_body(response)
8
+ JSON.parse(response.body)
9
+ end
10
+
11
+ def send
12
+ HTTParty.get(@url, basic_auth: auth)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ module YaKassa
2
+ module V3
3
+ module Client
4
+ class Post < Base
5
+ protected
6
+
7
+ def send
8
+ HTTParty.post(@url, body: @body, headers: headers, basic_auth: auth)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,26 @@
1
+ module YaKassa
2
+ module V3
3
+ module Concerns
4
+ module Attributable
5
+ def attributable(name, params = {})
6
+ define_attr_method(name, params[:default])
7
+ end
8
+
9
+ private
10
+
11
+ def define_attr_method(name, default_val = nil)
12
+ define_method(name) do
13
+ if @params[name.to_sym].nil?
14
+ @params[name.to_sym] = default_val
15
+ end
16
+ @params[name.to_sym]
17
+ end
18
+
19
+ define_method("#{name}=") do |val|
20
+ @params[name.to_sym] = val
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,70 @@
1
+ module YaKassa
2
+ module V3
3
+ module Concerns
4
+ module Validatable
5
+ VALIDATORS = {
6
+ present: 'Present',
7
+ is_a: "IsA",
8
+ is_a_boolean: 'IsABoolean',
9
+ float_or_nil: 'FloatOrNil'
10
+ }
11
+
12
+ module ClassMethods
13
+ def validatable(name, type, params = {})
14
+ validators = self.class_variable_get(:@@validators)
15
+ validators << { name: name, type: type, params: params }
16
+ class_variable_set(:@@validators, validators)
17
+ end
18
+ end
19
+
20
+ def self.included(klass)
21
+ class_variable_set(:@@validators, [])
22
+ klass.extend(ClassMethods)
23
+ end
24
+
25
+ def valid?
26
+ @errors = {}
27
+ valid_arr = validators.map do |opts|
28
+ validator = create_validator(opts)
29
+ validator.validate
30
+ collect_errors(validator)
31
+ validator.valid?
32
+ end
33
+ valid_arr.select { |v| v == false }.empty?
34
+ end
35
+
36
+ def errors
37
+ @errors.select { |k, v| v.any? }
38
+ end
39
+
40
+ private
41
+
42
+ def create_validator(opts)
43
+ validator = validator_class(opts[:type]).new(
44
+ opts[:name],
45
+ attr_value(opts[:name]),
46
+ opts[:params]
47
+ )
48
+ end
49
+
50
+ def validators
51
+ self.class.class_variable_get(:@@validators)
52
+ end
53
+
54
+ def attr_value(attr_name)
55
+ self.public_send(attr_name)
56
+ end
57
+
58
+ def collect_errors(validator)
59
+ @errors[validator.name] ||= []
60
+ @errors[validator.name] << validator.error
61
+ end
62
+
63
+ def validator_class(type)
64
+ klass = VALIDATORS[type]
65
+ "::YaKassa::V3::Validators::#{klass}".constantize
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,15 @@
1
+ module YaKassa
2
+ module V3
3
+ class PaymentCancelRequest < BaseRequest
4
+ private
5
+
6
+ def api_client
7
+ api_client_post
8
+ end
9
+
10
+ def url
11
+ router.payment_cancel_url
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,34 @@
1
+ module YaKassa
2
+ module V3
3
+ class PaymentCaptureRequest < BaseRequest
4
+ attributable :amount_value
5
+ attributable :amount_currency, default: "RUB"
6
+
7
+ validatable :amount_value, :present
8
+ validatable :amount_currency, :present
9
+
10
+ def body
11
+ res = nil
12
+ if amount_value && amount_currency
13
+ res = {
14
+ amount: {
15
+ value: amount_value,
16
+ currency: amount_currency
17
+ }
18
+ }
19
+ end
20
+ res
21
+ end
22
+
23
+ private
24
+
25
+ def api_client
26
+ api_client_post
27
+ end
28
+
29
+ def url
30
+ router.payment_confirmation_url
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,49 @@
1
+ module YaKassa
2
+ module V3
3
+ class PaymentRequest < BaseRequest
4
+ attributable :amount_value
5
+ attributable :amount_currency, default: "RUB"
6
+ attributable :capture, default: true
7
+ attributable :confirmation_type, default: "redirect"
8
+ attributable :return_url
9
+ attributable :confirmation_url
10
+ attributable :description
11
+
12
+ validatable :amount_value, :is_a, class: 'Float'
13
+ validatable :amount_currency, :present
14
+ validatable :capture, :is_a_boolean
15
+ validatable :confirmation_type, :present
16
+ validatable :return_url, :is_a, class: 'String'
17
+
18
+ # amount_value and return_url are required
19
+ def body
20
+ {
21
+ amount: {
22
+ value: amount_value,
23
+ currency: amount_currency
24
+ },
25
+ capture: capture,
26
+ confirmation: {
27
+ type: confirmation_type,
28
+ return_url: return_url
29
+ },
30
+ description: description
31
+ }
32
+ end
33
+
34
+ private
35
+
36
+ def api_client
37
+ api_client_post
38
+ end
39
+
40
+ def url
41
+ router.payment_url
42
+ end
43
+
44
+ def class_validator
45
+ 'PaymentRequest'
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,12 @@
1
+ module YaKassa
2
+ module V3
3
+ class PaymentResponse < BaseResponse
4
+ attributable :id
5
+ attributable :status
6
+ attributable :amount
7
+ attributable :created_at
8
+ attributable :payment_id
9
+ attributable :requestor
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,23 @@
1
+ module YaKassa
2
+ module V3
3
+ class PaymentStatusRequest < BaseRequest
4
+ def initialize(payment_id)
5
+ @payment_id = payment_id
6
+ end
7
+
8
+ def create
9
+ @response = api_client.request[:body]
10
+ end
11
+
12
+ private
13
+
14
+ def api_client
15
+ api_client_get
16
+ end
17
+
18
+ def router
19
+ Router.new(payment_id: @payment_id)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,92 @@
1
+ module YaKassa
2
+ module V3
3
+ class ReceiptRequest < BaseRequest
4
+ attributable :customer
5
+ attributable :payment_id
6
+ attributable :type, default: "payment"
7
+ attributable :send, default: "true"
8
+ attributable :items
9
+ attributable :full_name
10
+ attributable :email
11
+ attributable :phone
12
+ attributable :inn
13
+ attributable :vat_code, default: "2" # НДС "2" == 0%
14
+ attributable :currency, default: "RUB"
15
+ attributable :payment_mode, default: "full_payment"
16
+ attributable :payment_type, default: "prepayment"
17
+
18
+ validatable :payment_id, :is_a, class: "String"
19
+ validatable :type, :present
20
+ validatable :send, :present
21
+ validatable :items, :is_a, class: 'Array'
22
+ validatable :full_name, :is_a, class: "String"
23
+ validatable :email, :is_a, class: "String"
24
+ validatable :phone, :present
25
+ validatable :inn, :present
26
+
27
+ def body
28
+ {
29
+ customer: body_customer,
30
+ payment_id: payment_id,
31
+ type: type,
32
+ send: send,
33
+ items: body_items,
34
+ settlements: settlements_body
35
+ }
36
+ end
37
+
38
+ protected
39
+
40
+ def body_customer
41
+ body = {
42
+ full_name: full_name,
43
+ email: email,
44
+ phone: phone
45
+ }
46
+ body[:inn] = inn if inn
47
+ body
48
+ end
49
+
50
+ def body_items
51
+ items.map do |item|
52
+ {
53
+ description: item[:description],
54
+ quantity: item[:quantity],
55
+ amount: {
56
+ value: item[:amount_value],
57
+ currency: currency
58
+ },
59
+ vat_code: vat_code,
60
+ payment_mode: payment_mode
61
+ }
62
+ end
63
+ end
64
+
65
+ def settlements_body
66
+ items.map do |item|
67
+ {
68
+ type: payment_type,
69
+ amount: {
70
+ value: item[:amount_value],
71
+ currency: currency
72
+ }
73
+ }
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ def api_client
80
+ api_client_post
81
+ end
82
+
83
+ def url
84
+ router.receipt_url
85
+ end
86
+
87
+ def class_validator
88
+ 'ReceiptRequest'
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,9 @@
1
+ module YaKassa
2
+ module V3
3
+ class ReceiptResponse < BaseResponse
4
+ include Concerns::Attributable
5
+
6
+ attributable :id, default: 1
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,37 @@
1
+ module YaKassa
2
+ module V3
3
+ class RefundRequest < BaseRequest
4
+ attributable :amount_value
5
+ attributable :amount_currency, default: "RUB"
6
+ attributable :payment_id
7
+
8
+ validatable :amount_value, :is_a, class: 'Float'
9
+ validatable :amount_currency, :present
10
+ validatable :payment_id, :present
11
+
12
+ def body
13
+ {
14
+ payment_id: payment_id,
15
+ amount: {
16
+ value: amount_value,
17
+ currency: amount_currency
18
+ }
19
+ }
20
+ end
21
+
22
+ private
23
+
24
+ def api_client
25
+ api_client_post
26
+ end
27
+
28
+ def url
29
+ router.refund_url
30
+ end
31
+
32
+ def class_validator
33
+ 'RefundRequest'
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,12 @@
1
+ module YaKassa
2
+ module V3
3
+ class RefundResponse < BaseResponse
4
+ attributable :id
5
+ attributable :status
6
+ attributable :amount
7
+ attributable :created_at
8
+ attributable :payment_id
9
+ attributable :requestor
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,40 @@
1
+ module YaKassa
2
+ module V3
3
+ class Router
4
+ ENDPOINT='https://payment.yandex.net/api/v3/'
5
+ PATH = {
6
+ payments: 'payments',
7
+ refunds: 'refunds',
8
+ receipts: 'receipts'
9
+ }
10
+
11
+ def initialize(params = {})
12
+ @params = params
13
+ end
14
+
15
+ def payment_url
16
+ "#{ENDPOINT}#{PATH[:payments]}"
17
+ end
18
+
19
+ def payment_status_url
20
+ "#{ENDPOINT}#{PATH[:payments]}/#{@params[:payment_id]}"
21
+ end
22
+
23
+ def payment_confirmation_url
24
+ "#{ENDPOINT}#{PATH[:payments]}/#{@params[:payment_id]}/capture"
25
+ end
26
+
27
+ def payment_cancel_url
28
+ "#{ENDPOINT}#{PATH[:payments]}/#{@params[:payment_id]}/cancel"
29
+ end
30
+
31
+ def refund_url
32
+ "#{ENDPOINT}#{PATH[:refunds]}"
33
+ end
34
+
35
+ def receipt_url
36
+ "#{ENDPOINT}#{PATH[:receipts]}"
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,46 @@
1
+ module YaKassa
2
+ module V3
3
+ module Validators
4
+ class Base
5
+ attr_reader :error, :name, :value
6
+
7
+ def initialize(name, value, params = {})
8
+ @name = name
9
+ @value = value
10
+ @params = params
11
+ @error = nil
12
+ @is_validated = false
13
+ end
14
+
15
+ def validate
16
+ @error = error_msg unless condition
17
+ @is_validated = true
18
+ nil
19
+ end
20
+
21
+ def valid?
22
+ unless @is_validated
23
+ msg = "#{self.class.name}. Need to run #validate method before call #valid?"
24
+ Rails.logger.info(msg)
25
+ return nil
26
+ end
27
+ @error.blank?
28
+ end
29
+
30
+ private
31
+
32
+ def not_implemented_method
33
+ raise 'Method is not implemented'
34
+ end
35
+
36
+ def condition
37
+ not_implemented_method
38
+ end
39
+
40
+ def error_msg
41
+ not_implemented_method
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,17 @@
1
+ module YaKassa
2
+ module V3
3
+ module Validators
4
+ class FloatOrNil < Base
5
+ private
6
+
7
+ def condition
8
+ value.is_a?(Float) || value.nil?
9
+ end
10
+
11
+ def error_msg
12
+ "Should be present"
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module YaKassa
2
+ module V3
3
+ module Validators
4
+ class IsA < Base
5
+ private
6
+
7
+ def condition
8
+ value.is_a?(is_a_class)
9
+ end
10
+
11
+ def error_msg
12
+ "Should be #{is_a_class}"
13
+ end
14
+
15
+ def is_a_class
16
+ @params[:class].constantize
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ module YaKassa
2
+ module V3
3
+ module Validators
4
+ class IsABoolean < Base
5
+ private
6
+
7
+ def condition
8
+ value.is_a?(TrueClass) || value.is_a?(FalseClass)
9
+ end
10
+
11
+ def error_msg
12
+ "Should be Boolean"
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module YaKassa
2
+ module V3
3
+ module Validators
4
+ class Present < Base
5
+ private
6
+
7
+ def condition
8
+ value.present?
9
+ end
10
+
11
+ def error_msg
12
+ "Should be present"
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,3 +1,3 @@
1
1
  module YaKassa
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ya_kassa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - nikulinaleksandr
@@ -70,6 +70,28 @@ files:
70
70
  - bin/console
71
71
  - bin/setup
72
72
  - lib/ya_kassa.rb
73
+ - lib/ya_kassa/v3/base_request.rb
74
+ - lib/ya_kassa/v3/base_response.rb
75
+ - lib/ya_kassa/v3/client/base.rb
76
+ - lib/ya_kassa/v3/client/get.rb
77
+ - lib/ya_kassa/v3/client/post.rb
78
+ - lib/ya_kassa/v3/concerns/attributable.rb
79
+ - lib/ya_kassa/v3/concerns/validatable.rb
80
+ - lib/ya_kassa/v3/payment_cancel_request.rb
81
+ - lib/ya_kassa/v3/payment_capture_request.rb
82
+ - lib/ya_kassa/v3/payment_request.rb
83
+ - lib/ya_kassa/v3/payment_response.rb
84
+ - lib/ya_kassa/v3/payment_status_request.rb
85
+ - lib/ya_kassa/v3/receipt_request.rb
86
+ - lib/ya_kassa/v3/receipt_response.rb
87
+ - lib/ya_kassa/v3/refund_request.rb
88
+ - lib/ya_kassa/v3/refund_response.rb
89
+ - lib/ya_kassa/v3/router.rb
90
+ - lib/ya_kassa/v3/validators/base.rb
91
+ - lib/ya_kassa/v3/validators/float_or_nil.rb
92
+ - lib/ya_kassa/v3/validators/is_a.rb
93
+ - lib/ya_kassa/v3/validators/is_a_boolean.rb
94
+ - lib/ya_kassa/v3/validators/present.rb
73
95
  - lib/ya_kassa/version.rb
74
96
  - ya_kassa.gemspec
75
97
  homepage: http://github.com/niksan/ya_kassa