solidus_six_saferpay 0.1.5 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +35 -0
  3. data/.gem_release.yml +5 -0
  4. data/.github/stale.yml +17 -0
  5. data/.gitignore +18 -0
  6. data/.rspec +2 -0
  7. data/.rubocop.yml +2 -0
  8. data/.travis.yml +12 -0
  9. data/Gemfile +33 -0
  10. data/LICENSE +26 -0
  11. data/README.md +36 -20
  12. data/Rakefile +4 -54
  13. data/app/assets/config/solidus_six_saferpay_manifest.js +1 -0
  14. data/app/assets/images/solidus_six_saferpay/.keep +0 -0
  15. data/app/assets/javascripts/solidus_six_saferpay/saferpay_payment.js +4 -1
  16. data/app/assets/javascripts/spree/backend/solidus_six_saferpay.js +2 -0
  17. data/app/assets/javascripts/spree/frontend/solidus_six_saferpay.js +2 -0
  18. data/app/assets/stylesheets/spree/backend/solidus_six_saferpay.css +4 -0
  19. data/app/assets/stylesheets/spree/frontend/solidus_six_saferpay.css +4 -0
  20. data/app/controllers/spree/solidus_six_saferpay/checkout_controller.rb +133 -17
  21. data/app/controllers/spree/solidus_six_saferpay/transaction/checkout_controller.rb +1 -1
  22. data/app/models/spree/payment_method/saferpay_payment_method.rb +1 -1
  23. data/app/models/spree/payment_method/saferpay_payment_page.rb +2 -2
  24. data/app/models/spree/payment_method/saferpay_transaction.rb +2 -2
  25. data/app/services/spree/solidus_six_saferpay/cancel_authorized_payment.rb +33 -0
  26. data/app/services/spree/solidus_six_saferpay/initialize_payment.rb +0 -1
  27. data/app/services/spree/solidus_six_saferpay/initialize_transaction.rb +0 -1
  28. data/app/services/spree/solidus_six_saferpay/inquire_payment.rb +27 -1
  29. data/app/views/spree/checkout/payment/_saferpay_payment.html.erb +2 -2
  30. data/app/views/spree/solidus_six_saferpay/checkout/{iframe_breakout_redirect.html.erb → iframe_breakout_redirect.erb} +1 -1
  31. data/bin/console +17 -0
  32. data/bin/rails +18 -0
  33. data/bin/rake +7 -0
  34. data/bin/setup +8 -0
  35. data/config/initializers/assets.rb +3 -0
  36. data/config/locales/de.yml +4 -1
  37. data/config/locales/en.yml +4 -1
  38. data/config/locales/fr.yml +4 -1
  39. data/config/routes.rb +8 -8
  40. data/lib/generators/solidus_six_saferpay/install/install_generator.rb +15 -3
  41. data/lib/solidus_six_saferpay.rb +6 -3
  42. data/lib/solidus_six_saferpay/configuration.rb +6 -7
  43. data/lib/solidus_six_saferpay/engine.rb +19 -10
  44. data/lib/solidus_six_saferpay/gateway.rb +11 -11
  45. data/lib/solidus_six_saferpay/payment_page_gateway.rb +8 -9
  46. data/lib/solidus_six_saferpay/transaction_gateway.rb +8 -9
  47. data/lib/solidus_six_saferpay/version.rb +3 -1
  48. data/solidus_six_saferpay.gemspec +42 -0
  49. data/spec/controllers/spree/solidus_six_saferpay/payment_page/checkout_controller_spec.rb +16 -0
  50. data/spec/controllers/spree/solidus_six_saferpay/transaction/checkout_controller_spec.rb +16 -0
  51. data/spec/factories/payment_methods.rb +23 -0
  52. data/spec/factories/payments.rb +11 -0
  53. data/spec/factories/spree/six_saferpay_payments.rb +118 -0
  54. data/spec/models/spree/six_saferpay_payment_spec.rb +203 -0
  55. data/spec/rails_helper.rb +73 -0
  56. data/spec/services/spree/solidus_six_saferpay/assert_payment_page_spec.rb +22 -0
  57. data/spec/services/spree/solidus_six_saferpay/authorize_payment_spec.rb +39 -0
  58. data/spec/services/spree/solidus_six_saferpay/authorize_transaction_spec.rb +24 -0
  59. data/spec/services/spree/solidus_six_saferpay/cancel_authorized_payment_spec.rb +58 -0
  60. data/spec/services/spree/solidus_six_saferpay/initialize_payment_page_spec.rb +81 -0
  61. data/spec/services/spree/solidus_six_saferpay/initialize_payment_spec.rb +40 -0
  62. data/spec/services/spree/solidus_six_saferpay/initialize_transaction_spec.rb +84 -0
  63. data/spec/services/spree/solidus_six_saferpay/inquire_payment_page_payment_spec.rb +20 -0
  64. data/spec/services/spree/solidus_six_saferpay/inquire_payment_spec.rb +39 -0
  65. data/spec/services/spree/solidus_six_saferpay/inquire_transaction_payment_spec.rb +21 -0
  66. data/spec/services/spree/solidus_six_saferpay/payment_validator_spec.rb +100 -0
  67. data/spec/services/spree/solidus_six_saferpay/process_authorized_payment_spec.rb +39 -0
  68. data/spec/services/spree/solidus_six_saferpay/process_payment_page_payment_spec.rb +20 -0
  69. data/spec/services/spree/solidus_six_saferpay/process_transaction_payment_spec.rb +20 -0
  70. data/spec/solidus_six_saferpay/configuration_spec.rb +15 -0
  71. data/spec/solidus_six_saferpay/error_handler_spec.rb +65 -0
  72. data/spec/solidus_six_saferpay/gateway_response_spec.rb +70 -0
  73. data/spec/solidus_six_saferpay/gateway_spec.rb +365 -0
  74. data/spec/solidus_six_saferpay/payment_page_gateway_spec.rb +392 -0
  75. data/spec/solidus_six_saferpay/transaction_gateway_spec.rb +390 -0
  76. data/spec/spec_helper.rb +21 -0
  77. data/spec/support/route_access.rb +6 -0
  78. data/spec/support/shared_examples/authorize_payment.rb +132 -0
  79. data/spec/support/shared_examples/checkout_controller.rb +342 -0
  80. data/spec/support/shared_examples/inquire_payment.rb +118 -0
  81. data/spec/support/shared_examples/process_authorized_payment.rb +202 -0
  82. data/spec/support/uses_payment_page_gateway.rb +29 -0
  83. data/spec/support/uses_transaction_gateway.rb +28 -0
  84. metadata +250 -101
  85. data/app/services/spree/solidus_six_saferpay/inquire_transaction.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8848c45b0e022027642158af899f3b1c9d577c2e996f9fefece9f18b98d9d23f
4
- data.tar.gz: 6d58c5b848c8afa2b29f3ed61e3af5d59d2972fb4092b91e749ddb9e049fa745
3
+ metadata.gz: 6a50764caa3e856291be76ef3516ec267c44b056b8824aad3970cb7ba227454e
4
+ data.tar.gz: d0e1a19041a511d2485415d32efba781ff2558a0d75088e32f1fc20b90ece359
5
5
  SHA512:
6
- metadata.gz: 858c40016a86e47f86b804b58b1196ff9ede4207123923d0a4bb4b2f6ea479eca58eac3d1dc7360ddeedeebe4c058f772a7be09f25b2035f7465d3da14db0cb6
7
- data.tar.gz: ef2cff8cdb39f534a610358ba3d66f53261ebd48f7c394e1deb06d379b313db8fa9d375d932fbb0d606a2538d4f8dfd1ef7207a1ee287a5db934273cb331e11c
6
+ metadata.gz: c5e7411ccb2307f1ddd9f0cb4b94a38e8e0ec5702a7a78387dd35593197febb77a684067e6b6e879babc34611de359ec3b38fd79ecc9ac34995ffdf7dbc14b3a
7
+ data.tar.gz: cd0b224c254e21bb70a3c17576474ab46b2e5b4f8d9ecc9e8a90c3c28e6a1866bdbe596254e6f377bd332954b5a9e9e35a02c60916dce7fc78149abcd1db86e3
@@ -0,0 +1,35 @@
1
+ version: 2.1
2
+
3
+ orbs:
4
+ # Always take the latest version of the orb, this allows us to
5
+ # run specs against Solidus supported versions only without the need
6
+ # to change this configuration every time a Solidus version is released
7
+ # or goes EOL.
8
+ solidusio_extensions: solidusio/extensions@volatile
9
+
10
+ jobs:
11
+ run-specs-with-postgres:
12
+ executor: solidusio_extensions/postgres
13
+ steps:
14
+ - solidusio_extensions/run-tests
15
+ run-specs-with-mysql:
16
+ executor: solidusio_extensions/mysql
17
+ steps:
18
+ - solidusio_extensions/run-tests
19
+
20
+ workflows:
21
+ "Run specs on supported Solidus versions":
22
+ jobs:
23
+ - run-specs-with-postgres
24
+ - run-specs-with-mysql
25
+ "Weekly run specs against master":
26
+ triggers:
27
+ - schedule:
28
+ cron: "0 0 * * 4" # every Thursday
29
+ filters:
30
+ branches:
31
+ only:
32
+ - master
33
+ jobs:
34
+ - run-specs-with-postgres
35
+ - run-specs-with-mysql
@@ -0,0 +1,5 @@
1
+ bump:
2
+ recurse: false
3
+ file: 'lib/solidus_six_saferpay/version.rb'
4
+ message: Bump SolidusSixSaferpay to %{version}
5
+ tag: true
@@ -0,0 +1,17 @@
1
+ # Number of days of inactivity before an issue becomes stale
2
+ daysUntilStale: 60
3
+ # Number of days of inactivity before a stale issue is closed
4
+ daysUntilClose: 7
5
+ # Issues with these labels will never be considered stale
6
+ exemptLabels:
7
+ - pinned
8
+ - security
9
+ # Label to use when marking an issue as stale
10
+ staleLabel: wontfix
11
+ # Comment to post when marking an issue as stale. Set to `false` to disable
12
+ markComment: >
13
+ This issue has been automatically marked as stale because it has not had
14
+ recent activity. It will be closed if no further activity occurs. Thank you
15
+ for your contributions.
16
+ # Comment to post when closing a stale issue. Set to `false` to disable
17
+ closeComment: false
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ \#*
3
+ *~
4
+ .#*
5
+ .DS_Store
6
+ .idea
7
+ .project
8
+ .sass-cache
9
+ coverage
10
+ Gemfile.lock
11
+ tmp
12
+ nbproject
13
+ pkg
14
+ *.swp
15
+ spec/dummy
16
+ spec/examples.txt
17
+
18
+ sandbox
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,2 @@
1
+ require:
2
+ - solidus_dev_support/rubocop
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.5.1
4
+ before_install:
5
+ - gem install bundler -v 2.0.1
6
+ script:
7
+ - bin/rake extension:test_app
8
+ - bin/rake extension:specs
9
+ notifications:
10
+ slack:
11
+ secure: Vpuu/JENlZAiH67DU5bFmyKlKNmhiAZ0wSd6mjFyzcFAXaEbFIt9xkMigoEwLfQh/ZMUvKQcv3oQ6s9j5FkYImRZ0gfs1me7z/H8NTXMF5eOu7aS/gRHMGq8x2nvDBqNhSVtffqLfF3aydjZPJvGz8cvAQtqw4b+qOSIuxs2BOpcMMgEZEXW7Py6AthY2p1jxByyiqGB7NcvKsQedVtgdrnK4j+jcwK6Q9/DTOMivhWLEWAvn6VJ5zMomM5FdOFfH86uhHASGYB72ufpmKUwmFASSNHBM3CNQhZ0O/LS+a1dOlaW1BhU5q6KS/q6vgEYHyjdqcD7HhKFdlaVm6W/N1lbX+MFFcFT++l6CN8Aa3xmYpy/zWO5wwBRZw0zhYT/7P4BRoCll1D7RetnGcIV6KJyC0ydn2u/pi1kKBOgzuwbgQ+pH/lPH9+HuZzlhynRBdz2v45ctXf6AFQZmfJvFEBNwb38Q08zzGcCru0+Lu4uhFFLEwi2oMCWtpUsk0PfUJf/cUfp0hluh8wZsQWe+VQOS1NjmL8/yxjijFGzmS8WmMTb+fw7bRXFir0ecdntbP9aAhJxBN4PaMfYEFzBjCbc1e2gmwXk0VBV/0IH9hxxzIorUSmGydrWLDWiap0yDC2bm+gndodxKawT4+O45qB9jI5aYXG6JlHzrTn8QU4=
12
+ email: false
data/Gemfile ADDED
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
5
+
6
+ branch = ENV.fetch('SOLIDUS_BRANCH', 'master')
7
+ gem 'solidus', github: 'solidusio/solidus', branch: branch
8
+
9
+ # Needed to help Bundler figure out how to resolve dependencies,
10
+ # otherwise it takes forever to resolve them.
11
+ # See https://github.com/bundler/bundler/issues/6677
12
+ gem 'rails', '>0.a'
13
+
14
+ # Provides basic authentication functionality for testing parts of your engine
15
+ gem 'solidus_auth_devise'
16
+
17
+ case ENV['DB']
18
+ when 'mysql'
19
+ gem 'mysql2'
20
+ when 'postgresql'
21
+ gem 'pg'
22
+ else
23
+ gem 'sqlite3'
24
+ end
25
+
26
+ gemspec
27
+
28
+ # Use a local Gemfile to include development dependencies that might not be
29
+ # relevant for the project or for other contributors, e.g. pry-byebug.
30
+ #
31
+ # We use `send` instead of calling `eval_gemfile` to work around an issue with
32
+ # how Dependabot parses projects: https://github.com/dependabot/dependabot-core/issues/1658.
33
+ send(:eval_gemfile, 'Gemfile-local') if File.exist? 'Gemfile-local'
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2020 [name of plugin creator]
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name Solidus nor the names of its contributors may be used to
13
+ endorse or promote products derived from this software without specific
14
+ prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md CHANGED
@@ -1,33 +1,26 @@
1
1
  # SolidusSixSaferpay
2
+
2
3
  The `solidus_six_saferpay` engine adds checkout options for the Saferpay Payment Page ([Integration Guide](https://saferpay.github.io/sndbx/Integration_PP.html), [JSON API documentation](http://saferpay.github.io/jsonapi/#ChapterPaymentPage)) and the Saferpay Transaction ([Integration Guide](https://saferpay.github.io/sndbx/Integration_trx.html), [JSON API documentation](https://saferpay.github.io/sndbx/Integration_trx.html)).
3
4
 
5
+ ### Disclaimer
6
+ This gem is built to be a general-purpose integration of the Six Saferpay payment interface. However due to lack of resources and because we are (as far as we know) the only users of this gem, we are only testing our use cases (PaymentPage). Therefore we can not guarantee that this will work in any other solidus shop. If you consider using this gem, please test everything thoroughly.
7
+
4
8
  ## Status
5
9
  Travis CI status: [![Build Status](https://travis-ci.org/fadendaten/solidus_six_saferpay.svg?branch=master)](https://travis-ci.org/fadendaten/solidus_six_saferpay)
6
10
 
7
-
8
11
  ## Installation
9
- Add this line to your application's Gemfile:
12
+
13
+ Add solidus_six_saferpay to your Gemfile:
10
14
 
11
15
  ```ruby
12
16
  gem 'solidus_six_saferpay'
13
17
  ```
14
18
 
15
- And then execute:
16
-
17
- ```bash
18
- $ bundle
19
- ```
20
-
21
- Or install it yourself as:
19
+ Bundle your dependencies and run the installation generator:
22
20
 
23
- ```bash
24
- $ gem install solidus_six_saferpay
25
- ```
26
-
27
- After installing the gem, copy the migrations to your host application and migrate:
28
-
29
- ```bash
30
- $ bundle exec rails g solidus_six_saferpay:install
21
+ ```shell
22
+ bundle
23
+ bundle exec rails g solidus_six_saferpay:install
31
24
  ```
32
25
 
33
26
  Add the following javascript to your `application.js` manifest file below the `//= require spree` line:
@@ -60,7 +53,6 @@ Spree::Core::Engine.routes.default_url_options { 'http://localhost:3000' }
60
53
  Spree::Core::Engine.routes.default_url_options { 'https://url-to-your-solidus-shop.tld' }
61
54
  ```
62
55
 
63
-
64
56
  ## Configuration and Usage
65
57
  After adding the `solidus_six_saferpay` gem to your Solidus Rails app, you can create new payment methods `Saferpay Payment Page` and `Saferpay Transaction` in the admin backend under "Settings" > "Payment". When adding a new Saferpay payment method, you can configure the payment method with the information you have received from SIX when creating a new test account.
66
58
 
@@ -212,9 +204,33 @@ When the user confirms the purchase in the checkout process, the saferpay paymen
212
204
  #### Checkout: Payment Cancel
213
205
  When a user cancels a payment, the `CheckoutController` receives a `fail` request and handles this request in the `#fail` action. The result is that the user is shown an error message stating that the payment was aborted.
214
206
 
207
+
208
+ ## Testing
209
+
210
+ First bundle your dependencies, then run `rake`. `rake` will default to building the dummy app if it does not exist, then it will run specs, and [Rubocop](https://github.com/bbatsov/rubocop) static code analysis. The dummy app can be regenerated by using `rake test_app`.
211
+
212
+ ```shell
213
+ bundle
214
+ bin/rake
215
+ ```
216
+
217
+ When testing your application's integration with this extension you may use its factories.
218
+ Simply add this require statement to your spec_helper:
219
+
220
+ ```ruby
221
+ require 'solidus_six_saferpay/factories'
222
+ ```
223
+
215
224
  ## Contributing
216
225
  This gem is available for everyone to use, however chances are that its implementation is still tailored towards our custom solidus-based shop.
217
226
  If you see improvements to be made, feel free to fork the gem and submit pull requests. All incoming pull requests will be discussed, but it's possible that we will reject pull requests that break functionality for our use case.
218
227
 
219
- ## License
220
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
228
+ ## Releasing
229
+
230
+ Your new extension version can be released using `gem-release` like this:
231
+
232
+ ```shell
233
+ bundle exec gem bump -v VERSION --tag --push --remote upstream && gem release
234
+ ```
235
+
236
+ Copyright (c) 2020 fadendaten GmbH, released under the New BSD License
data/Rakefile CHANGED
@@ -1,56 +1,6 @@
1
- # begin
2
- # require 'bundler/setup'
3
- # rescue LoadError
4
- # puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
- # end
1
+ # frozen_string_literal: true
6
2
 
7
- # require 'rdoc/task'
3
+ require 'solidus_dev_support/rake_tasks'
4
+ SolidusDevSupport::RakeTasks.install
8
5
 
9
- # RDoc::Task.new(:rdoc) do |rdoc|
10
- # rdoc.rdoc_dir = 'rdoc'
11
- # rdoc.title = 'SolidusSixSaferpay'
12
- # rdoc.options << '--line-numbers'
13
- # rdoc.rdoc_files.include('README.md')
14
- # rdoc.rdoc_files.include('lib/**/*.rb')
15
- # end
16
-
17
- # APP_RAKEFILE = File.expand_path("spec/dummy/Rakefile", __dir__)
18
- # load 'rails/tasks/engine.rake'
19
-
20
- # load 'rails/tasks/statistics.rake'
21
-
22
- # require 'bundler/gem_tasks'
23
-
24
- # require 'rspec/core/rake_task'
25
- # RSpec::Core::RakeTask.new(:spec)
26
-
27
- # task default: :spec
28
-
29
- require 'bundler'
30
-
31
- Bundler::GemHelper.install_tasks
32
-
33
- begin
34
- require 'spree/testing_support/extension_rake'
35
- require 'rspec/core/rake_task'
36
-
37
- RSpec::Core::RakeTask.new(:spec)
38
-
39
- # task default: %i(first_run spec)
40
- task default: %i(first_run spec)
41
- rescue LoadError
42
- # no rspec available
43
- end
44
-
45
- task :first_run do
46
- if Dir['spec/dummy'].empty?
47
- Rake::Task[:test_app].invoke
48
- Dir.chdir('../../')
49
- end
50
- end
51
-
52
- desc 'Generates a dummy app for testing'
53
- task :test_app do
54
- ENV['LIB_NAME'] = 'solidus_six_saferpay'
55
- Rake::Task['extension:test_app'].invoke
56
- end
6
+ task default: 'extension:specs'
@@ -1,2 +1,3 @@
1
+ //= link_tree ../images
1
2
  //= link_directory ../javascripts/solidus_six_saferpay .js
2
3
  //= link_directory ../stylesheets/solidus_six_saferpay .css
@@ -18,7 +18,10 @@ let SaferpayPayment = {
18
18
  },
19
19
 
20
20
  error: function(xhr) {
21
- console.error(xhr.responseText);
21
+ // We have no other option for displaying this message, so to inform
22
+ // the user we must alert
23
+ alert(xhr.responseJSON.errors);
24
+ window.location.replace(xhr.responseJSON.redirect_url);
22
25
  return false;
23
26
  },
24
27
  })
@@ -0,0 +1,2 @@
1
+ // Placeholder manifest file.
2
+ // the installer will append this file to the app vendored assets here: vendor/assets/javascripts/spree/backend/all.js'
@@ -0,0 +1,2 @@
1
+ // Placeholder manifest file.
2
+ // the installer will append this file to the app vendored assets here: vendor/assets/javascripts/spree/frontend/all.js'
@@ -0,0 +1,4 @@
1
+ /*
2
+ Placeholder manifest file.
3
+ the installer will append this file to the app vendored assets here: 'vendor/assets/stylesheets/spree/backend/all.css'
4
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Placeholder manifest file.
3
+ the installer will append this file to the app vendored assets here: 'vendor/assets/stylesheets/spree/frontend/all.css'
4
+ */
@@ -2,11 +2,27 @@ module Spree
2
2
  module SolidusSixSaferpay
3
3
  class CheckoutController < StoreController
4
4
 
5
- before_action :load_order
6
-
7
- after_action :allow_embed, only: [:success, :fail]
8
-
9
5
  def init
6
+ order_number = params[:order_number]
7
+ @order = Spree::Order.find_by(number: order_number)
8
+
9
+ # We must make sure that the order for which the user requests a
10
+ # payment is still their `current_order`.
11
+ # This can be false if the user tries to add something to the cart
12
+ # after getting to the payment checkout step, and then switches back to
13
+ # the payment step and starts the payment process by selecting a
14
+ # payment method.
15
+ # In that case, we redirect to the checkout path so the user needs to
16
+ # go through the checkout process again to ensure that the real
17
+ # `current_order` contains all necessary information.
18
+ if @order.nil? || @order != current_order
19
+ render json: {
20
+ redirect_url: spree.cart_path,
21
+ errors: t('.order_was_modified_after_confirmation')
22
+ }, status: 422
23
+ return
24
+ end
25
+
10
26
  payment_method = Spree::PaymentMethod.find(params[:payment_method_id])
11
27
  initialized_payment = initialize_payment(@order, payment_method)
12
28
 
@@ -14,17 +30,49 @@ module Spree
14
30
  redirect_url = initialized_payment.redirect_url
15
31
  render json: { redirect_url: redirect_url }
16
32
  else
17
- render json: { errors: t('.checkout_not_initialized') }, status: 422
33
+ render json: {
34
+ redirect_url: spree.cart_path,
35
+ errors: t('.checkout_not_initialized')
36
+ }, status: 422
18
37
  end
19
38
  end
20
39
 
21
40
  def success
41
+ order_number = params[:order_number]
42
+ @order = Spree::Order.find_by(number: order_number)
43
+
44
+ if @order.nil?
45
+ handle_order_not_found(order_number)
46
+
47
+ flash[:error] = t('.error_while_processing_payment')
48
+ @redirect_path = spree.cart_path
49
+ render :iframe_breakout_redirect, layout: false
50
+ return
51
+ end
52
+
22
53
  saferpay_payment = Spree::SixSaferpayPayment.where(order_id: @order.id).order(:created_at).last
23
54
 
24
55
  if saferpay_payment.nil?
25
- raise Spree::Core::GatewayError, t('.payment_source_not_created')
56
+ handle_payment_not_found(@order)
57
+
58
+ flash[:error] = t('.error_while_processing_payment')
59
+ @redirect_path = spree.cart_path
60
+ render :iframe_breakout_redirect, layout: false
61
+ return
26
62
  end
27
63
 
64
+ # ensure that completed orders don't try to reprocess the
65
+ # authorization. This could happen if a user presses the back button
66
+ # after completing an order.
67
+ # There is no error handling because it should look like you are simply
68
+ # redirected to the cart page.
69
+ if @order.completed?
70
+ @redirect_path = spree.cart_path
71
+ render :iframe_breakout_redirect, layout: false
72
+ return
73
+ end
74
+
75
+
28
76
  # NOTE: PaymentPage payments are authorized directly. Instead, we
29
77
  # perform an ASSERT here to gather the necessary details.
30
78
  # This might be confusing at first, but doing it this way makes sense
@@ -40,7 +88,7 @@ module Spree
40
88
 
41
89
  processed_authorization = process_authorization(saferpay_payment)
42
90
  if processed_authorization.success?
43
- @order.next! if @order.payment?
91
+ handle_payment_processing_success
44
92
  else
45
93
  flash[:error] = processed_authorization.user_message
46
94
  end
@@ -50,27 +98,44 @@ module Spree
50
98
  flash[:error] = payment_inquiry.user_message
51
99
  end
52
100
 
53
- @redirect_path = order_checkout_path(@order.state)
101
+ @redirect_path ||= order_checkout_path(@order.state)
54
102
  render :iframe_breakout_redirect, layout: false
55
103
  end
56
104
 
57
105
  def fail
106
+ order_number = params[:order_number]
107
+ @order = Spree::Order.find_by(number: order_number)
108
+
109
+ if @order.nil?
110
+ handle_order_not_found(order_number)
111
+
112
+ flash[:error] = t('.error_while_processing_payment')
113
+ @redirect_path = spree.cart_path
114
+ render :iframe_breakout_redirect, layout: false
115
+ return
116
+ end
117
+
58
118
  saferpay_payment = Spree::SixSaferpayPayment.where(order_id: @order.id).order(:created_at).last
59
119
 
120
+ if saferpay_payment.nil?
121
+ handle_payment_not_found(@order)
122
+
123
+ flash[:error] = t('.error_while_processing_payment')
124
+ @redirect_path = spree.cart_path
125
+ render :iframe_breakout_redirect, layout: false
126
+ return
127
+ end
128
+
129
+
60
130
  payment_inquiry = inquire_payment(saferpay_payment)
131
+ flash[:error] = payment_inquiry.user_message
61
132
 
62
133
  @redirect_path = order_checkout_path(:payment)
63
- flash[:error] = payment_inquiry.user_message
64
134
  render :iframe_breakout_redirect, layout: false
65
135
  end
66
136
 
67
137
  private
68
138
 
69
- def allow_embed
70
- # allow response to be embedded in iFrame
71
- response.headers.except! 'X-Frame-Options'
72
- end
73
-
74
139
  def initialize_payment(order, payment_method)
75
140
  raise NotImplementedError, "Must be implemented in PaymentPageCheckoutController or TransactionCheckoutController"
76
141
  end
@@ -87,9 +152,60 @@ module Spree
87
152
  raise NotImplementedError, "Must be implemented in PaymentPageCheckoutController or TransactionCheckoutController"
88
153
  end
89
154
 
90
- def load_order
91
- @order = current_order
92
- redirect_to(spree.cart_path) && return unless @order
155
+ # Allows overriding of success behaviour in host application by setting
156
+ # SolidusSixSaferpay.config.payment_processing_order_not_found_handler
157
+ #
158
+ # If not overridden, it will call the configured error handler without actually raising any errors
159
+ #
160
+ # Example
161
+ # config.payment_processing_order_not_found_handler = Proc.new do |context, order_number|
162
+ # puts "No solidus order with this number: #{order_number}!"
163
+ # end
164
+ #
165
+ def handle_order_not_found(order_number)
166
+ if order_not_found_handler = ::SolidusSixSaferpay.config.payment_processing_order_not_found_handler.presence
167
+ order_not_found_handler.call(self, order_number)
168
+ else
169
+ ::SolidusSixSaferpay::ErrorHandler.handle(
170
+ StandardError.new("No solidus order could be found for number #{order_number}"),
171
+ level: :error
172
+ )
173
+ end
174
+ end
175
+
176
+ # Allows overriding of success behaviour in host application by setting
177
+ # SolidusSixSaferpay.config.payment_processing_payment_not_found_handler
178
+ #
179
+ # If not overridden, it will call the configured error handler without actually raising any errors
180
+ #
181
+ # Example
182
+ # config.payment_processing_payment_not_found_handler = Proc.new { |context, order| puts "No saferpay payment found for #{order}!" }
183
+ #
184
+ def handle_payment_not_found(order)
185
+ if payment_not_found_handler = ::SolidusSixSaferpay.config.payment_processing_payment_not_found_handler.presence
186
+ payment_not_found_handler.call(self, order)
187
+ else
188
+ ::SolidusSixSaferpay::ErrorHandler.handle(
189
+ StandardError.new("No Saferpay Payment found for order #{order.number}"),
190
+ level: :error
191
+ )
192
+ end
193
+ end
194
+
195
+ # Allows overriding of success behaviour in host application by setting
196
+ # SolidusSixSaferpay.config.payment_processing_success_handler
197
+ #
198
+ # If not overridden, it will ensure that the order state is no longer "payment"
199
+ #
200
+ # Example
201
+ # config.payment_processing_success_handler = Proc.new { |context, order| puts "Order #{order} has been successfully paid!" }
202
+ #
203
+ def handle_payment_processing_success
204
+ if success_handler = ::SolidusSixSaferpay.config.payment_processing_success_handler.presence
205
+ success_handler.call(self, @order)
206
+ else
207
+ @order.next! if @order.payment?
208
+ end
93
209
  end
94
210
 
95
211
  def order_checkout_path(state)