cloud_payments 0.0.2 → 0.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 02f3745fb8ba27279fbc61b8457ea085e80a423e
4
- data.tar.gz: df63c5180c52eb51cfc4a59e009b428cc6b6c3bd
3
+ metadata.gz: 9e65806150df505158679b9614835f31235eb91d
4
+ data.tar.gz: fb0bbe75f1d804547b4eef7fa4f6e3ec72f65a94
5
5
  SHA512:
6
- metadata.gz: 52aea99410e9b050a7ed070e9b5642dba502fafa12a4ff034450aa74e319cf1f6767aa38f70399b42b466650da0896599ce234c843cc3eb37e884b657cd30605
7
- data.tar.gz: 2f8a19f58a38a67a62aa691b36382f3d23f67d9edee409f7d8d126eb840cc125f8fd81ad30daed3bc54e24526161655b74de76f3d6e8b51cbff17252e67a0fde
6
+ metadata.gz: ebc7f7442b275344048f833e615f889abfb38a1253a06e10199a328835447cf3d076d7a2af3263174461963cbcef1ae8549a9d499d606ccf09652b1486d2bd6b
7
+ data.tar.gz: 8bb8fe1362062a6ba1cb73cdfc43a845ff80519380b2be392cc19a0dd738e5d7af529d190bbbfe9fdfc766e8a7555707741695d185a29784d55b5c949b842621
data/.travis.yml CHANGED
@@ -1,8 +1,17 @@
1
1
  language: ruby
2
+ sudo: false
3
+ cache: bundler
4
+ script: bundle exec rspec
2
5
  env:
3
6
  - CODECLIMATE_REPO_TOKEN=8e9b89269d9aafc2dec2706a43825201de496b743505d7a7666068f7b22b07d
4
7
  rvm:
5
- - 1.9.3
6
- - 2.0.0
7
- - 2.1.3
8
+ - '1.9.3'
9
+ - '2.0'
10
+ - '2.1'
11
+ - '2.2'
12
+ - '2.3.0'
8
13
  - rbx-2
14
+ - ruby-head
15
+ matrix:
16
+ allow_failures:
17
+ - rvm: ruby-head
data/Gemfile CHANGED
@@ -7,4 +7,4 @@ gem 'oj'
7
7
  gem 'pry'
8
8
  gem 'rack'
9
9
  gem 'webmock', require: 'webmock/rspec'
10
- gem "codeclimate-test-reporter", group: :test, require: nil
10
+ gem "codeclimate-test-reporter", group: :test, require: nil
data/README.md CHANGED
@@ -97,6 +97,41 @@ transaction.token
97
97
  # => "a4e67841-abb0-42de-a364-d1d8f9f4b3c0"
98
98
  ```
99
99
 
100
+ ## Webhooks
101
+
102
+ ```ruby
103
+ if CloudPayments.webhooks.data_valid?(payload, hmac_token)
104
+ event = CloudPayments.webhooks.on_recurrent(payload)
105
+ # or
106
+ event = CloudPayments.webhooks.on_pay(payload)
107
+ # or
108
+ event = CloudPayments.webhooks.on_fail(payload)
109
+ end
110
+ ```
111
+
112
+ with capturing of an exception
113
+
114
+ ```ruby
115
+ rescue_from CloudPayments::Webhooks::HMACError, :handle_hmac_error
116
+
117
+ before_action -> { CloudPayments.webhooks.validate_data!(payload, hmac_token) }
118
+
119
+ def pay
120
+ event = CloudPayments.webhooks.on_pay(payload)
121
+ # ...
122
+ end
123
+
124
+ def fail
125
+ event = CloudPayments.webhooks.on_fail(payload)
126
+ # ...
127
+ end
128
+
129
+ def recurrent
130
+ event = CloudPayments.webhooks.on_recurrent(payload)
131
+ # ...
132
+ end
133
+ ```
134
+
100
135
  ## Contributing
101
136
 
102
137
  1. Fork it ( https://github.com/undr/cloud_payments/fork )
@@ -18,11 +18,10 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency 'faraday'
22
- spec.add_dependency 'multi_json'
23
- spec.add_dependency 'hashie'
21
+ spec.add_dependency 'faraday', '~> 0.9.2'
22
+ spec.add_dependency 'multi_json', '~> 1.11'
23
+ spec.add_dependency 'hashie', '~> 3.4'
24
24
 
25
- spec.add_development_dependency 'bundler', '~> 1.7'
26
25
  spec.add_development_dependency 'rake', '~> 10.0'
27
- spec.add_development_dependency 'rspec'
26
+ spec.add_development_dependency 'rspec', '~> 3.4'
28
27
  end
@@ -8,6 +8,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,4 +1,10 @@
1
1
  require 'cloud_payments/models/model'
2
+ require 'cloud_payments/models/like_subscription'
2
3
  require 'cloud_payments/models/secure3d'
3
4
  require 'cloud_payments/models/transaction'
4
5
  require 'cloud_payments/models/subscription'
6
+ require 'cloud_payments/models/order'
7
+
8
+ require 'cloud_payments/models/on_recurrent'
9
+ require 'cloud_payments/models/on_pay'
10
+ require 'cloud_payments/models/on_fail'
@@ -0,0 +1,29 @@
1
+ module CloudPayments
2
+ module LikeSubscription
3
+ ACTIVE = 'Active'
4
+ PAST_DUE = 'PastDue'
5
+ CANCELLED = 'Cancelled'
6
+ REJECTED = 'Rejected'
7
+ EXPIRED = 'Expired'
8
+
9
+ def active?
10
+ status == ACTIVE
11
+ end
12
+
13
+ def past_due?
14
+ status == PAST_DUE
15
+ end
16
+
17
+ def cancelled?
18
+ status == CANCELLED
19
+ end
20
+
21
+ def rejected?
22
+ status == REJECTED
23
+ end
24
+
25
+ def expired?
26
+ status == EXPIRED
27
+ end
28
+ end
29
+ end
@@ -1,5 +1,13 @@
1
+ require 'bigdecimal'
2
+ require 'bigdecimal/util'
3
+
1
4
  module CloudPayments
2
5
  class Model < Hashie::Trash
3
6
  include Hashie::Extensions::IgnoreUndeclared
7
+
8
+ DateTimeTransform = ->(v) { DateTime.parse(v) if v && v.respond_to?(:to_s) }
9
+ DecimalTransform = ->(v) { v.to_d if v }
10
+ IntegralTransform = ->(v) { v.to_i if v }
11
+ BooleanTransform = ->(v) { (v == '0') ? false : !!v }
4
12
  end
5
13
  end
@@ -0,0 +1,29 @@
1
+ module CloudPayments
2
+ # @see https://cloudpayments.ru/Docs/Notifications#fail CloudPayments API
3
+ class OnFail < Model
4
+ property :id, from: :transaction_id, required: true
5
+ property :amount, transform_with: DecimalTransform, required: true
6
+ property :currency, required: true
7
+ property :date_time, transform_with: DateTimeTransform
8
+ property :card_first_six, required: true
9
+ property :card_last_four, required: true
10
+ property :card_type, required: true
11
+ property :card_exp_date, required: true
12
+ property :test_mode, required: true
13
+ property :reason, required: true
14
+ property :reason_code, required: true
15
+ property :invoice_id
16
+ property :account_id
17
+ property :subscription_id
18
+ property :name
19
+ property :email
20
+ property :ip_address
21
+ property :ip_country
22
+ property :ip_city
23
+ property :ip_region
24
+ property :ip_district
25
+ property :issuer_bank_country
26
+ property :description
27
+ property :metadata, from: :data, default: {}
28
+ end
29
+ end
@@ -0,0 +1,35 @@
1
+ module CloudPayments
2
+ class OnPay < Model
3
+ property :id, from: :transaction_id, required: true
4
+ property :amount, transform_with: DecimalTransform, required: true
5
+ property :currency, required: true
6
+ property :invoice_id
7
+ property :account_id
8
+ property :subscription_id
9
+ property :email
10
+ property :description
11
+ property :metadata, from: :data, default: {}
12
+ property :date_time, transform_with: DateTimeTransform
13
+ property :auth_code
14
+ property :test_mode, required: true
15
+ property :ip_address
16
+ property :ip_country
17
+ property :ip_city
18
+ property :ip_region
19
+ property :ip_district
20
+ property :ip_lat, from: :ip_latitude
21
+ property :ip_lng, from: :ip_longitude
22
+ property :card_first_six, required: true
23
+ property :card_last_four, required: true
24
+ property :card_type, required: true
25
+ property :card_type_code
26
+ property :card_exp_date
27
+ property :name
28
+ property :issuer_bank_country
29
+ property :status, required: true
30
+ property :status_code
31
+ property :reason
32
+ property :reason_code
33
+ property :token
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ module CloudPayments
2
+ class OnRecurrent < Model
3
+ property :id, required: true
4
+ property :account_id, required: true
5
+ property :description, required: true
6
+ property :email, required: true
7
+ property :amount, transform_with: DecimalTransform, required: true
8
+ property :currency, required: true
9
+ property :require_confirmation, transform_with: BooleanTransform, required: true
10
+ property :started_at, from: :start_date, with: DateTimeTransform, required: true
11
+ property :interval, required: true
12
+ property :period, transform_with: IntegralTransform, required: true
13
+ property :status, required: true
14
+ property :successful_transactions, from: :successful_transactions_number, with: IntegralTransform, required: true
15
+ property :failed_transactions, from: :failed_transactions_number, with: IntegralTransform, required: true
16
+ property :last_transaction_at, from: :last_transaction_date, with: DateTimeTransform
17
+ property :next_transaction_at, from: :next_transaction_date, with: DateTimeTransform
18
+
19
+ include LikeSubscription
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ module CloudPayments
2
+ class Order < Model
3
+ property :id, required: true
4
+ property :number, required: true
5
+ property :amount, transform_with: DecimalTransform, required: true
6
+ property :currency, required: true
7
+ property :currency_code, required: true
8
+ property :email
9
+ property :description, required: true
10
+ property :require_confirmation, transform_with: BooleanTransform, required: true
11
+ property :url, required: true
12
+ end
13
+ end
@@ -1,49 +1,25 @@
1
1
  module CloudPayments
2
2
  class Subscription < Model
3
- ACTIVE = 'Active'
4
- PAST_DUE = 'PastDue'
5
- CANCELLED = 'Cancelled'
6
- REJECTED = 'Rejected'
7
- EXPIRED = 'Expired'
3
+ include LikeSubscription
8
4
 
9
5
  property :id, required: true
10
6
  property :account_id, required: true
11
7
  property :description, required: true
12
8
  property :email, required: true
13
- property :amount, required: true
9
+ property :amount, transform_with: DecimalTransform, required: true
14
10
  property :currency, required: true
15
11
  property :currency_code, required: true
16
- property :require_confirmation, required: true
17
- property :started_at, from: :start_date_iso, with: ->(v){ DateTime.parse(v) if v }, required: true
12
+ property :require_confirmation, transform_with: BooleanTransform, required: true
13
+ property :started_at, from: :start_date_iso, with: DateTimeTransform, required: true
18
14
  property :interval, required: true
19
15
  property :interval_code, required: true
20
- property :period, required: true
16
+ property :period, transform_with: IntegralTransform, required: true
21
17
  property :max_periods
22
18
  property :status, required: true
23
19
  property :status_code, required: true
24
20
  property :successful_transactions, from: :successful_transactions_number, required: true
25
21
  property :failed_transactions, from: :failed_transactions_number, required: true
26
- property :last_transaction_at, from: :last_transaction_date_iso, with: ->(v){ DateTime.parse(v) if v }
27
- property :next_transaction_at, from: :next_transaction_date_iso, with: ->(v){ DateTime.parse(v) if v }
28
-
29
- def active?
30
- status == ACTIVE
31
- end
32
-
33
- def past_due?
34
- status == PAST_DUE
35
- end
36
-
37
- def cancelled?
38
- status == CANCELLED
39
- end
40
-
41
- def rejected?
42
- status == REJECTED
43
- end
44
-
45
- def expired?
46
- status == EXPIRED
47
- end
22
+ property :last_transaction_at, from: :last_transaction_date_iso, with: DateTimeTransform
23
+ property :next_transaction_at, from: :next_transaction_date_iso, with: DateTimeTransform
48
24
  end
49
25
  end
@@ -16,10 +16,10 @@ module CloudPayments
16
16
  property :email
17
17
  property :description
18
18
  property :metadata, from: :json_data, default: {}
19
- property :date_time, transform_with: ->(v){ DateTime.parse(v) if v }
20
- property :created_at, from: :created_date_iso, with: ->(v){ DateTime.parse(v) if v }
21
- property :authorized_at, from: :auth_date_iso, with: ->(v){ DateTime.parse(v) if v }
22
- property :confirmed_at, from: :confirm_date_iso, with: ->(v){ DateTime.parse(v) if v }
19
+ property :date_time, transform_with: DateTimeTransform
20
+ property :created_at, from: :created_date_iso, with: DateTimeTransform
21
+ property :authorized_at, from: :auth_date_iso, with: DateTimeTransform
22
+ property :confirmed_at, from: :confirm_date_iso, with: DateTimeTransform
23
23
  property :auth_code
24
24
  property :test_mode, required: true
25
25
  property :ip_address
@@ -3,6 +3,7 @@ require 'cloud_payments/namespaces/cards'
3
3
  require 'cloud_payments/namespaces/tokens'
4
4
  require 'cloud_payments/namespaces/payments'
5
5
  require 'cloud_payments/namespaces/subscriptions'
6
+ require 'cloud_payments/namespaces/orders'
6
7
 
7
8
  module CloudPayments
8
9
  module Namespaces
@@ -14,6 +15,10 @@ module CloudPayments
14
15
  Subscriptions.new(self)
15
16
  end
16
17
 
18
+ def orders
19
+ Orders.new(self)
20
+ end
21
+
17
22
  def ping
18
23
  !!(perform_request('/test').body || {})[:success]
19
24
  rescue ::Faraday::Error::ConnectionFailed, ::Faraday::Error::TimeoutError, CloudPayments::Client::ServerError => e
@@ -0,0 +1,10 @@
1
+ module CloudPayments
2
+ module Namespaces
3
+ class Orders < Base
4
+ def create(attributes)
5
+ response = request(:create, attributes)
6
+ Order.new(response[:model])
7
+ end
8
+ end
9
+ end
10
+ end
@@ -1,3 +1,3 @@
1
1
  module CloudPayments
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
@@ -0,0 +1,37 @@
1
+ require 'openssl'
2
+ require 'base64'
3
+
4
+ module CloudPayments
5
+ class Webhooks
6
+ class HMACError < StandardError; end
7
+
8
+ attr_reader :config
9
+
10
+ def initialize
11
+ @config = CloudPayments.config
12
+ @digest = OpenSSL::Digest.new('sha256')
13
+ @serializer = Client::Serializer::Base.new(config)
14
+ end
15
+
16
+ def data_valid?(data, hmac)
17
+ Base64.decode64(hmac) == OpenSSL::HMAC.digest(@digest, config.secret_key, data)
18
+ end
19
+
20
+ def validate_data!(data, hmac)
21
+ raise HMACError unless data_valid?(data, hmac)
22
+ true
23
+ end
24
+
25
+ def on_recurrent(data)
26
+ OnRecurrent.new(@serializer.load(data))
27
+ end
28
+
29
+ def on_pay(data)
30
+ OnPay.new(@serializer.load(data))
31
+ end
32
+
33
+ def on_fail(data)
34
+ OnFail.new(@serializer.load(data))
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ require 'spec_helper'
4
+
5
+ describe CloudPayments::Order do
6
+ subject{ described_class.new(attributes) }
7
+
8
+ let(:attributes) do
9
+ {
10
+ id: 'f2K8LV6reGE9WBFn',
11
+ number: 61,
12
+ amount: 10.0,
13
+ currency: 'RUB',
14
+ currency_code: 0,
15
+ email: 'client@test.local',
16
+ description: 'Оплата на сайте example.com',
17
+ require_confirmation: true,
18
+ url:'https://orders.cloudpayments.ru/d/f2K8LV6reGE9WBFn'
19
+ }
20
+ end
21
+
22
+ describe 'properties' do
23
+ specify{ expect(subject.id).to eq('f2K8LV6reGE9WBFn') }
24
+ specify{ expect(subject.number).to eq(61) }
25
+ specify{ expect(subject.amount).to eq(10.0) }
26
+ specify{ expect(subject.currency).to eq('RUB') }
27
+ specify{ expect(subject.currency_code).to eq(0) }
28
+ specify{ expect(subject.email).to eq('client@test.local') }
29
+ specify{ expect(subject.description).to eq('Оплата на сайте example.com') }
30
+ specify{ expect(subject.require_confirmation).to eq(true) }
31
+ specify{ expect(subject.url).to eq('https://orders.cloudpayments.ru/d/f2K8LV6reGE9WBFn') }
32
+
33
+ it_behaves_like :raise_without_attribute, :id
34
+ it_behaves_like :raise_without_attribute, :number
35
+ it_behaves_like :raise_without_attribute, :amount
36
+ it_behaves_like :raise_without_attribute, :currency
37
+ it_behaves_like :raise_without_attribute, :currency_code
38
+ it_behaves_like :raise_without_attribute, :description
39
+ it_behaves_like :raise_without_attribute, :require_confirmation
40
+ it_behaves_like :raise_without_attribute, :url
41
+
42
+ it_behaves_like :not_raise_without_attribute, :email
43
+ end
44
+
45
+ describe 'transformations' do
46
+ context 'amount from string' do
47
+ before { attributes[:amount] = '293.42' }
48
+ specify{ expect(subject.amount).to eql(293.42) }
49
+ end
50
+
51
+ context 'require_confirmation from "1"' do
52
+ before { attributes[:require_confirmation] = '1' }
53
+ specify{ expect(subject.require_confirmation).to eql(true) }
54
+ end
55
+
56
+ context 'require_confirmation from "0"' do
57
+ before { attributes[:require_confirmation] = '0' }
58
+ specify{ expect(subject.require_confirmation).to eql(false) }
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ require 'spec_helper'
4
+
5
+ describe CloudPayments::Namespaces::Orders do
6
+ subject{ described_class.new(CloudPayments.client) }
7
+
8
+ describe '#create' do
9
+ let(:attributes) do
10
+ {
11
+ amount: 10.0,
12
+ currency: 'RUB',
13
+ description: 'Оплата на сайте example.com',
14
+ email: 'client@test.local',
15
+ require_confirmation: true,
16
+ send_email: false,
17
+ invoice_id: 'invoice_100',
18
+ account_id: 'account_200',
19
+ phone: '+7(495)765-4321',
20
+ send_sms: false,
21
+ send_whats_app: false
22
+ }
23
+ end
24
+
25
+ context do
26
+ before{ stub_api_request('orders/create/successful').perform }
27
+
28
+ specify{ expect(subject.create(attributes)).to be_instance_of(CloudPayments::Order) }
29
+
30
+ context do
31
+ let(:sub){ subject.create(attributes) }
32
+
33
+ specify{ expect(sub.id).to eq('f2K8LV6reGE9WBFn') }
34
+ specify{ expect(sub.amount).to eq(10.0) }
35
+ specify{ expect(sub.currency).to eq('RUB') }
36
+ specify{ expect(sub.currency_code).to eq(0) }
37
+ specify{ expect(sub.email).to eq('client@test.local') }
38
+ specify{ expect(sub.description).to eq('Оплата на сайте example.com') }
39
+ specify{ expect(sub.require_confirmation).to eq(true) }
40
+ specify{ expect(sub.url).to eq('https://orders.cloudpayments.ru/d/f2K8LV6reGE9WBFn') }
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,229 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ require 'spec_helper'
4
+
5
+ describe CloudPayments::Webhooks do
6
+ describe 'HMAC validation' do
7
+ let(:valid_hmac) { 'tJW02TMAce4Em8eJTNqjhOax+BYRM5K2D8mX9xsmUUc=' }
8
+ let(:invalid_hmac) { '6sUXv4W0wmhfpkkDtp+3Hw/M8deAPkMRVV3OWANcqro=' }
9
+ let(:data) {
10
+ "TransactionId=666&Amount=123.00&Currency=RUB&PaymentAmount=123.00&PaymentCurrency=RUB&InvoiceId=1234567&AccountId=user%40example.com&SubscriptionId=&Name=VLADIMIR+KOCHNEV&Email=user%40example.com&DateTime=2015-11-17+14%3a51%3a20&IpAddress=127.0.0.1&IpCountry=RU&IpCity=%d0%a1%d0%b0%d0%bd%d0%ba%d1%82-%d0%9f%d0%b5%d1%82%d0%b5%d1%80%d0%b1%d1%83%d1%80%d0%b3&IpRegion=%d0%a1%d0%b0%d0%bd%d0%ba%d1%82-%d0%9f%d0%b5%d1%82%d0%b5%d1%80%d0%b1%d1%83%d1%80%d0%b3&IpDistrict=%d0%a1%d0%b5%d0%b2%d0%b5%d1%80%d0%be-%d0%97%d0%b0%d0%bf%d0%b0%d0%b4%d0%bd%d1%8b%d0%b9+%d1%84%d0%b5%d0%b4%d0%b5%d1%80%d0%b0%d0%bb%d1%8c%d0%bd%d1%8b%d0%b9+%d0%be%d0%ba%d1%80%d1%83%d0%b3&IpLatitude=59.939000&IpLongitude=30.315800&CardFirstSix=411111&CardLastFour=1111&CardType=Visa&CardExpDate=01%2f19&Issuer=&IssuerBankCountry=&Description=%d0%9e%d0%bf%d0%bb%d0%b0%d1%82%d0%b0+%d0%b2+example.com&AuthCode=DEADBEEF&Token=1234567890&TestMode=1&Status=Completed"
11
+ }
12
+
13
+ context 'with data_valid?' do
14
+ it 'returns true on valid hmac' do
15
+ expect(CloudPayments.webhooks.data_valid?(data, valid_hmac)).to be_truthy
16
+ end
17
+
18
+ it 'returns false on invalid hmac' do
19
+ expect(CloudPayments.webhooks.data_valid?(data, invalid_hmac)).to be_falsey
20
+ end
21
+ end
22
+
23
+ context 'with validate_data!' do
24
+ it 'returns true on valid hmac' do
25
+ expect(CloudPayments.webhooks.validate_data!(data, valid_hmac)).to be_truthy
26
+ end
27
+
28
+ it 'raises a HMACError on invalid hmac' do
29
+ expect {
30
+ CloudPayments.webhooks.validate_data!(data, invalid_hmac)
31
+ }.to raise_error(CloudPayments::Webhooks::HMACError)
32
+ end
33
+ end
34
+ end
35
+
36
+ describe 'on_check' do
37
+ let(:raw_data) do
38
+ {"TransactionId"=>"1701609",
39
+ "Amount"=>"123.00",
40
+ "Currency"=>"RUB",
41
+ "PaymentAmount"=>"123.00",
42
+ "PaymentCurrency"=>"RUB",
43
+ "InvoiceId"=>"1234567",
44
+ "AccountId"=>"user@example.com",
45
+ "SubscriptionId"=>"",
46
+ "Name"=>"OLEG FOMIN",
47
+ "Email"=>"user@example.com",
48
+ "DateTime"=>"2015-11-17 23:06:15",
49
+ "IpAddress"=>"127.0.0.1",
50
+ "IpCountry"=>"RU",
51
+ "IpCity"=>"Санкт-Петербург",
52
+ "IpRegion"=>"Санкт-Петербург",
53
+ "IpDistrict"=>"Северо-Западный федеральный округ",
54
+ "IpLatitude"=>"59.939000",
55
+ "IpLongitude"=>"30.315000",
56
+ "CardFirstSix"=>"411111",
57
+ "CardLastFour"=>"1111",
58
+ "CardType"=>"Visa",
59
+ "CardExpDate"=>"01/19",
60
+ "Issuer"=>"",
61
+ "IssuerBankCountry"=>"",
62
+ "Description"=>"Оплата в example.com",
63
+ "TestMode"=>"1",
64
+ "Status"=>"Completed",
65
+ "Data"=>
66
+ "{\"cloudPayments\":{\"recurrent\":{\"interval\":\"Month\",\"period\":1}}}"}
67
+ end
68
+
69
+ subject { CloudPayments.webhooks.on_check(raw_data) }
70
+ end
71
+
72
+ describe 'on_pay' do
73
+ let(:raw_data) do
74
+ {"TransactionId"=>"1701609",
75
+ "Amount"=>"123.00",
76
+ "Currency"=>"RUB",
77
+ "PaymentAmount"=>"123.00",
78
+ "PaymentCurrency"=>"RUB",
79
+ "InvoiceId"=>"1234567",
80
+ "AccountId"=>"user@example.com",
81
+ "SubscriptionId"=>"sc_b865df3d4f27c54dc8067520c071a",
82
+ "Name"=>"OLEG FOMIN",
83
+ "Email"=>"user@example.com",
84
+ "DateTime"=>"2015-11-17 23:06:17",
85
+ "IpAddress"=>"127.0.0.1",
86
+ "IpCountry"=>"RU",
87
+ "IpCity"=>"Санкт-Петербург",
88
+ "IpRegion"=>"Санкт-Петербург",
89
+ "IpDistrict"=>"Северо-Западный федеральный округ",
90
+ "IpLatitude"=>"59.939037",
91
+ "IpLongitude"=>"30.315784",
92
+ "CardFirstSix"=>"411111",
93
+ "CardLastFour"=>"1111",
94
+ "CardType"=>"Visa",
95
+ "CardExpDate"=>"01/19",
96
+ "Issuer"=>"",
97
+ "IssuerBankCountry"=>"",
98
+ "Description"=>"Оплата в example.com",
99
+ "AuthCode"=>"A1B2C3",
100
+ "Token"=>"9BBEF19476623CA56C17DA75FD57734DBF82530686043A6E491C6D71BEFE8F6E",
101
+ "TestMode"=>"1",
102
+ "Status"=>"Completed",
103
+ "Data"=>
104
+ "{\"cloudPayments\":{\"recurrent\":{\"interval\":\"Month\",\"period\":1}}}"}
105
+ end
106
+
107
+ subject { CloudPayments.webhooks.on_pay(raw_data) }
108
+
109
+ specify { expect(subject.id).to eq '1701609' }
110
+ specify { expect(subject.amount).to eq 123.00 }
111
+ specify { expect(subject.currency).to eq 'RUB' }
112
+ specify { expect(subject.invoice_id).to eq '1234567' }
113
+ specify { expect(subject.account_id).to eq 'user@example.com' }
114
+ specify { expect(subject.subscription_id).to eq 'sc_b865df3d4f27c54dc8067520c071a' }
115
+ specify { expect(subject.name).to eq 'OLEG FOMIN' }
116
+ specify { expect(subject.email).to eq 'user@example.com' }
117
+ specify { expect(subject.date_time).to eq DateTime.parse('2015-11-17 23:06:17') }
118
+ specify { expect(subject.ip_address).to eq '127.0.0.1' }
119
+ specify { expect(subject.ip_country).to eq 'RU' }
120
+ specify { expect(subject.ip_city).to eq 'Санкт-Петербург' }
121
+ specify { expect(subject.ip_region).to eq 'Санкт-Петербург' }
122
+ specify { expect(subject.ip_district).to eq 'Северо-Западный федеральный округ' }
123
+ specify { expect(subject.ip_lat).to eq '59.939037' }
124
+ specify { expect(subject.ip_lng).to eq '30.315784' }
125
+ specify { expect(subject.card_first_six).to eq '411111' }
126
+ specify { expect(subject.card_last_four).to eq '1111' }
127
+ specify { expect(subject.card_type).to eq 'Visa' }
128
+ specify { expect(subject.card_exp_date).to eq '01/19' }
129
+ specify { expect(subject.description).to eq 'Оплата в example.com' }
130
+ specify { expect(subject.auth_code).to eq 'A1B2C3' }
131
+ specify { expect(subject.token).to eq '9BBEF19476623CA56C17DA75FD57734DBF82530686043A6E491C6D71BEFE8F6E' }
132
+ specify { expect(subject.status).to eq 'Completed' }
133
+ end
134
+
135
+ describe 'on_fail' do
136
+ let(:raw_data) do
137
+ {"TransactionId"=>"1701658",
138
+ "Amount"=>"123.00",
139
+ "Currency"=>"RUB",
140
+ "PaymentAmount"=>"123.00",
141
+ "PaymentCurrency"=>"RUB",
142
+ "InvoiceId"=>"1234567",
143
+ "AccountId"=>"user@example.com",
144
+ "SubscriptionId"=>"",
145
+ "Name"=>"OLEG FOMIN",
146
+ "Email"=>"user@example.com",
147
+ "DateTime"=>"2015-11-17 23:35:09",
148
+ "IpAddress"=>"127.0.0.1",
149
+ "IpCountry"=>"RU",
150
+ "IpCity"=>"Санкт-Петербург",
151
+ "IpRegion"=>"Санкт-Петербург",
152
+ "IpDistrict"=>"Северо-Западный федеральный округ",
153
+ "IpLatitude"=>"59.939037",
154
+ "IpLongitude"=>"30.315784",
155
+ "CardFirstSix"=>"400005",
156
+ "CardLastFour"=>"5556",
157
+ "CardType"=>"Visa",
158
+ "CardExpDate"=>"01/19",
159
+ "Issuer"=>"",
160
+ "IssuerBankCountry"=>"",
161
+ "Description"=>"Оплата в example.com",
162
+ "TestMode"=>"1",
163
+ "Status"=>"Declined",
164
+ "StatusCode"=>"5",
165
+ "Reason"=>"InsufficientFunds",
166
+ "ReasonCode"=>"5051",
167
+ "Data"=>
168
+ "{\"cloudPayments\":{\"recurrent\":{\"interval\":\"Month\",\"period\":1}}}"}
169
+ end
170
+
171
+ subject { CloudPayments.webhooks.on_fail(raw_data) }
172
+
173
+ specify { expect(subject.id).to eq '1701658' }
174
+ specify { expect(subject.amount).to eq 123.00 }
175
+ specify { expect(subject.currency).to eq 'RUB' }
176
+ specify { expect(subject.invoice_id).to eq '1234567' }
177
+ specify { expect(subject.account_id).to eq 'user@example.com' }
178
+ specify { expect(subject.subscription_id).to eq '' }
179
+ specify { expect(subject.name).to eq 'OLEG FOMIN' }
180
+ specify { expect(subject.email).to eq 'user@example.com' }
181
+ specify { expect(subject.date_time).to eq DateTime.parse('2015-11-17 23:35:09') }
182
+ specify { expect(subject.ip_address).to eq '127.0.0.1' }
183
+ specify { expect(subject.ip_country).to eq 'RU' }
184
+ specify { expect(subject.ip_city).to eq 'Санкт-Петербург' }
185
+ specify { expect(subject.ip_region).to eq 'Санкт-Петербург' }
186
+ specify { expect(subject.ip_district).to eq 'Северо-Западный федеральный округ' }
187
+ specify { expect(subject.card_first_six).to eq '400005' }
188
+ specify { expect(subject.card_last_four).to eq '5556' }
189
+ specify { expect(subject.card_type).to eq 'Visa' }
190
+ specify { expect(subject.card_exp_date).to eq '01/19' }
191
+ specify { expect(subject.description).to eq 'Оплата в example.com' }
192
+ end
193
+
194
+ describe 'on_recurrent' do
195
+ let(:raw_data) do
196
+ {"Id"=>"sc_a38ca02005d40db7d32b36a0097b0",
197
+ "AccountId"=>"1234",
198
+ "Description"=>"just description",
199
+ "Email"=>"user@example.com",
200
+ "Amount"=>"2.00",
201
+ "Currency"=>"RUB",
202
+ "RequireConfirmation"=>"0",
203
+ "StartDate"=>"2015-12-17 20:22:14",
204
+ "Interval"=>"Month",
205
+ "Period"=>"1",
206
+ "Status"=>"PastDue",
207
+ "SuccessfulTransactionsNumber"=>"11",
208
+ "FailedTransactionsNumber"=>"22",
209
+ "NextTransactionDate"=>"2015-11-18 20:29:05"}
210
+ end
211
+
212
+ subject { CloudPayments.webhooks.on_recurrent(raw_data) }
213
+
214
+ specify { expect(subject.id).to eq 'sc_a38ca02005d40db7d32b36a0097b0' }
215
+ specify { expect(subject.account_id).to eq '1234' }
216
+ specify { expect(subject.description).to eq 'just description' }
217
+ specify { expect(subject.email).to eq 'user@example.com' }
218
+ specify { expect(subject.amount).to eq 2.00 }
219
+ specify { expect(subject.currency).to eq 'RUB' }
220
+ specify { expect(subject.require_confirmation).to eq false }
221
+ specify { expect(subject.started_at).to eq DateTime.parse('2015-12-17 20:22:14') }
222
+ specify { expect(subject.interval).to eq 'Month' }
223
+ specify { expect(subject.period).to eq 1 }
224
+ specify { expect(subject.status).to eq 'PastDue' }
225
+ specify { expect(subject.successful_transactions).to eq 11 }
226
+ specify { expect(subject.failed_transactions).to eq 22 }
227
+ specify { expect(subject.next_transaction_at).to eq DateTime.parse('2015-11-18 20:29:05') }
228
+ end
229
+ end
@@ -0,0 +1,20 @@
1
+ ---
2
+ :request:
3
+ :url: '/orders/create'
4
+ :body: '{"Amount":10.0,"Currency":"RUB","Description":"Оплата на сайте example.com","Email":"client@test.local","RequireConfirmation":true,"SendEmail":false,"InvoiceId":"invoice_100","AccountId":"account_200","Phone":"+7(495)765-4321","SendSms":false,"SendWhatsApp":false}'
5
+ :response:
6
+ :body: >
7
+ {
8
+ "Model":{
9
+ "Id":"f2K8LV6reGE9WBFn",
10
+ "Number":61,
11
+ "Amount":10.0,
12
+ "Currency":"RUB",
13
+ "CurrencyCode":0,
14
+ "Email":"client@test.local",
15
+ "Description":"Оплата на сайте example.com",
16
+ "RequireConfirmation":true,
17
+ "Url":"https://orders.cloudpayments.ru/d/f2K8LV6reGE9WBFn"
18
+ },
19
+ "Success":true
20
+ }
metadata CHANGED
@@ -1,71 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloud_payments
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - undr
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-19 00:00:00.000000000 Z
11
+ date: 2016-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 0.9.2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: 0.9.2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: multi_json
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '1.11'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '1.11'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: hashie
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: bundler
57
43
  requirement: !ruby/object:Gem::Requirement
58
44
  requirements:
59
45
  - - "~>"
60
46
  - !ruby/object:Gem::Version
61
- version: '1.7'
62
- type: :development
47
+ version: '3.4'
48
+ type: :runtime
63
49
  prerelease: false
64
50
  version_requirements: !ruby/object:Gem::Requirement
65
51
  requirements:
66
52
  - - "~>"
67
53
  - !ruby/object:Gem::Version
68
- version: '1.7'
54
+ version: '3.4'
69
55
  - !ruby/object:Gem::Dependency
70
56
  name: rake
71
57
  requirement: !ruby/object:Gem::Requirement
@@ -84,16 +70,16 @@ dependencies:
84
70
  name: rspec
85
71
  requirement: !ruby/object:Gem::Requirement
86
72
  requirements:
87
- - - ">="
73
+ - - "~>"
88
74
  - !ruby/object:Gem::Version
89
- version: '0'
75
+ version: '3.4'
90
76
  type: :development
91
77
  prerelease: false
92
78
  version_requirements: !ruby/object:Gem::Requirement
93
79
  requirements:
94
- - - ">="
80
+ - - "~>"
95
81
  - !ruby/object:Gem::Version
96
- version: '0'
82
+ version: '3.4'
97
83
  description: CloudPayments ruby client
98
84
  email:
99
85
  - undr@yandex.ru
@@ -120,29 +106,39 @@ files:
120
106
  - lib/cloud_payments/client/serializer/multi_json.rb
121
107
  - lib/cloud_payments/config.rb
122
108
  - lib/cloud_payments/models.rb
109
+ - lib/cloud_payments/models/like_subscription.rb
123
110
  - lib/cloud_payments/models/model.rb
111
+ - lib/cloud_payments/models/on_fail.rb
112
+ - lib/cloud_payments/models/on_pay.rb
113
+ - lib/cloud_payments/models/on_recurrent.rb
114
+ - lib/cloud_payments/models/order.rb
124
115
  - lib/cloud_payments/models/secure3d.rb
125
116
  - lib/cloud_payments/models/subscription.rb
126
117
  - lib/cloud_payments/models/transaction.rb
127
118
  - lib/cloud_payments/namespaces.rb
128
119
  - lib/cloud_payments/namespaces/base.rb
129
120
  - lib/cloud_payments/namespaces/cards.rb
121
+ - lib/cloud_payments/namespaces/orders.rb
130
122
  - lib/cloud_payments/namespaces/payments.rb
131
123
  - lib/cloud_payments/namespaces/subscriptions.rb
132
124
  - lib/cloud_payments/namespaces/tokens.rb
133
125
  - lib/cloud_payments/version.rb
126
+ - lib/cloud_payments/webhooks.rb
134
127
  - spec/cloud_payments/client/response_spec.rb
135
128
  - spec/cloud_payments/client/serializer/multi_json_spec.rb
136
129
  - spec/cloud_payments/client_spec.rb
130
+ - spec/cloud_payments/models/order_spec.rb
137
131
  - spec/cloud_payments/models/secure3d_spec.rb
138
132
  - spec/cloud_payments/models/subscription_spec.rb
139
133
  - spec/cloud_payments/models/transaction_spec.rb
140
134
  - spec/cloud_payments/namespaces/base_spec.rb
141
135
  - spec/cloud_payments/namespaces/cards_spec.rb
136
+ - spec/cloud_payments/namespaces/orders_spec.rb
142
137
  - spec/cloud_payments/namespaces/payments_spec.rb
143
138
  - spec/cloud_payments/namespaces/subscriptions_spec.rb
144
139
  - spec/cloud_payments/namespaces/tokens_spec.rb
145
140
  - spec/cloud_payments/namespaces_spec.rb
141
+ - spec/cloud_payments/webhooks_spec.rb
146
142
  - spec/cloud_payments_spec.rb
147
143
  - spec/fixtures/apis/cards/auth/failed.yml
148
144
  - spec/fixtures/apis/cards/auth/secure3d.yml
@@ -150,6 +146,7 @@ files:
150
146
  - spec/fixtures/apis/cards/charge/failed.yml
151
147
  - spec/fixtures/apis/cards/charge/secure3d.yml
152
148
  - spec/fixtures/apis/cards/charge/successful.yml
149
+ - spec/fixtures/apis/orders/create/successful.yml
153
150
  - spec/fixtures/apis/payments/confirm/failed.yml
154
151
  - spec/fixtures/apis/payments/confirm/failed_with_message.yml
155
152
  - spec/fixtures/apis/payments/confirm/successful.yml
@@ -194,7 +191,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
191
  version: '0'
195
192
  requirements: []
196
193
  rubyforge_project:
197
- rubygems_version: 2.4.3
194
+ rubygems_version: 2.4.8
198
195
  signing_key:
199
196
  specification_version: 4
200
197
  summary: CloudPayments ruby client
@@ -202,15 +199,18 @@ test_files:
202
199
  - spec/cloud_payments/client/response_spec.rb
203
200
  - spec/cloud_payments/client/serializer/multi_json_spec.rb
204
201
  - spec/cloud_payments/client_spec.rb
202
+ - spec/cloud_payments/models/order_spec.rb
205
203
  - spec/cloud_payments/models/secure3d_spec.rb
206
204
  - spec/cloud_payments/models/subscription_spec.rb
207
205
  - spec/cloud_payments/models/transaction_spec.rb
208
206
  - spec/cloud_payments/namespaces/base_spec.rb
209
207
  - spec/cloud_payments/namespaces/cards_spec.rb
208
+ - spec/cloud_payments/namespaces/orders_spec.rb
210
209
  - spec/cloud_payments/namespaces/payments_spec.rb
211
210
  - spec/cloud_payments/namespaces/subscriptions_spec.rb
212
211
  - spec/cloud_payments/namespaces/tokens_spec.rb
213
212
  - spec/cloud_payments/namespaces_spec.rb
213
+ - spec/cloud_payments/webhooks_spec.rb
214
214
  - spec/cloud_payments_spec.rb
215
215
  - spec/fixtures/apis/cards/auth/failed.yml
216
216
  - spec/fixtures/apis/cards/auth/secure3d.yml
@@ -218,6 +218,7 @@ test_files:
218
218
  - spec/fixtures/apis/cards/charge/failed.yml
219
219
  - spec/fixtures/apis/cards/charge/secure3d.yml
220
220
  - spec/fixtures/apis/cards/charge/successful.yml
221
+ - spec/fixtures/apis/orders/create/successful.yml
221
222
  - spec/fixtures/apis/payments/confirm/failed.yml
222
223
  - spec/fixtures/apis/payments/confirm/failed_with_message.yml
223
224
  - spec/fixtures/apis/payments/confirm/successful.yml