payonline 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
  SHA1:
3
- metadata.gz: ffecc72ab316af139858d166bad9f2f061fee703
4
- data.tar.gz: e37aa7b384f956ab5a019081a9a8da21efbe042d
3
+ metadata.gz: 4eeed6efaf2e7fdf7739e8ffce53c6d490a43407
4
+ data.tar.gz: 8ae885feb0eafc060bebf8c39dd39f730b11cd03
5
5
  SHA512:
6
- metadata.gz: 73e84b51ee88012b49eb71a948b7676a285dcc1a7000a0d1d5bd0ae9b81ce9432f6d01af43dde8933516dbefc2c6986442e5edf079e24fcca7bf72b53265f0b6
7
- data.tar.gz: fa5ad0967fc1ed6b014ea35140332bfb9f89f5a2ec1496aeb3e22b97306aa9bec0a024fd4ea3111f3db45d8037e484b88dd54ac26b7f64ae2bc85677044e3f39
6
+ metadata.gz: 04328df7d7d41d4528fdf46456cce0e6d4707e0ab6398d0210a3ac785a0af96a435530d6a57110144d78692a194316f849600528b19616aa6ad082a33c392040
7
+ data.tar.gz: 0489c355b5f137c6015d5000fa6185bbcce0bd031c65a31acb10b7f74910536e5cce539b21746944eea9d22e222ab2c16e05a67fb0164fc1b06e60a2d049870c
data/.hound.yml ADDED
@@ -0,0 +1,2 @@
1
+ ruby:
2
+ config_file: .rubocop.yml
data/.rubocop.yml ADDED
@@ -0,0 +1,16 @@
1
+ Metrics/LineLength:
2
+ Max: 100
3
+ Documentation:
4
+ Enabled: false
5
+ NumericLiterals:
6
+ Enabled: false
7
+ ClassAndModuleChildren:
8
+ Enabled: false
9
+ SingleLineBlockParams:
10
+ Enabled: false
11
+ FrozenStringLiteralComment:
12
+ Enabled: false
13
+ MutableConstant:
14
+ Enabled: false
15
+ MultilineMethodCallIndentation:
16
+ EnforcedStyle: indented
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  ## Payonline
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/payonline.svg)](http://badge.fury.io/rb/payonline) [![Code Climate](https://codeclimate.com/github/yuri-zubov/payonline/badges/gpa.svg)](https://codeclimate.com/github/yuri-zubov/payonline)
4
+
3
5
  This is a thin wrapper library that makes using PayOnline API a bit easier.
4
6
 
5
7
  ## Installation
@@ -18,37 +20,40 @@ $ bundle
18
20
 
19
21
  ## Configuring
20
22
 
21
- Create initialize file. This file is usually located at /config/initializers/payonline.rb
23
+ Create an initializer: `config/initializers/payonline.rb`:
24
+
22
25
  ```ruby
23
- Payonline.config do |c|
24
- c.merchant_id = '12345'
25
- c.private_security_key = '3844908d-4c2a-42e1-9be0-91bb5d068d22'
26
- c.return_url = 'http://you_domain/payments/success'
27
- c.fail_url = 'http://you_domain/payments/failed'
26
+ Payonline.config do |config|
27
+ config.merchant_id = '12345'
28
+ config.private_security_key = 'your-private-security-key'
29
+ config.return_url = 'https://example.com/payments/success'
30
+ config.fail_url = 'https://example.com/payments/fail'
28
31
  end
29
32
  ```
30
33
 
31
34
  ## Usage
32
35
 
33
- Get payment link
36
+ Get payment URL:
34
37
 
35
38
  ```ruby
36
- Payonline::PaymentGateway.new(order_id: 56789, amount: 9.99 , currency: 'USD').get_payment_url
39
+ Payonline::PaymentGateway.new(order_id: 1, amount: 2.0, currency: 'RUB').payment_url
37
40
  ```
38
41
 
39
- Check Call-back
42
+ Implement a callback action that will be called by PayOnline after a transaction is completed:
43
+
40
44
  ```ruby
41
- @paymant_response = Payonline::PaymentResponse.new(prms)
42
- if paymant_response.valid_payment?
43
- Order.find(@paymant_response.order_id).pay
44
- end
45
+ @response = Payonline::PaymentResponse.new(params)
46
+
47
+ if @response.valid_payment?
48
+ Order.find(@response.order_id).set_paid!
49
+ end
45
50
  ```
46
51
 
47
52
  ## Contributing
48
53
 
49
54
  1. Fork it
50
- 2. Clone it `git clone http://github.com/path/to/your/fork`
55
+ 2. Clone it `git clone https://github.com/SumatoSoft/payonline`
51
56
  3. Create your feature branch `git checkout -b my-new-feature`
52
- 4. Commit your changes `git commit -am 'Add some feature`
57
+ 4. Commit your changes `git commit -am 'Add some feature'`
53
58
  5. Push to the branch `git push origin my-new-feature`
54
59
  6. Create new pull request through Github
data/Rakefile CHANGED
@@ -1 +1 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
@@ -1,70 +1,44 @@
1
1
  module Payonline
2
2
  class PaymentGateway
3
- class Params < SimpleDelegator
4
-
5
- REQUIED_PARAMS = %w(order_id amount currency valid_until order_description return_url fail_url return_url)
6
-
7
- def initialize(params)
8
- @params = prepare_params(params)
9
-
10
- filter_params
11
-
12
- __setobj__ @params
13
- end
14
-
15
- def to_query
16
- @params.each_with_object({}) do |(k, v), params|
17
- params[k.camelize] = v
18
- end.to_query
19
- end
20
-
21
- private
22
-
23
- def prepare_params(params)
24
- params[:amount] = '%.2f' % params[:amount]
25
-
26
- default_params = { return_url: return_url, fail_url: fail_url }
27
- params.merge(default_params)
28
- end
29
-
30
- def filter_params
31
- @params.select! { |k, v| REQUIED_PARAMS.include?(k) && v }
32
- end
33
-
34
- def return_url
35
- @return_url ||= Payonline.configuration.return_url
36
- end
37
-
38
- def fail_url
39
- @fail_url ||= Payonline.configuration.fail_url
40
- end
41
- end
3
+ BASE_URL = 'https://secure.payonlinesystem.com'
42
4
 
43
5
  SIGNED_PARAMS = %w(order_id amount currency valid_until order_description)
44
-
45
- def initialize(params={})
46
- @params = Params.new(params.with_indifferent_access)
6
+ PERMITTED_PARAMS = %w(
7
+ order_id amount currency valid_until order_description return_url fail_url
8
+ )
9
+
10
+ PAYMENT_TYPE_URL = {
11
+ qiwi: 'select/qiwi/',
12
+ webmoney: 'select/webmoney/',
13
+ yandexmoney: 'select/yandexmoney/',
14
+ masterpass: 'select/masterpass/'
15
+ }
16
+
17
+ def initialize(params = {})
18
+ @params = prepare_params(params)
47
19
  end
48
20
 
49
- def get_payment_url(type = 'card')
50
- params = Payonline::Signature.sign_params(@params, SIGNED_PARAMS)
21
+ def payment_url(type: :card, language: :ru)
22
+ params = Payonline::Signature.new(@params, SIGNED_PARAMS).sign
51
23
 
52
- "#{url_by_kind_of_payment(type)}?#{params.to_query}"
24
+ "#{BASE_URL}/#{language}/payment/#{PAYMENT_TYPE_URL[type]}?#{params.to_query}"
53
25
  end
54
26
 
55
27
  private
56
28
 
57
- def url_by_kind_of_payment(type, language = 'ru')
58
- case type.to_s
59
- when 'qiwi'
60
- "https://secure.payonlinesystem.com/#{language}/payment/select/qiwi/"
61
- when 'webmoney'
62
- "https://secure.payonlinesystem.com/#{language}/payment/select/webmoney/"
63
- when 'yandexmoney'
64
- "https://secure.payonlinesystem.com/#{language}/payment/select/webmoney/"
65
- when 'card'
66
- "https://secure.payonlinesystem.com/#{language}/payment/"
67
- end
29
+ def prepare_params(params)
30
+ params
31
+ .with_indifferent_access
32
+ .slice(*PERMITTED_PARAMS)
33
+ .merge(default_params){ |_, important, _| important }
34
+ .merge(amount: format('%.2f', params[:amount]))
35
+ end
36
+
37
+ def default_params
38
+ {
39
+ return_url: Payonline.configuration.return_url,
40
+ fail_url: Payonline.configuration.fail_url
41
+ }
68
42
  end
69
43
  end
70
44
  end
@@ -2,31 +2,28 @@ module Payonline
2
2
  class PaymentResponse
3
3
  extend Forwardable
4
4
 
5
- attr_accessor :response, :params
5
+ attr_accessor :data, :params
6
6
 
7
- RESPONSE_PARAMS = %w(date_time transaction_id order_id amount currency)
7
+ SIGNED_PARAMS = %i(date_time transaction_id order_id amount currency)
8
8
 
9
- def_delegators :params, *RESPONSE_PARAMS
9
+ def_delegators :data, *SIGNED_PARAMS
10
10
 
11
- def initialize(response = {})
12
- self.response = response
13
- self.params = OpenStruct.new(normalize_params)
11
+ def initialize(params = {})
12
+ @params = prepare_params(params)
13
+ @data = OpenStruct.new(@params)
14
14
  end
15
15
 
16
16
  def valid_payment?
17
- keys = RESPONSE_PARAMS.each_with_object([]).each do |key, array|
18
- array << response.keys.select{ |e| e.underscore == key }.first
19
- end
20
-
21
- params.security_key == Payonline::Signature.digest(response, keys)
17
+ keys = SIGNED_PARAMS.select { |key| @params.key?(key) }
18
+ @params[:security_key] == Payonline::Signature.new(@params, keys, false).digest
22
19
  end
23
20
 
24
21
  private
25
22
 
26
- def normalize_params
27
- result = response.each_with_object({}) do |(k, v), params|
28
- params[k.underscore] = v
29
- end.with_indifferent_access
23
+ def prepare_params(params)
24
+ params
25
+ .transform_keys { |key| key.to_s.underscore }
26
+ .with_indifferent_access
30
27
  end
31
28
  end
32
29
  end
@@ -0,0 +1,40 @@
1
+ module Payonline
2
+ class RebillGateway
3
+ SIGNED_PARAMS = %w(rebill_anchor order_id amount currency)
4
+ PERMITTED_PARAMS = %w(rebill_anchor order_id amount currency)
5
+ BASE_URL = 'https://secure.payonlinesystem.com'
6
+
7
+ def initialize(params = {})
8
+ @params = prepare_params(params)
9
+ end
10
+
11
+ # Perform the rebill operation and return the response
12
+ def rebill
13
+ response = HTTParty.get(rebill_url)
14
+ return false unless response.success?
15
+
16
+ Payonline::RebillResponse.new(response.body).success?
17
+ end
18
+
19
+ # Return the URL without performing a request
20
+ def rebill_url
21
+ params = Payonline::Signature.new(@params, SIGNED_PARAMS).sign
22
+
23
+ "#{BASE_URL}/payment/transaction/rebill/?#{params.to_query}"
24
+ end
25
+
26
+ private
27
+
28
+ def prepare_params(params)
29
+ params
30
+ .with_indifferent_access
31
+ .slice(*PERMITTED_PARAMS)
32
+ .merge(default_params)
33
+ .merge(amount: format('%.2f', params[:amount]))
34
+ end
35
+
36
+ def default_params
37
+ {}
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,26 @@
1
+ module Payonline
2
+ class RebillResponse
3
+ SUCCESS_CODE = 'OK'
4
+
5
+ def initialize(response)
6
+ @response = parse_response(response)
7
+ end
8
+
9
+ def success?
10
+ @response[:result] == SUCCESS_CODE
11
+ end
12
+
13
+ def failure?
14
+ !success?
15
+ end
16
+
17
+ private
18
+
19
+ def parse_response(response)
20
+ CGI.parse(response)
21
+ .transform_keys { |key| key.to_s.underscore }
22
+ .transform_values(&:first)
23
+ .with_indifferent_access
24
+ end
25
+ end
26
+ end
@@ -1,23 +1,48 @@
1
1
  module Payonline
2
2
  class Signature
3
- def self.digest(sign_params, keys=[])
4
- if keys.present?
5
- sign_params = sign_params.slice(*keys)
6
- end
3
+ def initialize(params, keys, add_merchant_id = true)
4
+ @keys = keys
5
+
6
+ # The order of parameter keys matters
7
+ @params = prepare_params(params, add_merchant_id)
8
+
9
+ # Permitted content_type values: text, xml
10
+ @params[:security_key] = digest
11
+ @params[:content_type] = 'text'
12
+ end
13
+
14
+ # A signed copy of params
15
+ def sign
16
+ @params.transform_keys { |key| key.to_s.camelize }
17
+ end
7
18
 
8
- sign_params.merge!({ private_security_key: Payonline.configuration.private_security_key })
9
- Digest::MD5.hexdigest(sign_params.each.map{|k, v| "#{k.to_s.camelize}=#{v}"}.join('&'))
19
+ def digest
20
+ Digest::MD5.hexdigest(digest_data)
10
21
  end
11
22
 
12
- def self.sign_params(params, keys=[], add_merchant_id = true)
13
- params.reverse_merge!({ 'merchant_id' => Payonline.configuration.merchant_id }) if add_merchant_id
14
- if keys.present?
15
- keys.unshift 'merchant_id' if add_merchant_id
23
+ private
24
+
25
+ # Prepend params hash with merchant_id
26
+ def prepare_params(params, add_merchant_id = true)
27
+ if add_merchant_id
28
+ params.reverse_merge!(merchant_id: Payonline.configuration.merchant_id)
29
+ @keys.unshift(:merchant_id)
16
30
  end
17
- digest = self.digest(params, keys)
18
- params.merge!({ 'security_key' => digest, 'content_type' => 'text' })
19
31
 
20
- params
32
+ params.with_indifferent_access
33
+ end
34
+
35
+ # Prepare params for digest
36
+ def digest_data
37
+ digest_params = @params.slice(*@keys) if @keys.present?
38
+ digest_params[:private_security_key] = Payonline.configuration.private_security_key
39
+
40
+ # HACK: PayOnline sends OrderId but TransactionID (notice the letter case)
41
+ digest_params
42
+ .transform_keys { |key| key.to_s.camelize }
43
+ .transform_keys { |key| key == 'TransactionId' ? 'TransactionID' : key }
44
+ .map { |key, value| "#{key}=#{value}" }
45
+ .join('&')
21
46
  end
22
47
  end
23
48
  end
@@ -1,3 +1,3 @@
1
1
  module Payonline
2
- VERSION = "0.1.0"
2
+ VERSION = '0.1.1'
3
3
  end
data/lib/payonline.rb CHANGED
@@ -1,12 +1,14 @@
1
- require 'yaml'
1
+ require 'active_support/all'
2
+ require 'httparty'
3
+
2
4
  require 'payonline/config'
3
5
  require 'payonline/payment_gateway'
4
6
  require 'payonline/payment_response'
7
+ require 'payonline/rebill_gateway'
8
+ require 'payonline/rebill_response'
5
9
  require 'payonline/signature'
6
10
 
7
11
  module Payonline
8
- extend self
9
-
10
12
  def self.configuration
11
13
  @configuration ||= Config.new
12
14
  end
data/payonline.gemspec CHANGED
@@ -1,24 +1,25 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
4
5
  require 'payonline/version'
5
6
 
6
7
  Gem::Specification.new do |spec|
7
- spec.name = "payonline"
8
+ spec.name = 'payonline'
8
9
  spec.version = Payonline::VERSION
9
- spec.authors = ["Yuri Zubov"]
10
- spec.email = ["I0Result86@gmail.com"]
10
+ spec.authors = ['Yuri Zubov', 'SumatoSoft']
11
+ spec.email = ['I0Result86@gmail.com']
11
12
 
12
- spec.summary = %q{This is a thin wrapper library that makes using PayOnline API a bit easier.}
13
- spec.description = %q{This is a thin wrapper library that makes using PayOnline API a bit easier.}
14
- spec.homepage = "https://github.com/I0Result/payonline"
15
- spec.license = "MIT"
13
+ spec.summary = 'PayOnline API wrapper.'
14
+ spec.description = 'This is a thin wrapper library that makes using PayOnline API a bit easier.'
15
+ spec.homepage = 'https://github.com/SumatoSoft/payonline'
16
+ spec.license = 'MIT'
16
17
 
17
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
- spec.bindir = "exe"
18
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec)/}) }
19
+ spec.bindir = 'exe'
19
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
- spec.require_paths = ["lib"]
21
+ spec.require_paths = ['lib']
21
22
 
22
- spec.add_development_dependency "bundler", "~> 1.9"
23
- spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency 'activesupport', '>= 4.2'
24
+ spec.add_development_dependency 'rake', '~> 11.2'
24
25
  end
metadata CHANGED
@@ -1,43 +1,44 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: payonline
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
  - Yuri Zubov
8
+ - SumatoSoft
8
9
  autorequire:
9
10
  bindir: exe
10
11
  cert_chain: []
11
- date: 2015-04-08 00:00:00.000000000 Z
12
+ date: 2017-01-16 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
- name: bundler
15
+ name: activesupport
15
16
  requirement: !ruby/object:Gem::Requirement
16
17
  requirements:
17
- - - ~>
18
+ - - ">="
18
19
  - !ruby/object:Gem::Version
19
- version: '1.9'
20
+ version: '4.2'
20
21
  type: :development
21
22
  prerelease: false
22
23
  version_requirements: !ruby/object:Gem::Requirement
23
24
  requirements:
24
- - - ~>
25
+ - - ">="
25
26
  - !ruby/object:Gem::Version
26
- version: '1.9'
27
+ version: '4.2'
27
28
  - !ruby/object:Gem::Dependency
28
29
  name: rake
29
30
  requirement: !ruby/object:Gem::Requirement
30
31
  requirements:
31
- - - ~>
32
+ - - "~>"
32
33
  - !ruby/object:Gem::Version
33
- version: '10.0'
34
+ version: '11.2'
34
35
  type: :development
35
36
  prerelease: false
36
37
  version_requirements: !ruby/object:Gem::Requirement
37
38
  requirements:
38
- - - ~>
39
+ - - "~>"
39
40
  - !ruby/object:Gem::Version
40
- version: '10.0'
41
+ version: '11.2'
41
42
  description: This is a thin wrapper library that makes using PayOnline API a bit easier.
42
43
  email:
43
44
  - I0Result86@gmail.com
@@ -45,7 +46,9 @@ executables: []
45
46
  extensions: []
46
47
  extra_rdoc_files: []
47
48
  files:
48
- - .gitignore
49
+ - ".gitignore"
50
+ - ".hound.yml"
51
+ - ".rubocop.yml"
49
52
  - Gemfile
50
53
  - README.md
51
54
  - Rakefile
@@ -53,10 +56,12 @@ files:
53
56
  - lib/payonline/config.rb
54
57
  - lib/payonline/payment_gateway.rb
55
58
  - lib/payonline/payment_response.rb
59
+ - lib/payonline/rebill_gateway.rb
60
+ - lib/payonline/rebill_response.rb
56
61
  - lib/payonline/signature.rb
57
62
  - lib/payonline/version.rb
58
63
  - payonline.gemspec
59
- homepage: https://github.com/I0Result/payonline
64
+ homepage: https://github.com/SumatoSoft/payonline
60
65
  licenses:
61
66
  - MIT
62
67
  metadata: {}
@@ -66,18 +71,18 @@ require_paths:
66
71
  - lib
67
72
  required_ruby_version: !ruby/object:Gem::Requirement
68
73
  requirements:
69
- - - ! '>='
74
+ - - ">="
70
75
  - !ruby/object:Gem::Version
71
76
  version: '0'
72
77
  required_rubygems_version: !ruby/object:Gem::Requirement
73
78
  requirements:
74
- - - ! '>='
79
+ - - ">="
75
80
  - !ruby/object:Gem::Version
76
81
  version: '0'
77
82
  requirements: []
78
83
  rubyforge_project:
79
- rubygems_version: 2.4.2
84
+ rubygems_version: 2.4.6
80
85
  signing_key:
81
86
  specification_version: 4
82
- summary: This is a thin wrapper library that makes using PayOnline API a bit easier.
87
+ summary: PayOnline API wrapper.
83
88
  test_files: []