spree_ideal 2.4.0

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.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +12 -0
  5. data/LICENSE +22 -0
  6. data/README.md +69 -0
  7. data/Rakefile +17 -0
  8. data/app/assets/images/ideal_small.png +0 -0
  9. data/app/assets/javascripts/admin/spree_ideal.js +1 -0
  10. data/app/assets/javascripts/store/spree_ideal.js +1 -0
  11. data/app/assets/stylesheets/admin/spree_ideal.css +3 -0
  12. data/app/assets/stylesheets/store/spree_ideal.css +3 -0
  13. data/app/controllers/spree/checkout_controller_decorator.rb +21 -0
  14. data/app/controllers/spree/ideal_controller.rb +160 -0
  15. data/app/models/spree/hash_factory.rb +64 -0
  16. data/app/models/spree/locale_helper.rb +48 -0
  17. data/app/models/spree/order_decorator.rb +21 -0
  18. data/app/models/spree/payment_method/ideal.rb +15 -0
  19. data/app/models/spree/url_factory.rb +21 -0
  20. data/app/services/spree/ideal_service.rb +33 -0
  21. data/app/views/spree/admin/payments/source_forms/_ideal.html.erb +1 -0
  22. data/app/views/spree/admin/payments/source_views/_ideal.html.erb +2 -0
  23. data/app/views/spree/checkout/payment/_ideal.html.erb +6 -0
  24. data/config/locales/en.yml +24 -0
  25. data/config/routes.rb +6 -0
  26. data/db/migrate/20150505204200_add_ideal_data_to_payments.rb +9 -0
  27. data/lib/generators/spree_ideal/install/install_generator.rb +27 -0
  28. data/lib/spree_ideal.rb +2 -0
  29. data/lib/spree_ideal/engine.rb +26 -0
  30. data/lib/spree_ideal/factories.rb +10 -0
  31. data/script/rails +5 -0
  32. data/spec/models/spree/hash_factory_spec.rb +26 -0
  33. data/spec/models/spree/order_spec.rb +49 -0
  34. data/spec/models/spree/payment_method/ideal_spec.rb +77 -0
  35. data/spec/models/spree/url_factory_spec.rb +27 -0
  36. data/spec/services/spree/ideal_service_spec.rb +36 -0
  37. data/spec/spec_helper.rb +85 -0
  38. data/spree_ideal.gemspec +32 -0
  39. metadata +268 -0
@@ -0,0 +1,21 @@
1
+ Spree::Order.class_eval do
2
+
3
+ def last_payment_method
4
+ return nil if last_payment.blank?
5
+ return last_payment.payment_method
6
+ end
7
+
8
+ def last_payment
9
+ return nil if payments.blank?
10
+ return payments.last
11
+ end
12
+
13
+ def ideal_ref_number
14
+ if last_payment_method.present?
15
+ "#{number}"
16
+ else
17
+ number
18
+ end
19
+ end
20
+
21
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: UTF-8
2
+ module Spree
3
+ class PaymentMethod::Ideal < PaymentMethod::Check
4
+ preference :abn_url, :string, :default => "https://internetkassa.abnamro.nl/ncol/test/orderstandard.asp"
5
+ preference :pspid, :string, :default => ""
6
+ preference :accept_url, :string, :default => ""
7
+ preference :decline_url, :string, :default => ""
8
+ preference :exception_url, :string, :default => ""
9
+ preference :cancel_url, :string, :default => ""
10
+ preference :sha_in_pass_phrase, :string, :default => ""
11
+ preference :sha_out_pass_phrase, :string, :default => ""
12
+ preference :sha_algorithm, :string, :default => "SHA-1"
13
+ preference :shop_base_url, :string, :default => ""
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ class Spree::UrlFactory
2
+ def self.create_ideal_checkout_url_from_payment(order, ideal_payment_settings, hash, locale)
3
+
4
+ total = (order.total * 100).to_i # Convert according to
5
+
6
+ language = Spree::LocaleHelper.format_locale(locale)
7
+
8
+ url = ideal_payment_settings.preferred_abn_url + ""\
9
+ "?PSPID=" + ideal_payment_settings.preferred_pspid + ""\
10
+ "&ORDERID=" + order.number.to_s + ""\
11
+ "&AMOUNT=" + total.to_s + "" \
12
+ "&CURRENCY=" + Spree::Config.currency.to_s + "" \
13
+ "&LANGUAGE=" + language + ""\
14
+ "&SHASIGN=" + hash + ""\
15
+ "&ACCEPTURL=" + ideal_payment_settings.preferred_accept_url + ""\
16
+ "&DECLINEURL=" + ideal_payment_settings.preferred_decline_url + ""\
17
+ "&EXCEPTIONURL=" + ideal_payment_settings.preferred_exception_url + ""\
18
+ "&CANCELURL=" + ideal_payment_settings.preferred_cancel_url + ""\
19
+ "&BACKURL=" + ideal_payment_settings.preferred_shop_base_url + "/orders/#{order.number}"
20
+ end
21
+ end
@@ -0,0 +1,33 @@
1
+ require 'httparty'
2
+
3
+ module Spree
4
+ class IdealService
5
+
6
+ include Singleton
7
+
8
+ # make the initialization request
9
+ def initial_request order, ref_number=nil
10
+ init_data_by_order(order) # Some Validation
11
+ # Security Validations
12
+ raise I18n.t("ideal.no_sha_in_passphrase") if @order.last_payment.payment_method.preferred_sha_in_pass_phrase.blank?
13
+ raise I18n.t("ideal.no_sha_out_passphrase") if @order.last_payment.payment_method.preferred_sha_out_pass_phrase.blank?
14
+ raise I18n.t("ideal.invalid_hash_algorithm") unless ["SHA-1", "SHA-256", "SHA-512"].include?(@order.last_payment.payment_method.preferred_sha_algorithm)
15
+
16
+ # Hash
17
+ hash = Spree::HashFactory.create_hash(order, order.last_payment.payment_method, I18n.locale).upcase
18
+ order.last_payment.update_attribute(:ideal_hash, hash)
19
+ order.save!
20
+ end
21
+
22
+ private
23
+
24
+ def init_data_by_order(order)
25
+ raise I18n.t("ideal.no_order_given") if order.blank?
26
+ @order = order
27
+
28
+ raise I18n.t("ideal.order_has_no_payment") if @order.last_payment.blank?
29
+ raise I18n.t("ideal.order_has_no_payment_method") if @order.last_payment_method.blank?
30
+ raise I18n.t("ideal.orders_payment_method_is_not_ideal") unless @order.last_payment_method.kind_of? Spree::PaymentMethod::Ideal
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,2 @@
1
+ <h4><%= I18n.t("ideal.transactionmsgs") %> <%= payment.ideal_transaction %>: </h4>
2
+ <p>Log: <%= simple_format(payment.ideal_log) %></p>
@@ -0,0 +1,6 @@
1
+ <div class="ideal">
2
+ <p><%= I18n.t("ideal.name") %><p>
3
+ <%= image_tag "http://www.ideal.nl/cms/themes/ideal_nl/img/ideal_logo.png" %>
4
+ <p><%= I18n.t("ideal.desc") %></p>
5
+ <p>&nbsp;</p>
6
+ </div>
@@ -0,0 +1,24 @@
1
+ de:
2
+ ideal:
3
+ name: "iDEAL"
4
+ desc: "Use iDEAL to pay with your Bank Account"
5
+ completed_successfully: "iDEAL payment processed successfully"
6
+ canceled: "iDEAL payment canceled"
7
+ payment_not_found: "payment data for iDEAL payment could not be found"
8
+ order_not_found: "order for iDEAL payment could not be found"
9
+ no_payment_given: "no payment given"
10
+ no_payment_method_given: "no payment method given"
11
+ wrong_payment_method_given: "wrong payment method given"
12
+ no_order_given: "no order given"
13
+ order_has_no_payment: "order has no payment"
14
+ order_has_no_payment_method: "order has no payment method"
15
+ orders_payment_method_is_not_ideal: "orders payment method is not iDEAL payment"
16
+ transactionmsgs: "Transactions for iDEAL Transaction-ID"
17
+ order_invalid_state: "The order state is invalid to carry out this step"
18
+ order_invalid_setup: "The setup of iDEAL is invalid. Please get in touch with the site administrator"
19
+ security_error: "A security issue occurred. Please get in touch with the site administrator"
20
+ decline: "The payment was declined"
21
+ exception: "An Exception Occurred when updating the payment"
22
+ no_sha_in_passphrase: "The site administrator did not set security settings correctly"
23
+ no_sha_out_passphrase: "The site administrator did not set security settings correctly"
24
+ invalid_hash_algorithm: "The site administrator did not set security settings correctly"
@@ -0,0 +1,6 @@
1
+ Spree::Core::Engine.routes.draw do
2
+ get '/ideal/accept', :to => 'ideal#success'
3
+ get '/ideal/decline', :to => 'ideal#decline'
4
+ get '/ideal/exception', :to => 'ideal#exception'
5
+ get '/ideal/cancel', :to => 'ideal#cancel'
6
+ end
@@ -0,0 +1,9 @@
1
+ class AddIdealDataToPayments < ActiveRecord::Migration
2
+
3
+ def change
4
+ add_column :spree_payments, :ideal_hash, :string
5
+ add_column :spree_payments, :ideal_transaction, :string
6
+ add_column :spree_payments, :ideal_log, :string
7
+ end
8
+
9
+ end
@@ -0,0 +1,27 @@
1
+ module SpreeIdeal
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+
5
+ class_option :auto_run_migrations, :type => :boolean, :default => false
6
+
7
+ def add_javascripts
8
+ end
9
+
10
+ def add_stylesheets
11
+ end
12
+
13
+ def add_migrations
14
+ run 'bundle exec rake railties:install:migrations FROM=spree_ideal'
15
+ end
16
+
17
+ def run_migrations
18
+ run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask 'Would you like to run the migrations now? [Y/n]')
19
+ if run_migrations
20
+ run 'bundle exec rake db:migrate'
21
+ else
22
+ puts 'Skipping rake db:migrate, don\'t forget to run it!'
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,2 @@
1
+ require 'spree_core'
2
+ require 'spree_ideal/engine'
@@ -0,0 +1,26 @@
1
+ module SpreeIdeal
2
+ class Engine < Rails::Engine
3
+ require 'spree/core'
4
+ isolate_namespace Spree
5
+ engine_name 'spree_ideal'
6
+
7
+ config.autoload_paths += %W(#{config.root}/lib)
8
+
9
+ config.generators do |g|
10
+ g.test_framework :rspec
11
+ end
12
+
13
+ def self.activate
14
+ Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
15
+ Rails.configuration.cache_classes ? require(c) : load(c)
16
+ end
17
+ end
18
+
19
+ config.to_prepare &method(:activate).to_proc
20
+
21
+ initializer "spree_ideal.register.payment_methods", :after => 'spree.register.payment_methods' do |app|
22
+ app.config.spree.payment_methods += [Spree::PaymentMethod::Ideal]
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,10 @@
1
+ FactoryGirl.define do
2
+
3
+ factory :ideal, class: Spree::PaymentMethod::Ideal do
4
+ name "iDEAL payment"
5
+ type "Spree::PaymentMethod::Ideal"
6
+ active true
7
+ environment "test"
8
+ end
9
+
10
+ end
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ ENGINE_PATH = File.expand_path('../..', __FILE__)
5
+ load File.expand_path('../../spec/dummy/script/rails', __FILE__)
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::HashFactory do
4
+
5
+ before(:each) do
6
+ @order = FactoryGirl.create(:order)
7
+ @payment_method = FactoryGirl.create(:ideal)
8
+ end
9
+
10
+ #-------------------------------------------------------------------------------------------------
11
+ context "create hash" do
12
+ it "regular hash" do
13
+ @order.number = 10
14
+ @order.total = 10.00
15
+ hash = Spree::HashFactory.create_hash(@order, @payment_method, "en")
16
+ hash.should eql("549eb11425c906d8e0b86e7d75e1ef2a2bae73ba")
17
+ end
18
+
19
+ end
20
+ #-------------------------------------------------------------------------------------------------
21
+ after(:each) do
22
+ @order.destroy
23
+ @payment_method.destroy
24
+ end
25
+
26
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Order do
4
+
5
+ before(:each) do
6
+ @order = FactoryGirl.create(:order)
7
+ @payment_method = FactoryGirl.create(:ideal)
8
+ end
9
+
10
+ #-------------------------------------------------------------------------------------------------
11
+ context "it has no payment" do
12
+ it "last payment is null" do
13
+ @order.last_payment.should be_nil
14
+ end
15
+
16
+ it "last payment method is null" do
17
+ @order.last_payment_method.should be_nil
18
+ end
19
+
20
+ it "ideal ref number is only order number" do
21
+ @order.ideal_ref_number.should eql(@order.number);
22
+ end
23
+
24
+ end
25
+ #-------------------------------------------------------------------------------------------------
26
+ context "it has a valid payment" do
27
+ before(:each) do
28
+ @payment = FactoryGirl.create(:payment, order: @order, payment_method: @payment_method)
29
+ end
30
+
31
+ it "last payment is given" do
32
+ @order.last_payment.should_not be_nil
33
+ end
34
+
35
+ it "last payment method is given" do
36
+ @order.last_payment_method.should_not be_nil
37
+ end
38
+
39
+ after(:each) do
40
+ @payment.destroy
41
+ end
42
+ end
43
+ #-------------------------------------------------------------------------------------------------
44
+ after(:each) do
45
+ @order.destroy
46
+ @payment_method.destroy
47
+ end
48
+
49
+ end
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::PaymentMethod::Ideal do
4
+
5
+ before(:all) do
6
+ @ideal = create(:ideal)
7
+ end
8
+
9
+ describe "save preferences" do
10
+
11
+ it "can save abn_url" do
12
+ @ideal.set_preference(:abn_url, "the url")
13
+ @ideal.save!
14
+ @ideal.get_preference(:abn_url).should eql("the url")
15
+ end
16
+
17
+ it "can save pspid" do
18
+ @ideal.set_preference(:pspid, "the url")
19
+ @ideal.save!
20
+ @ideal.get_preference(:pspid).should eql("the url")
21
+ end
22
+
23
+ it "can save accept_url" do
24
+ @ideal.set_preference(:accept_url, "the url")
25
+ @ideal.save!
26
+ @ideal.get_preference(:accept_url).should eql("the url")
27
+ end
28
+
29
+ it "can save decline_url" do
30
+ @ideal.set_preference(:decline_url, "the url")
31
+ @ideal.save!
32
+ @ideal.get_preference(:decline_url).should eql("the url")
33
+ end
34
+
35
+ it "can save exception_url" do
36
+ @ideal.set_preference(:exception_url, "the url")
37
+ @ideal.save!
38
+ @ideal.get_preference(:exception_url).should eql("the url")
39
+ end
40
+
41
+ it "can save cancel_url" do
42
+ @ideal.set_preference(:cancel_url, "the url")
43
+ @ideal.save!
44
+ @ideal.get_preference(:cancel_url).should eql("the url")
45
+ end
46
+
47
+ it "can save sha_in_pass_phrase" do
48
+ @ideal.set_preference(:sha_in_pass_phrase, "the pass phrase")
49
+ @ideal.save!
50
+ @ideal.get_preference(:sha_in_pass_phrase).should eql("the pass phrase")
51
+ end
52
+
53
+ it "can save sha_out_pass_phrase" do
54
+ @ideal.set_preference(:sha_out_pass_phrase, "the sha_out_pass_phrase")
55
+ @ideal.save!
56
+ @ideal.get_preference(:sha_out_pass_phrase).should eql("the sha_out_pass_phrase")
57
+ end
58
+
59
+ it "can save sha_algorithm" do
60
+ @ideal.set_preference(:sha_algorithm, "the sha_algorithm")
61
+ @ideal.save!
62
+ @ideal.get_preference(:sha_algorithm).should eql("the sha_algorithm")
63
+ end
64
+
65
+ it "can save shop_base_url" do
66
+ @ideal.set_preference(:shop_base_url, "the shop_base_url")
67
+ @ideal.save!
68
+ @ideal.get_preference(:shop_base_url).should eql("the shop_base_url")
69
+ end
70
+
71
+ end
72
+
73
+ after(:all) do
74
+ @ideal.destroy
75
+ end
76
+
77
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::UrlFactory do
4
+
5
+ before(:each) do
6
+ @order = FactoryGirl.create(:order)
7
+ @payment_method = FactoryGirl.create(:ideal)
8
+ end
9
+
10
+ #-------------------------------------------------------------------------------------------------
11
+ context "create hash" do
12
+ it "regular hash" do
13
+ @order.number = 10
14
+ @order.total = 10.00
15
+ hash = Spree::HashFactory.create_hash(@order, @payment_method, "en")
16
+ url = Spree::UrlFactory.create_ideal_checkout_url_from_payment(@order, @payment_method, hash, "en")
17
+ url.should eql("https://internetkassa.abnamro.nl/ncol/test/orderstandard.asp?PSPID=&ORDERID=1&AMOUNT=1000&CURRENCY=USD&LANGUAGE=en_US&SHASIGN=549eb11425c906d8e0b86e7d75e1ef2a2bae73ba&ACCEPTURL=&DECLINEURL=&EXCEPTIONURL=&CANCELURL=&BACKURL=/orders/10")
18
+ end
19
+
20
+ end
21
+ #-------------------------------------------------------------------------------------------------
22
+ after(:each) do
23
+ @order.destroy
24
+ @payment_method.destroy
25
+ end
26
+
27
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::IdealService do
4
+
5
+ before(:each) do
6
+ @order = create(:order_with_line_items)
7
+ @ideal = create(:ideal)
8
+ end
9
+
10
+ describe "initial_request" do
11
+
12
+ context "fail" do
13
+
14
+ it "raise null order exception" do
15
+ expect {
16
+ Spree::IdealService.instance.initial_request(nil)
17
+ }.to raise_error(RuntimeError, "no order given")
18
+ end
19
+
20
+ it "raises no payment exception" do
21
+ expect {
22
+ Spree::IdealService.instance.initial_request(@order)
23
+ }.to raise_error(RuntimeError, "order has no payment")
24
+ end
25
+
26
+ end # context fail
27
+
28
+ end
29
+
30
+
31
+ after(:each) do
32
+ @order.destroy
33
+ @ideal.destroy
34
+ end
35
+
36
+ end