spree_paysera 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +13 -0
- data/.rspec +1 -0
- data/.travis.yml +43 -0
- data/Appraisals +22 -0
- data/Gemfile +12 -0
- data/LICENSE.md +21 -0
- data/README.md +24 -0
- data/Rakefile +23 -0
- data/app/controllers/spree/paysera_controller.rb +57 -0
- data/app/domain/spree/paysera/build_form.rb +58 -0
- data/app/domain/spree/paysera/build_url.rb +52 -0
- data/app/domain/spree/paysera/complete_order.rb +41 -0
- data/app/domain/spree/paysera/parse_response.rb +69 -0
- data/app/lib/spree/paysera/error.rb +4 -0
- data/app/lib/spree/paysera/error_handler.rb +15 -0
- data/app/models/spree/gateway/paysera.rb +31 -0
- data/app/models/spree/paysera_form.rb +52 -0
- data/app/views/spree/admin/payments/source_views/_paysera.html.erb +0 -0
- data/app/views/spree/checkout/payment/_paysera.html.erb +40 -0
- data/app/views/spree/paysera/callback.html.erb +0 -0
- data/app/views/spree/paysera/cancel.html.erb +1 -0
- data/app/views/spree/paysera/confirm.html.erb +1 -0
- data/config/locales/en.yml +5 -0
- data/config/locales/lt.yml +5 -0
- data/config/locales/ru.yml +5 -0
- data/config/routes.rb +8 -0
- data/gemfiles/spree_3_5.gemfile +10 -0
- data/gemfiles/spree_3_7.gemfile +11 -0
- data/gemfiles/spree_4_0.gemfile +10 -0
- data/gemfiles/spree_master.gemfile +10 -0
- data/lib/spree_paysera/engine.rb +22 -0
- data/lib/spree_paysera.rb +5 -0
- data/spec/controllers/spree/paysera_controller_spec.rb +198 -0
- data/spec/domain/spree/paysera/build_form_spec.rb +41 -0
- data/spec/domain/spree/paysera/build_url_spec.rb +24 -0
- data/spec/domain/spree/paysera/complete_order_spec.rb +59 -0
- data/spec/domain/spree/paysera/parse_response_spec.rb +28 -0
- data/spec/factories/paysera_form.rb +14 -0
- data/spec/factories/paysera_gateway.rb +21 -0
- data/spec/spec_helper.rb +65 -0
- data/spree_paysera.gemspec +40 -0
- metadata +56 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6b8058e1aa115aebb4a98427cf24d9fab00c5793f7fa493de0dcf4b16f6999bd
|
4
|
+
data.tar.gz: '0970e0e384fb48b6680e7a82620d0e484eedd8ce99a37e077c7fba57c32e0896'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c68ee4cef6066e13912f91911b2489060ace1bb7a8a2c522c5d4f6dd39c7569b4a3f849684bec83fa70088d0064d25b9229035a8bf8b2ac5069f736c61ab021
|
7
|
+
data.tar.gz: 1b4a45afb67ff90092ae844a6db1ac7c11f7589302865f9397ea66d26567280892101ce7a1694d9e670b04c9347332762393259fa392f8e7f94fdfd657d11fe0
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/.travis.yml
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
dist: trusty
|
2
|
+
|
3
|
+
language: ruby
|
4
|
+
rvm:
|
5
|
+
- 2.3.8
|
6
|
+
- 2.4.4
|
7
|
+
- 2.5.1
|
8
|
+
- 2.6.3
|
9
|
+
|
10
|
+
script:
|
11
|
+
- bundle exec rake test_app
|
12
|
+
- bundle exec rake spec
|
13
|
+
|
14
|
+
gemfile:
|
15
|
+
- gemfiles/spree_3_5.gemfile
|
16
|
+
- gemfiles/spree_3_7.gemfile
|
17
|
+
- gemfiles/spree_4_0.gemfile
|
18
|
+
- gemfiles/spree_master.gemfile
|
19
|
+
|
20
|
+
matrix:
|
21
|
+
allow_failures:
|
22
|
+
- gemfile: gemfiles/spree_master.gemfile
|
23
|
+
exclude:
|
24
|
+
- rvm: 2.3.8
|
25
|
+
gemfile: gemfiles/spree_4_0.gemfile
|
26
|
+
- rvm: 2.3.8
|
27
|
+
gemfile: gemfiles/spree_master.gemfile
|
28
|
+
- rvm: 2.4.4
|
29
|
+
gemfile: gemfiles/spree_4_0.gemfile
|
30
|
+
- rvm: 2.4.4
|
31
|
+
gemfile: gemfiles/spree_master.gemfile
|
32
|
+
- rvm: 2.5.1
|
33
|
+
gemfile: gemfiles/spree_3_5.gemfile
|
34
|
+
- rvm: 2.6.3
|
35
|
+
gemfile: gemfiles/spree_3_5.gemfile
|
36
|
+
|
37
|
+
|
38
|
+
addons:
|
39
|
+
apt:
|
40
|
+
packages:
|
41
|
+
- mysql-server-5.6
|
42
|
+
- mysql-client-core-5.6
|
43
|
+
- mysql-client-5.6
|
data/Appraisals
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
appraise 'spree-3-5' do
|
4
|
+
gem 'spree', '~> 3.5.0'
|
5
|
+
gem 'spree_auth_devise', '~> 3.3.0'
|
6
|
+
end
|
7
|
+
|
8
|
+
appraise 'spree-3-7' do
|
9
|
+
gem 'spree', '~> 3.7.1'
|
10
|
+
gem 'spree_auth_devise', '~> 3.5.2'
|
11
|
+
end
|
12
|
+
|
13
|
+
appraise 'spree-4-0' do
|
14
|
+
gem 'spree', '~> 4.0.0'
|
15
|
+
gem 'spree_auth_devise', '~> 4.0.0'
|
16
|
+
end
|
17
|
+
|
18
|
+
appraise 'spree-master' do
|
19
|
+
gem 'spree', github: 'spree/spree', branch: 'master'
|
20
|
+
gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: 'master'
|
21
|
+
gem 'rails-controller-testing'
|
22
|
+
end
|
data/Gemfile
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2018 Donatas Jarmalovičius
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# spree_paysera
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/donny741/spree_paysera.svg?branch=master)](https://travis-ci.org/donny741/spree_paysera)
|
4
|
+
|
5
|
+
Paysera payment gateway integration for Spree Ecommerce.
|
6
|
+
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
1. Add this to your gemfile:
|
11
|
+
|
12
|
+
gem 'spree_paysera', :github => 'donny741/spree_paysera'
|
13
|
+
|
14
|
+
2. Install the gem using Bundler:
|
15
|
+
|
16
|
+
bundle install
|
17
|
+
|
18
|
+
3. Restart your server
|
19
|
+
|
20
|
+
## Setup
|
21
|
+
|
22
|
+
In Spree admin panel go to "Configuration", "Payment Methods". Create a new payment method. Select provider "Spree::Gateway::Paysera", enter name and description. Click "Create". Enter project id, domain name (example: https://www.example.com) and message text (paytext).
|
23
|
+
|
24
|
+
For production untick "Test Mode".
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler'
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
require 'spree/testing_support/extension_rake'
|
8
|
+
|
9
|
+
RSpec::Core::RakeTask.new
|
10
|
+
|
11
|
+
task :default do
|
12
|
+
if Dir['spec/dummy'].empty?
|
13
|
+
Rake::Task[:test_app].invoke
|
14
|
+
Dir.chdir('../../')
|
15
|
+
end
|
16
|
+
Rake::Task[:spec].invoke
|
17
|
+
end
|
18
|
+
|
19
|
+
desc 'Generates a dummy app for testing'
|
20
|
+
task :test_app do
|
21
|
+
ENV['LIB_NAME'] = 'spree_paysera'
|
22
|
+
Rake::Task['extension:test_app'].invoke
|
23
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spree
|
4
|
+
class PayseraController < StoreController
|
5
|
+
protect_from_forgery only: :index
|
6
|
+
|
7
|
+
include Spree::Paysera::ErrorHandler
|
8
|
+
|
9
|
+
def index
|
10
|
+
form = Spree::Paysera::BuildForm.for(payment_method, current_order)
|
11
|
+
url = Spree::Paysera::BuildUrl.for(payment_method, form.attributes)
|
12
|
+
|
13
|
+
redirect_to url
|
14
|
+
end
|
15
|
+
|
16
|
+
def callback
|
17
|
+
Spree::LogEntry.create(
|
18
|
+
source: payment_method,
|
19
|
+
details: params.to_yaml
|
20
|
+
)
|
21
|
+
|
22
|
+
response = Spree::Paysera::ParseResponse.for(payment_method, params)
|
23
|
+
raise Spree::Paysera::Error, 'wrong project id' if response[:projectid] != payment_method.preferred_project_id.to_s
|
24
|
+
|
25
|
+
order = Spree::Order.find_by!(number: response[:orderid])
|
26
|
+
|
27
|
+
Spree::Paysera::CompleteOrder.for(order, payment_method, response)
|
28
|
+
render plain: 'OK'
|
29
|
+
end
|
30
|
+
|
31
|
+
def confirm
|
32
|
+
response = Spree::Paysera::ParseResponse.for(payment_method, params)
|
33
|
+
order = Spree::Order.find_by(number: response[:orderid])
|
34
|
+
|
35
|
+
if order.paid?
|
36
|
+
flash.notice = Spree.t(:order_processed_successfully)
|
37
|
+
else
|
38
|
+
flash.alert = Spree.t(:payment_processing_failed)
|
39
|
+
end
|
40
|
+
rescue StandardError
|
41
|
+
flash.alert = Spree.t(:payment_processing_failed)
|
42
|
+
ensure
|
43
|
+
redirect_to account_path
|
44
|
+
end
|
45
|
+
|
46
|
+
def cancel
|
47
|
+
flash.notice = Spree.t(:order_canceled)
|
48
|
+
redirect_to products_path
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def payment_method
|
54
|
+
@payment_method ||= Spree::Gateway::Paysera.find(params[:payment_method_id])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Spree::Paysera::BuildForm
|
4
|
+
include Spree::Core::Engine.routes.url_helpers
|
5
|
+
|
6
|
+
attr_reader :payment_method, :order
|
7
|
+
|
8
|
+
def self.for(payment_method, order)
|
9
|
+
new(payment_method, order).run
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(payment_method, order)
|
13
|
+
@payment_method = payment_method
|
14
|
+
@order = order
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
18
|
+
@result = {}
|
19
|
+
|
20
|
+
add_gateway_details
|
21
|
+
add_order_details
|
22
|
+
|
23
|
+
form = Spree::PayseraForm.new(@result)
|
24
|
+
raise Spree::Paysera::Error, 'Params are not valid' unless form.valid?
|
25
|
+
|
26
|
+
form
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def add_gateway_details
|
32
|
+
host = payment_method.preferred_domain_name.chomp('/')
|
33
|
+
|
34
|
+
@result.merge!(
|
35
|
+
version: payment_method.preferred_api_version,
|
36
|
+
projectid: payment_method.preferred_project_id,
|
37
|
+
callbackurl: paysera_callback_url(payment_method.id, host: host),
|
38
|
+
accepturl: paysera_confirm_url(payment_method.id, host: host),
|
39
|
+
cancelurl: paysera_cancel_url(payment_method.id, host: host),
|
40
|
+
paytext: payment_method.preferred_message_text || 'Payment',
|
41
|
+
test: payment_method.preferred_test_mode ? 1 : 0
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
def add_order_details
|
46
|
+
address = order.bill_address
|
47
|
+
@result.merge!(
|
48
|
+
orderid: order.number,
|
49
|
+
amount: order.total.to_money.cents,
|
50
|
+
currency: order.currency,
|
51
|
+
p_firstname: address.firstname,
|
52
|
+
p_lastname: address.lastname,
|
53
|
+
p_street: address.address1 + ' ' + address.address2,
|
54
|
+
p_city: address.city,
|
55
|
+
p_zip: address.zipcode
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cgi'
|
4
|
+
require 'digest/md5'
|
5
|
+
|
6
|
+
class Spree::Paysera::BuildUrl
|
7
|
+
attr_reader :payment_method, :options
|
8
|
+
|
9
|
+
def self.for(payment_method, options)
|
10
|
+
new(payment_method, options).run
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(payment_method, options)
|
14
|
+
@payment_method = payment_method
|
15
|
+
@options = options
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
provider_url + make_query(
|
20
|
+
data: assertion,
|
21
|
+
sign: sign_request(assertion, payment_method.preferred_sign_key)
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def assertion
|
28
|
+
@assertion ||= encode_string(make_query(options))
|
29
|
+
end
|
30
|
+
|
31
|
+
def make_query(data)
|
32
|
+
data.collect do |key, value|
|
33
|
+
"#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}"
|
34
|
+
end.compact.sort!.join('&')
|
35
|
+
end
|
36
|
+
|
37
|
+
def encode_string(string)
|
38
|
+
Base64.encode64(string).gsub("\n", '').gsub('/', '_').gsub('+', '-')
|
39
|
+
end
|
40
|
+
|
41
|
+
def sign_request(query, password)
|
42
|
+
Digest::MD5.hexdigest(query + password)
|
43
|
+
end
|
44
|
+
|
45
|
+
def provider_url
|
46
|
+
if payment_method.preferred_service_url.nil?
|
47
|
+
return 'https://www.paysera.lt/pay/?'
|
48
|
+
end
|
49
|
+
|
50
|
+
payment_method.preferred_service_url
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Spree::Paysera::CompleteOrder
|
4
|
+
attr_reader :order, :payment_method, :order_total, :payamount
|
5
|
+
|
6
|
+
def self.for(order, payment_method, params)
|
7
|
+
new(order, payment_method, params).run
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(order, payment_method, params)
|
11
|
+
@order = order
|
12
|
+
@payment_method = payment_method
|
13
|
+
@order_total = order.total.to_money
|
14
|
+
@payamount = params[:payamount].to_money / 100
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
18
|
+
return if order.paid?
|
19
|
+
|
20
|
+
check_payammount!
|
21
|
+
complete_order
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def check_payammount!
|
27
|
+
return if payamount >= order_total
|
28
|
+
|
29
|
+
raise Spree::Paysera::Error, 'bad order amount'
|
30
|
+
end
|
31
|
+
|
32
|
+
def complete_order
|
33
|
+
payment = order.payments.create!(
|
34
|
+
source_type: 'Spree::Gateway::Paysera',
|
35
|
+
amount: payamount.to_d,
|
36
|
+
payment_method: payment_method
|
37
|
+
)
|
38
|
+
payment.complete
|
39
|
+
order.next
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Spree::Paysera::ParseResponse
|
4
|
+
attr_reader :payment_method, :data, :ss1, :ss2
|
5
|
+
|
6
|
+
PUBLIC_KEY = 'http://www.paysera.com/download/public.key'
|
7
|
+
|
8
|
+
def self.for(payment_method, response)
|
9
|
+
new(payment_method, response).run
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(payment_method, response)
|
13
|
+
@payment_method = payment_method
|
14
|
+
@data = unescape_string(response[:data])
|
15
|
+
@ss1 = response[:ss1]
|
16
|
+
@ss2 = decode_string(unescape_string(response[:ss2]))
|
17
|
+
end
|
18
|
+
|
19
|
+
def run
|
20
|
+
validate!
|
21
|
+
result
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def validate!
|
27
|
+
if payment_method.preferred_sign_key.nil?
|
28
|
+
raise Spree::Paysera::Error, 'sign_password not found'
|
29
|
+
end
|
30
|
+
if payment_method.preferred_project_id.nil?
|
31
|
+
raise Spree::Paysera::Error, 'projectid not found'
|
32
|
+
end
|
33
|
+
raise Spree::Paysera::Error, 'invalid ss1' unless valid_ss1?
|
34
|
+
raise Spree::Paysera::Error, 'invalid ss2' unless valid_ss2?
|
35
|
+
end
|
36
|
+
|
37
|
+
def result
|
38
|
+
convert_to_hash(decode_string(data))
|
39
|
+
end
|
40
|
+
|
41
|
+
def convert_to_hash(query)
|
42
|
+
query = query
|
43
|
+
Hash[query.split('&').collect do |s|
|
44
|
+
a = s.split('=')
|
45
|
+
[a[0].to_sym, a[1]]
|
46
|
+
end]
|
47
|
+
end
|
48
|
+
|
49
|
+
def decode_string(string)
|
50
|
+
Base64.decode64 string.gsub('-', '+').gsub('_', '/').gsub("\n", '')
|
51
|
+
end
|
52
|
+
|
53
|
+
def valid_ss1?
|
54
|
+
sign_password = payment_method.preferred_sign_key
|
55
|
+
Digest::MD5.hexdigest(data + sign_password) == ss1
|
56
|
+
end
|
57
|
+
|
58
|
+
def valid_ss2?
|
59
|
+
public_key.verify(OpenSSL::Digest::SHA1.new, ss2, data)
|
60
|
+
end
|
61
|
+
|
62
|
+
def public_key
|
63
|
+
OpenSSL::X509::Certificate.new(open(PUBLIC_KEY).read).public_key
|
64
|
+
end
|
65
|
+
|
66
|
+
def unescape_string(string)
|
67
|
+
CGI.unescape(string)
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spree::Paysera::ErrorHandler
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
rescue_from(StandardError, with: ->(e) { handle_error(e) })
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def handle_error(error)
|
13
|
+
render plain: 'Error: ' + error.message
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Spree::Gateway::Paysera < Spree::Gateway
|
4
|
+
preference :project_id, :integer
|
5
|
+
preference :sign_key, :string
|
6
|
+
preference :api_version, :string, default: '1.6'
|
7
|
+
preference :domain_name, :string
|
8
|
+
preference :message_text, :string
|
9
|
+
preference :service_url, :string, default: 'https://www.paysera.lt/pay/?'
|
10
|
+
preference :image_url, :string, default: 'https://bank.paysera.com/assets/image/payment_types/wallet.png'
|
11
|
+
|
12
|
+
def provider_class
|
13
|
+
Paysera
|
14
|
+
end
|
15
|
+
|
16
|
+
def source_required?
|
17
|
+
false
|
18
|
+
end
|
19
|
+
|
20
|
+
def auto_capture?
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
def method_type
|
25
|
+
'paysera'
|
26
|
+
end
|
27
|
+
|
28
|
+
def purchase(_amount, _transaction_details, _options = {})
|
29
|
+
ActiveMerchant::Billing::Response.new(true, 'Paysera success', {}, {})
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Spree::PayseraForm
|
4
|
+
include ActiveModel::Model
|
5
|
+
|
6
|
+
attr_accessor :projectid, :orderid, :accepturl, :cancelurl, :callbackurl,
|
7
|
+
:version, :lang, :amount, :currency, :payment, :country,
|
8
|
+
:paytext, :p_firstname, :p_lastname, :p_email, :p_street,
|
9
|
+
:p_city, :p_state, :p_zip, :p_countrycode, :only_payments,
|
10
|
+
:disalow_payments, :test, :time_limit, :personcode, :developerid
|
11
|
+
|
12
|
+
validates :projectid, presence: true, length: { maximum: 11 },
|
13
|
+
format: { with: /\A\d+\z/ }
|
14
|
+
validates :version, presence: true, length: { maximum: 9 },
|
15
|
+
format: { with: /\A\d+\.\d+\z/ }
|
16
|
+
validates :orderid, presence: true, length: { maximum: 40 }
|
17
|
+
validates :accepturl, presence: true, length: { maximum: 255 }
|
18
|
+
validates :cancelurl, presence: true, length: { maximum: 255 }
|
19
|
+
validates :callbackurl, presence: true, length: { maximum: 255 }
|
20
|
+
|
21
|
+
validates :lang, length: { maximum: 3 },
|
22
|
+
format: { with: /\A[a-z]{3}\z/i, allow_blank: true }
|
23
|
+
validates :amount, length: { maximum: 11 },
|
24
|
+
numericality: { only_integer: true, allow_blank: true }
|
25
|
+
validates :currency, length: { maximum: 3 },
|
26
|
+
format: { with: /\A[a-z]{3}\z/i, allow_blank: true }
|
27
|
+
validates :country, length: { maximum: 2 },
|
28
|
+
format: { with: /\A[a-z]{2}\z/i, allow_blank: true }
|
29
|
+
validates :paytext, length: { maximum: 255 }
|
30
|
+
validates :payment, length: { maximum: 20 }
|
31
|
+
|
32
|
+
validates :p_firstname, length: { maximum: 255 }
|
33
|
+
validates :p_lastname, length: { maximum: 255 }
|
34
|
+
validates :p_email, length: { maximum: 255 }
|
35
|
+
validates :p_street, length: { maximum: 255 }
|
36
|
+
validates :p_city, length: { maximum: 255 }
|
37
|
+
validates :p_state, length: { maximum: 20 }
|
38
|
+
validates :p_zip, length: { maximum: 20 }
|
39
|
+
validates :p_countrycode, length: { maximum: 2 },
|
40
|
+
format: { with: /\A[a-z]{2}\z/i, allow_blank: true }
|
41
|
+
|
42
|
+
validates :time_limit, length: { maximum: 19 }
|
43
|
+
validates :personcode, length: { maximum: 255 }
|
44
|
+
validates :developerid, length: { maximum: 11 },
|
45
|
+
format: { with: /\A\d+\z/, allow_blank: true }
|
46
|
+
validates :test, length: { maximum: 1 },
|
47
|
+
format: { with: /\A[01]\z/, allow_blank: true }
|
48
|
+
|
49
|
+
def attributes
|
50
|
+
instance_values.except('errors', 'validation_context').symbolize_keys
|
51
|
+
end
|
52
|
+
end
|
File without changes
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<span class="pay-with-text" style="font-size:20pt"><%=Spree.t(:pay_with, scope: 'paysera')%></span> <br /><br />
|
2
|
+
<%= link_to(image_tag(payment_method.preferred_image_url), paysera_proceed_url(:payment_method_id => payment_method.id), :method => :post, :id => "paysera_button") %>
|
3
|
+
<br /><br />
|
4
|
+
<style>
|
5
|
+
.pay-with-text {
|
6
|
+
padding-bottom: 10px;
|
7
|
+
}
|
8
|
+
</style>
|
9
|
+
<script>
|
10
|
+
Paysera = {
|
11
|
+
updateSaveAndContinueVisibility: function() {
|
12
|
+
if (this.isButtonHidden()) {
|
13
|
+
$(this).trigger('hideSaveAndContinue')
|
14
|
+
} else {
|
15
|
+
$(this).trigger('showSaveAndContinue')
|
16
|
+
}
|
17
|
+
},
|
18
|
+
isButtonHidden: function () {
|
19
|
+
paymentMethod = this.checkedPaymentMethod();
|
20
|
+
return (!$('#use_existing_card_yes:checked').length && Paysera.paymentMethodID && paymentMethod.val() == Paysera.paymentMethodID);
|
21
|
+
},
|
22
|
+
checkedPaymentMethod: function() {
|
23
|
+
return $('div[data-hook="checkout_payment_step"] input[type="radio"][name="order[payments_attributes][][payment_method_id]"]:checked');
|
24
|
+
},
|
25
|
+
hideSaveAndContinue: function() {
|
26
|
+
$("#checkout_form_payment [data-hook=buttons]").hide();
|
27
|
+
},
|
28
|
+
showSaveAndContinue: function() {
|
29
|
+
$("#checkout_form_payment [data-hook=buttons]").show();
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
$(document).ready(function() {
|
34
|
+
Paysera.updateSaveAndContinueVisibility();
|
35
|
+
paymentMethods = $('div[data-hook="checkout_payment_step"] input[type="radio"]').click(function (e) {
|
36
|
+
Paysera.updateSaveAndContinueVisibility();
|
37
|
+
});
|
38
|
+
})
|
39
|
+
Paysera.paymentMethodID = "<%= payment_method.id %>"
|
40
|
+
</script>
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
Payment is rejected
|
@@ -0,0 +1 @@
|
|
1
|
+
Payment is accepted
|
data/config/routes.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Spree::Core::Engine.add_routes do
|
4
|
+
post '/paysera', to: 'paysera#index', as: :paysera_proceed
|
5
|
+
get '/paysera/:payment_method_id/callback', to: 'paysera#callback', as: :paysera_callback
|
6
|
+
get '/paysera/:payment_method_id/confirm', to: 'paysera#confirm', as: :paysera_confirm
|
7
|
+
get '/paysera/:payment_method_id/cancel', to: 'paysera#cancel', as: :paysera_cancel
|
8
|
+
end
|