paysto-rails 1.0.1 → 1.0.2

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,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZDZmN2Q3NWUxMmMwYzY0Njg0NzBkYzQxYTI5YmRkYTdmZjY3ZDUwZA==
4
+ NzRjM2IyMzliNGYwNjdhOGMyM2I1YmMyY2RhMzYwZDU0MzhjYWE5Yw==
5
5
  data.tar.gz: !binary |-
6
- YjFhYzZiMjFlOWJkMDNmOGI5Zjk0MTk5YTU5MmY0MTUxNmUxOGQwNw==
6
+ MDZjZDZhMzQxMDZmMDUzZmQ2MDA4YmMzMTQ3ZjQwMGE5YmMxNTFmMg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZGU3YTliYzMwMmZhNTIyMmI3YzEyNWFhNzBkZTdjNTA5YTAzMmNiZDgwNGUw
10
- YjhhZTM0MTZjZWNlNWJiNmNlMTQwMTgzZGEzYTE4OTg4NDUyNGY3ODk3YjVj
11
- MWNhZTM3YjVkY2NkNDVhMjJmZjRlODBkODU2ODg3MzI3Yjc5ZWI=
9
+ NmQwMmU0MDBhZWFjZDJiNjBiNTNmOTc4NzRhNDFkNjliZDRlNDRkM2RmNWM3
10
+ MzhmNWRlMjRhM2RiMDYyYWQyMzJmMmU5ZTc3NTA3YjcxOTQ1Yjc4YmVmMjdm
11
+ MTY0OWU5NDFmZWEwMTgzMmU1OTFkY2FmODAzOGZiZDkwNDZlOWQ=
12
12
  data.tar.gz: !binary |-
13
- YjE4ZmI5NDY2MGNkNTBlYTY3NjBmOGQ1YjA2YzYwZWVhNDgyYjMzOGZhNDBl
14
- MTQxOTJkMmMwNDliOWZkNmQ0NzU4YjY5ZmNhYjZlZDQwMzExMzgwZmMyMjMy
15
- ODY4NDQxNzUzZjliZWQ5MjVkNWM3OWI1NTYyMTE1NTBjOTlkZDc=
13
+ OTA3NzQ3Zjk5MTFlMmRiOTcyMTAzNWRhZTVhZjM2MTBkNjMxYjE5MTVhYjAx
14
+ ZDVlZDY3MWJlNDE1NjA1NTI5M2FjOTI4MDM2ZDc1MmU3ZTlkOWU0ZGE1ZmFh
15
+ MGI1NGMzNGJlN2ExYTIwMzkxOTFlMDg3ZGYyMjY2Y2VkMzJiNzk=
data/README.md CHANGED
@@ -2,10 +2,10 @@
2
2
  [![Gem Version](https://badge.fury.io/rb/paysto-rails.svg)](http://badge.fury.io/rb/paysto-rails)
3
3
  [![Code Climate](https://codeclimate.com/github/fbandrey/paysto-rails/badges/gpa.svg)](https://codeclimate.com/github/fbandrey/paysto-rails)
4
4
  [![Dependency Status](https://gemnasium.com/fbandrey/paysto-rails.svg)](https://gemnasium.com/fbandrey/paysto-rails)
5
+ [![security](https://hakiri.io/github/fbandrey/paysto-rails/master.svg)](https://hakiri.io/github/fbandrey/paysto-rails/master)
6
+ [![Inline docs](http://inch-ci.org/github/fbandrey/paysto-rails.png?branch=master)](http://inch-ci.org/github/fbandrey/paysto-rails)
5
7
 
6
- This is first implementation for passing payments through [Paysto](https://paysto.com) gateway.
7
-
8
- It works only with «[onlineMerchant](https://paysto.com/ru/products/onlineMerchant)», if you know what I mean. :)
8
+ This is first implementation for passing payments through [Paysto](https://paysto.com) gateway. It works only with «[onlineMerchant](https://paysto.com/ru/products/onlineMerchant)».
9
9
 
10
10
  ## Installation
11
11
 
@@ -65,35 +65,33 @@ In the simple case only what you should to do:
65
65
 
66
66
  That's all.
67
67
 
68
- Now you may customize models as you want, associate it with users or anything else...
69
-
70
- For more information check [payment workflow](https://github.com/fbandrey/paysto-rails/wiki/Payment-workflow) wiki.
71
-
72
68
  ## Usage
73
69
 
74
- You have 3 models and 1 controller now if you did everything right before. Check models and extend them with logic and associations, which you need in your application.
70
+ You have 3 models and 1 controller now if you did everything right before. Check models and extend them with logic or associations, which you need in your application.
75
71
 
76
- Controller by default [extended with concern](https://github.com/fbandrey/paysto-rails/blob/master/lib/paysto/controller.rb) and looks so:
72
+ Controller by default [extended with concern](https://github.com/fbandrey/paysto-rails/blob/master/lib/paysto/controller.rb) and contains all necessary methods:
77
73
  ```
78
74
  class PaystoController < ApplicationController
79
75
  include Paysto::Controller
80
76
  end
81
77
  ```
82
- But you may override methods here as you want. For example, if I want to redirect user to "/payments" URL when payment is passed:
78
+ But you may override methods as you want. For example, if you want to redirect user to custom URL when payment is passed:
83
79
  ```
84
80
  class PaystoController < ApplicationController
85
81
  include Paysto::Controller
86
82
 
87
83
  def success
88
84
  flash[:success] = I18n.t('paysto.success')
89
- redirect_to custom_payments_path
85
+ redirect_to any_custom_payments_path
90
86
  end
91
87
  end
92
88
  ```
93
89
 
94
- Also you can customize [check](https://github.com/fbandrey/paysto-rails/blob/master/lib/paysto/controller.rb#L9) or [callback](https://github.com/fbandrey/paysto-rails/blob/master/lib/paysto/controller.rb#L18) methods using Paysto module as you want, but we don't recommend it, do it only if you know what's going on there.
90
+ Also you can customize [check](https://github.com/fbandrey/paysto-rails/blob/master/lib/paysto/controller.rb#L9) or [callback](https://github.com/fbandrey/paysto-rails/blob/master/lib/paysto/controller.rb#L18) methods using Paysto module as you want, but do it only if you know what's going on there.
91
+
92
+ Check [payment workflow](https://github.com/fbandrey/paysto-rails/wiki/Payment-workflow) wiki for more information.
95
93
 
96
- ### Paysto methods
94
+ #### Paysto methods
97
95
 
98
96
  ```Paysto.balance``` – current balance in Paysto.
99
97
 
@@ -109,7 +107,7 @@ Also you can customize [check](https://github.com/fbandrey/paysto-rails/blob/mas
109
107
 
110
108
  ```Paysto.md5_valid?(params)``` – check whether the MD5 sign is valid.
111
109
 
112
- ```Paysto.pay_till``` – timestamp string in Paysto format.
110
+ ```Paysto.pay_till``` – timestamp string for payment expiration in Paysto format.
113
111
 
114
112
  ```Paysto.real_amount(amount)``` – real income amount without Paysto tax.
115
113
 
@@ -4,6 +4,7 @@ module Paysto
4
4
  class InstallGenerator < Rails::Generators::Base
5
5
  source_root File.expand_path('../../templates', __FILE__)
6
6
 
7
+ # Extend routes.rb with required routes.
7
8
  def add_paysto_routes
8
9
  paysto_route = <<-PAYSTO_ROUTES
9
10
  namespace :paysto do
@@ -14,18 +15,21 @@ PAYSTO_ROUTES
14
15
  route paysto_route
15
16
  end
16
17
 
18
+ # Copy general Paysto config.
17
19
  def copy_config
18
20
  template 'config/paysto.rb', 'config/initializers/paysto.rb'
19
21
  end
20
22
 
23
+ # Copy RU and EN locale files.
21
24
  def copy_locale
22
25
  template 'config/paysto.en.yml', 'config/locales/paysto.en.yml'
23
26
  template 'config/paysto.ru.yml', 'config/locales/paysto.ru.yml'
24
27
  end
25
28
 
29
+ # Copy default Paysto controller.
26
30
  def copy_controller
27
31
  template 'controllers/paysto_controller.rb', 'app/controllers/paysto_controller.rb'
28
32
  end
29
33
 
30
34
  end
31
- end
35
+ end
@@ -6,6 +6,7 @@ module Paysto
6
6
  include Rails::Generators::Migration
7
7
  source_root File.expand_path('../../templates', __FILE__)
8
8
 
9
+ # Migration timestamp.
9
10
  def self.next_migration_number(dirname)
10
11
  if ActiveRecord::Base.timestamped_migrations
11
12
  Time.new.utc.strftime("%Y%m%d%H%M%S")
@@ -14,14 +15,16 @@ module Paysto
14
15
  end
15
16
  end
16
17
 
18
+ # Create migration with required tables.
17
19
  def create_migration_file
18
20
  migration_template 'migration.rb', 'db/migrate/create_paysto_tables.rb'
19
21
  end
20
22
 
23
+ # Render configured models.
21
24
  def copy_models
22
25
  template 'models/payment.rb', "app/models/#{Paysto.payment_class_name.underscore}.rb"
23
26
  template 'models/invoice.rb', "app/models/#{Paysto.invoice_class_name.underscore}.rb"
24
27
  template 'models/invoice_notification.rb', "app/models/#{Paysto.invoice_notification_class_name.underscore}.rb"
25
28
  end
26
29
  end
27
- end
30
+ end
@@ -1,10 +1,11 @@
1
1
  Paysto.setup do |config|
2
2
 
3
- # === Put your Paysto credentials here
3
+ # === Put your real Paysto credentials here.
4
4
  config.id = 'SECRET-ID'
5
5
  config.secret = 'SECRET-KEY'
6
6
  config.description = 'CUSTOM-DESCRIPTION-FOR-PAYMENTS'
7
7
 
8
+ # === Paysto URLs.
8
9
  config.urls = {
9
10
  payment: 'https://paysto.com/ru/pay',
10
11
  currencies: 'https://paysto.com/api/Common/Currency',
@@ -12,6 +13,7 @@ Paysto.setup do |config|
12
13
  payments_list: 'https://paysto.com/api/Payment/GetList'
13
14
  }
14
15
 
16
+ # === Paysto server IPs.
15
17
  config.ips = [
16
18
  '66.226.72.66',
17
19
  '66.226.74.225',
@@ -20,10 +22,16 @@ Paysto.setup do |config|
20
22
  '66.226.74.228'
21
23
  ]
22
24
 
23
- # === Payments tax of your tariff plan in Paysto, default onlineMerchant "All inclusive" is 5%.
25
+ # === Payments tax of your tariff plan in Paysto. Default onlineMerchant "All inclusive" is 5%.
24
26
  config.tax = 0.05
25
27
 
26
- # === Customize model names as you want before they are will be generated
28
+ # === Minimal Paysto tax for each payment. Default: 10.
29
+ config.min_tax = 10
30
+
31
+ # === Payments expiration. Default: 1.day.
32
+ config.expiration = 1.day
33
+
34
+ # === Customize model names as you want before they are will be generated.
27
35
  config.payment_class_name = 'Payment'
28
36
  config.invoice_class_name = 'Invoice'
29
37
  config.invoice_notification_class_name = 'InvoiceNotification'
@@ -8,18 +8,22 @@ class <%= Paysto.invoice_class_name %> < ActiveRecord::Base
8
8
 
9
9
  validates :amount, presence: true
10
10
 
11
+ # 'Success' code for different gateways.
11
12
  SUCCESS_STATES = {
12
13
  'paysto' => 'RES_PAID'
13
14
  }
14
15
 
16
+ # Create <%= Paysto.invoice_notification_class_name %> with details.
15
17
  def notify(params, gateway)
16
18
  self.<%= Paysto.invoice_notification_class_name.underscore.pluralize %>.create(pay_data: info_by_gateway(params, gateway))
17
19
  end
18
20
 
21
+ # Check whether the <%= Paysto.invoice_class_name.underscore %> is should be paid.
19
22
  def need_to_be_paid?(gateway, payment_status, amount)
20
23
  !paid? && (payment_status == SUCCESS_STATES[gateway.to_s]) && (self.amount.to_f == amount.to_f)
21
24
  end
22
25
 
26
+ # Create <%= Paysto.payment_class_name %> record.
23
27
  def create_<%= Paysto.payment_class_name.underscore %>(payment_method, gateway_code, real_amount = nil)
24
28
  self.<%= Paysto.payment_class_name.underscore %> = <%= Paysto.payment_class_name %>.new(amount: self.amount,
25
29
  real_amount: real_amount,
@@ -32,12 +36,15 @@ class <%= Paysto.invoice_class_name %> < ActiveRecord::Base
32
36
  end
33
37
  end
34
38
 
39
+ # Whether the <%= Paysto.invoice_class_name.underscore %> is paid.
35
40
  def paid?
36
41
  !!paid_at
37
42
  end
38
43
 
39
44
  private
40
45
 
46
+ # Payment details string.
47
+ # You could extend this method for another gateways.
41
48
  def info_by_gateway(_params, _gateway)
42
49
  _keys = case _gateway
43
50
  when :paysto
@@ -51,4 +58,4 @@ class <%= Paysto.invoice_class_name %> < ActiveRecord::Base
51
58
  end.join(';')
52
59
  end
53
60
 
54
- end
61
+ end
data/lib/paysto/base.rb CHANGED
@@ -7,96 +7,115 @@ module Paysto
7
7
  :urls,
8
8
  :ips,
9
9
  :tax,
10
+ :min_tax,
11
+ :expiration,
10
12
  :payment_class_name,
11
13
  :invoice_class_name,
12
14
  :invoice_notification_class_name
13
15
 
14
16
  class << self
15
17
 
18
+ # Configuring module.
16
19
  def setup
17
20
  yield self
18
21
  end
19
22
 
23
+ # Payment class.
20
24
  def payment_class
21
25
  @@payment_class_name.constantize
22
26
  end
23
27
 
28
+ # Invoice class.
24
29
  def invoice_class
25
30
  @@invoice_class_name.constantize
26
31
  end
27
32
 
33
+ # InvoiceNotification class.
28
34
  def invoice_notification_class
29
35
  @@invoice_notification_class_name.constantize
30
36
  end
31
37
 
38
+ # List of available pay methods according to your tariff plan.
32
39
  def currencies
33
- https_request_to Paysto.urls[:currencies], base_params
40
+ https_request_to @@urls[:currencies], base_params
34
41
  end
35
42
 
43
+ # Your current balance in Paysto.
36
44
  def balance
37
- https_request_to Paysto.urls[:balance], base_params
45
+ https_request_to @@urls[:balance], base_params
38
46
  end
39
47
 
48
+ # Returns array of payments with details between dates.
49
+ # +from+ – from date.
50
+ # +to+ – to date.
40
51
  def get_payments(from, to)
41
- p = { 'PAYSTO_SHOP_ID' => Paysto.id,
52
+ p = { 'PAYSTO_SHOP_ID' => @@id,
42
53
  'FROM' => from.strftime('%Y%m%d%H%M'),
43
54
  'TO' => to.strftime('%Y%m%d%H%M') }
44
55
  p.merge!('PAYSTO_MD5' => generate_md5(p))
45
56
 
46
- res = https_request_to(Paysto.urls[:payments_list], p)
57
+ res = https_request_to(@@urls[:payments_list], p)
47
58
  CSV.parse(res)
48
59
  end
49
60
 
61
+ # Returns payment type or 'common' by default.
62
+ # +invoice_id+ – invoice ID of payment.
63
+ # +time+ – estimated payment execution time.
50
64
  def get_payment_type(invoice_id, time = Time.zone.now)
51
- _type = 'common'
52
65
  _payments = get_payments(time.utc - 30.minutes, time.utc + 5.minutes)
53
66
  if _payments.present?
54
67
  p = _payments.select{|_p| _p[2].eql?(invoice_id.to_s)}.first
55
68
  _type = p[7] if p
56
69
  end
57
- _type
70
+ _type || 'common'
58
71
  end
59
72
 
73
+ # Check whether the invoice is valid.
60
74
  def invoice_valid?(invoice)
61
- invoice && invoice.payment_id.blank? && invoice.paid_at.blank?
75
+ invoice && invoice.send("#{@@payment_class_name.underscore}_id").blank? && invoice.paid_at.blank?
62
76
  end
63
77
 
78
+ # Check whether the IP is permitted.
64
79
  def ip_valid?(ip)
65
- Paysto.ips.include?(ip)
80
+ @@ips.include?(ip)
66
81
  end
67
82
 
83
+ # Check whether the MD5 sign is valid.
68
84
  def md5_valid?(p)
69
- generate_md5(p.reject{|k,v| ['action', 'controller', 'PAYSTO_MD5'].include?(k)}) == p['PAYSTO_MD5']
85
+ except_keys = ['action', 'controller', 'PAYSTO_MD5']
86
+ generate_md5(p.reject{|k,v| except_keys.include?(k)}) == p['PAYSTO_MD5']
70
87
  end
71
88
 
89
+ # Timestamp string in Paysto format for payments expiration.
72
90
  def pay_till
73
- (Time.zone.now + 1.day + 1.minute).utc.strftime('%Y%m%d%H%M')
91
+ (Time.zone.now + @@expiration).utc.strftime('%Y%m%d%H%M')
74
92
  end
75
93
 
94
+ # Real income value without Paysto tax for any amount which you want to calculate.
95
+ # +str+ – amount string or numeric, does not matter.
76
96
  def real_amount(str)
77
97
  amount = str.to_f
78
- _tax = amount * Paysto.tax
79
- _tax = 10 if _tax < 10
98
+ _tax = amount * @@tax
99
+ _tax = @@min_tax if _tax < @@min_tax
80
100
  amount - _tax
81
101
  end
82
102
 
83
103
  private
84
104
 
105
+ # Generating MD5 sign according with received params.
85
106
  def generate_md5(p = {}, upcase = true)
86
107
  hash_str = p.to_a.sort_by{|pair| pair.first.downcase}.map{|pair| pair.join('=')}.join('&')
87
- md5 = Digest::MD5.hexdigest("#{hash_str}&#{Paysto.secret}")
88
- if upcase
89
- md5.upcase
90
- else
91
- md5
92
- end
108
+ md5 = Digest::MD5.hexdigest("#{hash_str}&#{@@secret}")
109
+ upcase ? md5.upcase : md5
93
110
  end
94
111
 
112
+ # Base set of params for requests.
95
113
  def base_params
96
- p = { 'PAYSTO_SHOP_ID' => Paysto.id }
114
+ p = { 'PAYSTO_SHOP_ID' => @@id }
97
115
  p.merge!('PAYSTO_MD5' => generate_md5(p))
98
116
  end
99
117
 
118
+ # Performing an HTTPS request.
100
119
  def https_request_to(url, params)
101
120
  uri = URI.parse(url)
102
121
  req = Net::HTTP::Post.new(uri.path)
@@ -110,4 +129,4 @@ module Paysto
110
129
  end
111
130
 
112
131
  end
113
- end
132
+ end
@@ -3,9 +3,12 @@ module Paysto
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
+ # Some callbacks does not requires verifications.
6
7
  skip_before_filter :verify_authenticity_token, only: [:callback, :check]
7
8
  end
8
9
 
10
+ # First step of payment workflow: Invoice, IP and MD5 verification.
11
+ # Render invoice ID if everything right or anything else if not.
9
12
  def check
10
13
  invoice = Paysto.invoice_class.find_by_id(params['PAYSTO_INVOICE_ID'])
11
14
  if Paysto.invoice_valid?(invoice) && Paysto.ip_valid?(request.remote_ip) && Paysto.md5_valid?(params)
@@ -15,6 +18,8 @@ module Paysto
15
18
  end
16
19
  end
17
20
 
21
+ # Second step of payment workflow: Payment creation.
22
+ # Render invoice ID if everything right or anything else if not.
18
23
  def callback
19
24
  invoice = Paysto.invoice_class.find_by_id(params['PAYSTO_INVOICE_ID'])
20
25
  if invoice && invoice.need_to_be_paid?(:paysto, params['PAYSTO_REQUEST_MODE'], params['PAYSTO_SUM']) && Paysto.ip_valid?(request.remote_ip) && Paysto.md5_valid?(params)
@@ -26,15 +31,17 @@ module Paysto
26
31
  end
27
32
  end
28
33
 
34
+ # Success callback.
29
35
  def success
30
36
  flash[:success] = I18n.t('paysto.success')
31
37
  redirect_to root_path
32
38
  end
33
39
 
40
+ # Fail callback.
34
41
  def fail
35
42
  flash[:alert] = I18n.t('paysto.fail')
36
43
  redirect_to root_path
37
44
  end
38
45
 
39
46
  end
40
- end
47
+ end
@@ -1,3 +1,3 @@
1
1
  module Paysto
2
- VERSION = '1.0.1'
2
+ VERSION = '1.0.2'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paysto-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey Baiburin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-19 00:00:00.000000000 Z
11
+ date: 2014-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler