cloud_payments 0.0.2 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +12 -6
  3. data/Gemfile +2 -2
  4. data/README.md +88 -5
  5. data/Rakefile +1 -0
  6. data/cloud_payments.gemspec +8 -8
  7. data/config.ru +1 -0
  8. data/lib/cloud_payments.rb +6 -1
  9. data/lib/cloud_payments/client.rb +3 -2
  10. data/lib/cloud_payments/client/errors.rb +1 -0
  11. data/lib/cloud_payments/client/gateway_errors.rb +3 -1
  12. data/lib/cloud_payments/client/response.rb +2 -1
  13. data/lib/cloud_payments/client/serializer.rb +1 -0
  14. data/lib/cloud_payments/client/serializer/base.rb +9 -1
  15. data/lib/cloud_payments/client/serializer/multi_json.rb +1 -0
  16. data/lib/cloud_payments/config.rb +4 -0
  17. data/lib/cloud_payments/models.rb +8 -0
  18. data/lib/cloud_payments/models/like_subscription.rb +30 -0
  19. data/lib/cloud_payments/models/model.rb +9 -0
  20. data/lib/cloud_payments/models/on_fail.rb +31 -0
  21. data/lib/cloud_payments/models/on_kassa_receipt.rb +23 -0
  22. data/lib/cloud_payments/models/on_pay.rb +37 -0
  23. data/lib/cloud_payments/models/on_recurrent.rb +22 -0
  24. data/lib/cloud_payments/models/order.rb +14 -0
  25. data/lib/cloud_payments/models/secure3d.rb +1 -0
  26. data/lib/cloud_payments/models/subscription.rb +9 -32
  27. data/lib/cloud_payments/models/transaction.rb +13 -4
  28. data/lib/cloud_payments/namespaces.rb +12 -1
  29. data/lib/cloud_payments/namespaces/base.rb +2 -1
  30. data/lib/cloud_payments/namespaces/cards.rb +6 -0
  31. data/lib/cloud_payments/namespaces/kassa.rb +22 -0
  32. data/lib/cloud_payments/namespaces/orders.rb +15 -0
  33. data/lib/cloud_payments/namespaces/payments.rb +11 -0
  34. data/lib/cloud_payments/namespaces/subscriptions.rb +6 -0
  35. data/lib/cloud_payments/namespaces/tokens.rb +1 -0
  36. data/lib/cloud_payments/version.rb +2 -1
  37. data/lib/cloud_payments/webhooks.rb +42 -0
  38. data/spec/cloud_payments/client/response_spec.rb +3 -1
  39. data/spec/cloud_payments/client/serializer/multi_json_spec.rb +1 -0
  40. data/spec/cloud_payments/models/order_spec.rb +62 -0
  41. data/spec/cloud_payments/models/secure3d_spec.rb +1 -0
  42. data/spec/cloud_payments/models/subscription_spec.rb +1 -1
  43. data/spec/cloud_payments/models/transaction_spec.rb +25 -1
  44. data/spec/cloud_payments/namespaces/base_spec.rb +10 -3
  45. data/spec/cloud_payments/namespaces/cards_spec.rb +42 -2
  46. data/spec/cloud_payments/namespaces/kassa_spec.rb +43 -0
  47. data/spec/cloud_payments/namespaces/orders_spec.rb +57 -0
  48. data/spec/cloud_payments/namespaces/payments_spec.rb +119 -0
  49. data/spec/cloud_payments/namespaces/subscriptions_spec.rb +21 -1
  50. data/spec/cloud_payments/namespaces/tokens_spec.rb +1 -0
  51. data/spec/cloud_payments/namespaces_spec.rb +2 -1
  52. data/spec/cloud_payments/webhooks_spec.rb +272 -0
  53. data/spec/cloud_payments_spec.rb +27 -4
  54. data/spec/fixtures/apis/cards/post3ds/failed.yml +45 -0
  55. data/spec/fixtures/apis/cards/post3ds/successful.yml +48 -0
  56. data/spec/fixtures/apis/orders/cancel/failed.yml +6 -0
  57. data/spec/fixtures/apis/orders/cancel/successful.yml +6 -0
  58. data/spec/fixtures/apis/orders/create/successful.yml +20 -0
  59. data/spec/fixtures/apis/payments/find/failed.yml +45 -0
  60. data/spec/fixtures/apis/payments/find/failed_with_message.yml +6 -0
  61. data/spec/fixtures/apis/payments/find/successful.yml +48 -0
  62. data/spec/fixtures/apis/payments/get/failed.yml +46 -0
  63. data/spec/fixtures/apis/payments/get/failed_with_message.yml +6 -0
  64. data/spec/fixtures/apis/payments/get/refunded.yml +49 -0
  65. data/spec/fixtures/apis/payments/get/successful.yml +49 -0
  66. data/spec/fixtures/apis/subscriptions/find/successful.yml +4 -4
  67. data/spec/fixtures/apis/subscriptions/get/successful.yml +31 -0
  68. data/spec/spec_helper.rb +13 -24
  69. data/spec/support/examples.rb +1 -0
  70. data/spec/support/helpers.rb +3 -2
  71. metadata +62 -34
  72. data/spec/cloud_payments/client_spec.rb +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 02f3745fb8ba27279fbc61b8457ea085e80a423e
4
- data.tar.gz: df63c5180c52eb51cfc4a59e009b428cc6b6c3bd
2
+ SHA256:
3
+ metadata.gz: '059f78713c51718c2fcc7474fe7e734b82dbf19a67b121ed86d3210caf061136'
4
+ data.tar.gz: 18c43e72122e00f883e41c0261ef614da2d2dd5474a68e1eb771c1b35bf8aa9b
5
5
  SHA512:
6
- metadata.gz: 52aea99410e9b050a7ed070e9b5642dba502fafa12a4ff034450aa74e319cf1f6767aa38f70399b42b466650da0896599ce234c843cc3eb37e884b657cd30605
7
- data.tar.gz: 2f8a19f58a38a67a62aa691b36382f3d23f67d9edee409f7d8d126eb840cc125f8fd81ad30daed3bc54e24526161655b74de76f3d6e8b51cbff17252e67a0fde
6
+ metadata.gz: a2071a9837d7c2545e0d0df976a964139cba78b85de31af0af556fb6b3335030ceda26ffc38be9aed7f553b67c6d0a6b3e1f21004680bbeeb5baaad0184759ce
7
+ data.tar.gz: 90c91193460f99b13aff8b04a9c4e325f118b44e99cec44ea33f1a668aa0dfd8afd7281d5481b4e15022c5b7208fb729c1f0b7d15776226139be4cce5c46ab99
@@ -1,8 +1,14 @@
1
1
  language: ruby
2
- env:
3
- - CODECLIMATE_REPO_TOKEN=8e9b89269d9aafc2dec2706a43825201de496b743505d7a7666068f7b22b07d
2
+
4
3
  rvm:
5
- - 1.9.3
6
- - 2.0.0
7
- - 2.1.3
8
- - rbx-2
4
+ - 2.3
5
+ - 2.4
6
+ - 2.5
7
+ - 2.6
8
+ - 2.7
9
+
10
+ cache: bundler
11
+
12
+ before_install: gem install bundler
13
+
14
+ script: bundle exec rspec
data/Gemfile CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  source 'https://rubygems.org'
2
3
 
3
4
  # Specify your gem's dependencies in cloud_payments.gemspec
@@ -6,5 +7,4 @@ gemspec
6
7
  gem 'oj'
7
8
  gem 'pry'
8
9
  gem 'rack'
9
- gem 'webmock', require: 'webmock/rspec'
10
- gem "codeclimate-test-reporter", group: :test, require: nil
10
+ gem 'webmock'
data/README.md CHANGED
@@ -1,10 +1,8 @@
1
1
  # CloudPayments
2
2
 
3
- CloudPayments ruby client (http://cloudpayments.eu/Docs/Integration)
3
+ CloudPayments ruby client (https://developers.cloudpayments.ru/en/)
4
4
 
5
- [![Build Status](https://travis-ci.org/undr/cloud_payments.svg)](https://travis-ci.org/undr/cloud_payments)
6
- [![Code Climate](https://codeclimate.com/github/undr/cloud_payments/badges/gpa.svg)](https://codeclimate.com/github/undr/cloud_payments)
7
- [![Test Coverage](https://codeclimate.com/github/undr/cloud_payments/badges/coverage.svg)](https://codeclimate.com/github/undr/cloud_payments)
5
+ [![Build Status](https://travis-ci.org/platmart/cloud_payments.svg)](https://travis-ci.org/platmart/cloud_payments)
8
6
 
9
7
  ## Installation
10
8
 
@@ -30,6 +28,8 @@ $ gem install cloud_payments
30
28
 
31
29
  ### Configuration
32
30
 
31
+ #### Global configuration
32
+
33
33
  ```ruby
34
34
  CloudPayments.configure do |c|
35
35
  c.host = 'http://localhost:3000' # By default, it is https://api.cloudpayments.ru
@@ -39,6 +39,28 @@ CloudPayments.configure do |c|
39
39
  c.logger = Logger.new('/dev/null') # By default, it writes logs to stdout
40
40
  c.raise_banking_errors = true # By default, it is not raising banking errors
41
41
  end
42
+
43
+ # API client
44
+ CloudPayments.client.payments.cards.charge(...)
45
+
46
+ # Webhooks
47
+ CloudPayments.webhooks.on_pay(...)
48
+ ```
49
+
50
+ #### Local configuration
51
+
52
+ ```ruby
53
+ config = CloudPayments::Config.new do |c|
54
+ # ...
55
+ end
56
+
57
+ # API client
58
+ client = CloudPayments::Client.new(config)
59
+ client.payments.cards.charge(...)
60
+
61
+ # Webhooks
62
+ webhooks = CloudPayments::Webhooks.new(config)
63
+ webhooks.on_pay(...)
42
64
  ```
43
65
 
44
66
  ### Test method
@@ -83,6 +105,7 @@ transaction = CloudPayments.client.payments.cards.charge(
83
105
  # :card_last_four=>"1111",
84
106
  # :card_type=>"Visa",
85
107
  # :card_type_code=>0,
108
+ # :issuer=>"Sberbank of Russia",
86
109
  # :issuer_bank_country=>"RU",
87
110
  # :status=>"Completed",
88
111
  # :status_code=>3,
@@ -97,9 +120,69 @@ transaction.token
97
120
  # => "a4e67841-abb0-42de-a364-d1d8f9f4b3c0"
98
121
  ```
99
122
 
123
+ ## Kassa Receipt
124
+
125
+ CloudPayments Kassa API (https://cloudpayments.ru/docs/api/kassa)
126
+
127
+ ```ruby
128
+ CloudPayments.client.kassa.receipt({
129
+ account_id: "user@example.com",
130
+ customer_receipt: {
131
+ items: [
132
+ {
133
+ amount: "13350.00",
134
+ ean13: nil,
135
+ label: "Good Description",
136
+ price: "13350.00",
137
+ quantity: 1.0,
138
+ vat: nil
139
+ }
140
+ ]
141
+ },
142
+ inn: "7708806666",
143
+ invoice_id: "231312312",
144
+ type: "Income"
145
+ })
146
+ ```
147
+
148
+ ## Webhooks
149
+
150
+ ```ruby
151
+ if CloudPayments.webhooks.data_valid?(payload, hmac_token)
152
+ event = CloudPayments.webhooks.on_recurrent(payload)
153
+ # or
154
+ event = CloudPayments.webhooks.on_pay(payload)
155
+ # or
156
+ event = CloudPayments.webhooks.on_fail(payload)
157
+ end
158
+ ```
159
+
160
+ with capturing of an exception
161
+
162
+ ```ruby
163
+ rescue_from CloudPayments::Webhooks::HMACError, :handle_hmac_error
164
+
165
+ before_action -> { CloudPayments.webhooks.validate_data!(payload, hmac_token) }
166
+
167
+ def pay
168
+ event = CloudPayments.webhooks.on_pay(payload)
169
+ # ...
170
+ end
171
+
172
+ def fail
173
+ event = CloudPayments.webhooks.on_fail(payload)
174
+ # ...
175
+ end
176
+
177
+ def recurrent
178
+ event = CloudPayments.webhooks.on_recurrent(payload)
179
+ # ...
180
+ end
181
+ ```
182
+
100
183
  ## Contributing
101
184
 
102
- 1. Fork it ( https://github.com/undr/cloud_payments/fork )
185
+ 1. Fork it ( https://github.com/platmart/cloud_payments/fork )
103
186
  2. Create your feature branch (`git checkout -b my-new-feature`)
104
187
  3. Commit your changes (`git commit -am 'Add some feature'`)
105
188
  4. Push to the branch (`git push origin my-new-feature`)
data/Rakefile CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'bundler/gem_tasks'
2
3
  require 'rspec/core/rake_task'
3
4
 
@@ -1,4 +1,5 @@
1
1
  # coding: utf-8
2
+ # frozen_string_literal: true
2
3
  lib = File.expand_path('../lib', __FILE__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'cloud_payments/version'
@@ -6,11 +7,11 @@ require 'cloud_payments/version'
6
7
  Gem::Specification.new do |spec|
7
8
  spec.name = 'cloud_payments'
8
9
  spec.version = CloudPayments::VERSION
9
- spec.authors = ['undr']
10
- spec.email = ['undr@yandex.ru']
10
+ spec.authors = ['undr', 'kirillplatonov']
11
+ spec.email = ['undr@yandex.ru', 'mail@kirillplatonov.com']
11
12
  spec.summary = %q{CloudPayments ruby client}
12
13
  spec.description = %q{CloudPayments ruby client}
13
- spec.homepage = ''
14
+ spec.homepage = 'https://github.com/platmart/cloud_payments'
14
15
  spec.license = 'MIT'
15
16
 
16
17
  spec.files = `git ls-files -z`.split("\x0")
@@ -19,10 +20,9 @@ Gem::Specification.new do |spec|
19
20
  spec.require_paths = ['lib']
20
21
 
21
22
  spec.add_dependency 'faraday'
22
- spec.add_dependency 'multi_json'
23
- spec.add_dependency 'hashie'
23
+ spec.add_dependency 'multi_json', '~> 1.11'
24
+ spec.add_dependency 'hashie', '~> 3.4'
24
25
 
25
- spec.add_development_dependency 'bundler', '~> 1.7'
26
- spec.add_development_dependency 'rake', '~> 10.0'
27
- spec.add_development_dependency 'rspec'
26
+ spec.add_development_dependency 'rake', '~> 13.0'
27
+ spec.add_development_dependency 'rspec', '~> 3.9'
28
28
  end
data/config.ru CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
3
  require 'cloud_payments'
3
4
  require 'rack'
@@ -1,13 +1,14 @@
1
+ # frozen_string_literal: true
1
2
  require 'date'
2
3
  require 'hashie'
3
4
  require 'faraday'
4
5
  require 'multi_json'
5
- require 'pp'
6
6
  require 'cloud_payments/version'
7
7
  require 'cloud_payments/config'
8
8
  require 'cloud_payments/namespaces'
9
9
  require 'cloud_payments/models'
10
10
  require 'cloud_payments/client'
11
+ require 'cloud_payments/webhooks'
11
12
 
12
13
  module CloudPayments
13
14
  extend self
@@ -31,4 +32,8 @@ module CloudPayments
31
32
  def client
32
33
  @client ||= Client.new
33
34
  end
35
+
36
+ def webhooks
37
+ @webhooks ||= Webhooks.new
38
+ end
34
39
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'cloud_payments/client/errors'
2
3
  require 'cloud_payments/client/gateway_errors'
3
4
  require 'cloud_payments/client/response'
@@ -9,8 +10,8 @@ module CloudPayments
9
10
 
10
11
  attr_reader :config, :connection
11
12
 
12
- def initialize
13
- @config = CloudPayments.config
13
+ def initialize(config = nil)
14
+ @config = config || CloudPayments.config
14
15
  @connection = build_connection
15
16
  end
16
17
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module CloudPayments
2
3
  class Client
3
4
  class Error < StandardError; end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
1
2
  module CloudPayments
2
3
  class Client
4
+ class ReasonedGatewayError < StandardError; end
3
5
  module GatewayErrors; end
4
6
 
5
7
  REASON_CODES = {
@@ -29,7 +31,7 @@ module CloudPayments
29
31
 
30
32
  GATEWAY_ERRORS = REASON_CODES.inject({}) do |result, error|
31
33
  status, name = error
32
- result[status] = GatewayErrors.const_set(name, Class.new(StandardError))
34
+ result[status] = GatewayErrors.const_set(name, Class.new(ReasonedGatewayError))
33
35
  result
34
36
  end
35
37
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module CloudPayments
2
3
  class Client
3
4
  class Response
@@ -5,7 +6,7 @@ module CloudPayments
5
6
 
6
7
  def initialize(status, body, headers = {})
7
8
  @status, @origin_body, @headers = status, body, headers
8
- @origin_body = body.force_encoding('UTF-8') if body.respond_to?(:force_encoding)
9
+ @origin_body = body.dup.force_encoding('UTF-8') if body.respond_to?(:force_encoding)
9
10
  end
10
11
 
11
12
  def body
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'cloud_payments/client/serializer/base'
2
3
  require 'cloud_payments/client/serializer/multi_json'
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module CloudPayments
2
3
  class Client
3
4
  module Serializer
@@ -20,7 +21,14 @@ module CloudPayments
20
21
 
21
22
  def convert_keys_from_api(attributes)
22
23
  attributes.each_with_object({}) do |(key, value), result|
23
- value = convert_keys_from_api(value) if value.is_a?(Hash)
24
+ value = case value
25
+ when Hash
26
+ convert_keys_from_api(value)
27
+ when Array
28
+ value.map { |item| convert_keys_from_api(item) }
29
+ else
30
+ value
31
+ end
24
32
 
25
33
  key = key.to_s.gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
26
34
  key.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module CloudPayments
2
3
  class Client
3
4
  module Serializer
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module CloudPayments
2
3
  class Config
3
4
  attr_accessor :connection_options, :serializer, :log, :public_key, :secret_key, :host, :raise_banking_errors
@@ -17,6 +18,9 @@ module CloudPayments
17
18
  @connection_options = {}
18
19
  @connection_block = nil
19
20
  @host = 'https://api.cloudpayments.ru'
21
+ if block_given?
22
+ yield self
23
+ end
20
24
  end
21
25
 
22
26
  def logger
@@ -1,4 +1,12 @@
1
+ # frozen_string_literal: true
1
2
  require 'cloud_payments/models/model'
3
+ require 'cloud_payments/models/like_subscription'
2
4
  require 'cloud_payments/models/secure3d'
3
5
  require 'cloud_payments/models/transaction'
4
6
  require 'cloud_payments/models/subscription'
7
+ require 'cloud_payments/models/order'
8
+
9
+ require 'cloud_payments/models/on_recurrent'
10
+ require 'cloud_payments/models/on_pay'
11
+ require 'cloud_payments/models/on_fail'
12
+ require 'cloud_payments/models/on_kassa_receipt'
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+ module CloudPayments
3
+ module LikeSubscription
4
+ ACTIVE = 'Active'
5
+ PAST_DUE = 'PastDue'
6
+ CANCELLED = 'Cancelled'
7
+ REJECTED = 'Rejected'
8
+ EXPIRED = 'Expired'
9
+
10
+ def active?
11
+ status == ACTIVE
12
+ end
13
+
14
+ def past_due?
15
+ status == PAST_DUE
16
+ end
17
+
18
+ def cancelled?
19
+ status == CANCELLED
20
+ end
21
+
22
+ def rejected?
23
+ status == REJECTED
24
+ end
25
+
26
+ def expired?
27
+ status == EXPIRED
28
+ end
29
+ end
30
+ end
@@ -1,5 +1,14 @@
1
+ # frozen_string_literal: true
2
+ require 'bigdecimal'
3
+ require 'bigdecimal/util'
4
+
1
5
  module CloudPayments
2
6
  class Model < Hashie::Trash
3
7
  include Hashie::Extensions::IgnoreUndeclared
8
+
9
+ DateTimeTransform = ->(v) { DateTime.parse(v) if v && v.respond_to?(:to_s) }
10
+ DecimalTransform = ->(v) { v.to_d if v }
11
+ IntegralTransform = ->(v) { v.to_i if v }
12
+ BooleanTransform = ->(v) { (v == '0') ? false : !!v }
4
13
  end
5
14
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+ module CloudPayments
3
+ # @see https://cloudpayments.ru/Docs/Notifications#fail CloudPayments API
4
+ class OnFail < Model
5
+ property :id, from: :transaction_id, required: true
6
+ property :amount, transform_with: DecimalTransform, required: true
7
+ property :currency, required: true
8
+ property :date_time, transform_with: DateTimeTransform
9
+ property :card_first_six, required: true
10
+ property :card_last_four, required: true
11
+ property :card_type, required: true
12
+ property :card_exp_date, required: true
13
+ property :test_mode, required: true
14
+ property :reason, required: true
15
+ property :reason_code, required: true
16
+ property :invoice_id
17
+ property :account_id
18
+ property :subscription_id
19
+ property :name
20
+ property :email
21
+ property :ip_address
22
+ property :ip_country
23
+ property :ip_city
24
+ property :ip_region
25
+ property :ip_district
26
+ property :issuer
27
+ property :issuer_bank_country
28
+ property :description
29
+ property :metadata, from: :data, default: {}
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+ module CloudPayments
3
+ # @see https://cloudpayments.ru/Docs/Notifications#receipt CloudPayments API
4
+ class OnKassaReceipt < Model
5
+ property :id, required: true
6
+ property :document_number, required: true
7
+ property :session_number, required: true
8
+ property :fiscal_sign, required: true
9
+ property :device_number, required: true
10
+ property :reg_number, required: true
11
+ property :inn, required: true
12
+ property :type, required: true
13
+ property :ofd, required: true
14
+ property :url, required: true
15
+ property :qr_code_url, required: true
16
+ property :amount, transform_with: DecimalTransform, required: true
17
+ property :date_time, transform_with: DateTimeTransform
18
+ property :receipt
19
+ property :invoice_id
20
+ property :transaction_id
21
+ property :account_id
22
+ end
23
+ end