spree_omnikassa 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +11 -0
- data/.rspec +1 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +224 -0
- data/LICENSE +26 -0
- data/README.md +36 -0
- data/Rakefile +29 -0
- data/Versionfile +9 -0
- data/app/assets/javascripts/admin/spree_omnikassa.js +1 -0
- data/app/assets/javascripts/store/spree_omnikassa.js +1 -0
- data/app/assets/stylesheets/admin/spree_omnikassa.css +3 -0
- data/app/assets/stylesheets/store/spree_omnikassa.css +3 -0
- data/app/controllers/spree/checkout_controller_decorator.rb +10 -0
- data/app/controllers/spree/omnikassa_payments_controller.rb +97 -0
- data/app/models/spree/omnikassa_payment_request.rb +89 -0
- data/app/models/spree/omnikassa_payment_response.rb +129 -0
- data/app/models/spree/order_decorator.rb +33 -0
- data/app/models/spree/payment_method/omnikassa.rb +39 -0
- data/app/views/spree/checkout/omnikassa_edit.html.erb +36 -0
- data/config/locales/en.yml +5 -0
- data/config/routes.rb +5 -0
- data/lib/generators/spree_omnikassa/install/install_generator.rb +29 -0
- data/lib/spree_omnikassa.rb +26 -0
- data/script/rails +5 -0
- data/spec/controllers/spree/checkout_controller_spec.rb +28 -0
- data/spec/controllers/spree/omnikassa_payments_controller_spec.rb +198 -0
- data/spec/functional/spree_omnikassa_checkout_decorator_spec.rb +10 -0
- data/spec/integration/spree_omnikassa_checkout_spec.rb +10 -0
- data/spec/models/spree_omnikassa_payment_request_spec.rb +93 -0
- data/spec/models/spree_omnikassa_payment_response_spec.rb +144 -0
- data/spec/models/spree_payment_method_omnikassa_spec.rb +72 -0
- data/spec/spec_helper.rb +79 -0
- data/spree_omnikassa.gemspec +19 -0
- metadata +114 -0
@@ -0,0 +1,89 @@
|
|
1
|
+
module Spree
|
2
|
+
# OmnikassaPaymentRequest deals with the data
|
3
|
+
# for the actual request to and fro Omnikassa.
|
4
|
+
#
|
5
|
+
# Not a persistent object: will not interact or
|
6
|
+
# get saved in the database.
|
7
|
+
#
|
8
|
+
# It requires amount and order_id to be passed in
|
9
|
+
# on creation.
|
10
|
+
class OmnikassaPaymentRequest
|
11
|
+
include Spree::Core::Engine.routes.url_helpers
|
12
|
+
attr_accessor :amount, :order_id, :payment_method
|
13
|
+
|
14
|
+
def initialize(amount, transaction_reference, response_code = nil)
|
15
|
+
@payment_method = Spree::PaymentMethod::Omnikassa.fetch_payment_method
|
16
|
+
if transaction_reference.to_s.include? merchant_id
|
17
|
+
@amount = amount
|
18
|
+
@order_id = transaction_reference.to_s.match(merchant_id).post_match
|
19
|
+
@response_code = response_code
|
20
|
+
else
|
21
|
+
raise "transactionReference cannot be parsed"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Generates datastring according to omnikassa
|
26
|
+
# requirements §9. name=value|name=value.
|
27
|
+
def data
|
28
|
+
"amount=#{amount}|orderId=#{order_id}|currencyCode=#{currency_code}|merchantId=#{merchant_id}|normalReturnUrl=#{normal_return_url}|automaticResponseUrl=#{automatic_response_url}|transactionReference=#{transaction_reference}|keyVersion=#{key_version}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def interface_version
|
32
|
+
"HP_1.0"
|
33
|
+
end
|
34
|
+
|
35
|
+
def seal
|
36
|
+
::Digest::SHA2.hexdigest(data + @payment_method.preferred_secret_key)
|
37
|
+
end
|
38
|
+
|
39
|
+
# to_s magic method simply wraps the data string generator.
|
40
|
+
def to_s
|
41
|
+
data
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.build_transaction_reference order_id
|
45
|
+
@payment_method ||= Spree::PaymentMethod::Omnikassa.fetch_payment_method
|
46
|
+
@payment_method.preferred_merchant_id + order_id.to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
# @TODO implement size and format validation acc to §9.2.
|
51
|
+
|
52
|
+
def amount
|
53
|
+
(@amount * 100).to_i
|
54
|
+
end
|
55
|
+
|
56
|
+
def order_id
|
57
|
+
@order_id
|
58
|
+
end
|
59
|
+
|
60
|
+
# @TODO implement currency lookup from locales and map to table in §9.3.
|
61
|
+
def currency_code *args
|
62
|
+
978 #hardcoded to Euro.
|
63
|
+
end
|
64
|
+
|
65
|
+
def merchant_id
|
66
|
+
@payment_method.preferred_merchant_id
|
67
|
+
end
|
68
|
+
|
69
|
+
def normal_return_url
|
70
|
+
return_url_for_action "homecoming"
|
71
|
+
end
|
72
|
+
|
73
|
+
def automatic_response_url
|
74
|
+
return_url_for_action "reply"
|
75
|
+
end
|
76
|
+
|
77
|
+
def return_url_for_action action
|
78
|
+
url_for(:controller => 'spree/omnikassa_payments', :action => action, :host => Spree::Config.preferred_site_url)
|
79
|
+
end
|
80
|
+
|
81
|
+
def transaction_reference
|
82
|
+
Spree::OmnikassaPaymentRequest.build_transaction_reference order_id
|
83
|
+
end
|
84
|
+
|
85
|
+
def key_version
|
86
|
+
@payment_method.preferred_key_version
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module Spree
|
2
|
+
class OmnikassaPaymentResponse
|
3
|
+
attr_accessor :data
|
4
|
+
attr_reader :seal, :attributes, :payment_method
|
5
|
+
|
6
|
+
def initialize seal, data
|
7
|
+
@payment_method = Spree::PaymentMethod::Omnikassa.fetch_payment_method
|
8
|
+
@seal = seal
|
9
|
+
@data = data
|
10
|
+
@attributes = to_h
|
11
|
+
end
|
12
|
+
|
13
|
+
def valid?
|
14
|
+
return false unless @seal == ::Digest::SHA2.hexdigest(@data + @payment_method.preferred_secret_key)
|
15
|
+
|
16
|
+
required_attributes.each do |required_attribute|
|
17
|
+
return false unless @attributes.has_key? required_attribute.underscore.to_sym
|
18
|
+
end
|
19
|
+
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
# Finds a payment with provided parameters trough activeRecord.
|
24
|
+
def payment
|
25
|
+
Spree::Payment.find(:first, :conditions => {
|
26
|
+
:payment_method_id => @payment_method.id,
|
27
|
+
:order_id => @attributes[:order_id]} ) || raise(ActiveRecord::RecordNotFound)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Finds the order trough ActiveRecord
|
31
|
+
def order
|
32
|
+
Spree::Order.find(@attributes[:order_id].to_i)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Level can be :success, :pending, :cancelled or :failed
|
36
|
+
def response_level
|
37
|
+
response_codes.each do |level, codes|
|
38
|
+
if codes.include?(@attributes[:response_code].to_i)
|
39
|
+
return level
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
def to_h
|
48
|
+
h = Hash.new
|
49
|
+
@data.split("|").each do |s|
|
50
|
+
k,v = s.split("=")
|
51
|
+
key = k.underscore
|
52
|
+
preparator = "prepare_#{key}"
|
53
|
+
if self.respond_to? preparator, true
|
54
|
+
v = self.send(preparator, v)
|
55
|
+
end
|
56
|
+
h[key.to_sym] = v if valid_attributes.include? k
|
57
|
+
end
|
58
|
+
h
|
59
|
+
end
|
60
|
+
|
61
|
+
# Callback for the to_h.
|
62
|
+
# Converts the amount to BigDecimal and from cents to currency.
|
63
|
+
def prepare_amount amount
|
64
|
+
BigDecimal.new(amount)/100
|
65
|
+
end
|
66
|
+
|
67
|
+
# As per "Tabel 5: Gegevenswoordenboek - beschrijving velden"
|
68
|
+
# from Rabo_OmniKassa_Integratiehandleiding_v200.pdf
|
69
|
+
def valid_attributes
|
70
|
+
%w[
|
71
|
+
amount
|
72
|
+
authorisationId
|
73
|
+
automaticResponseUrl
|
74
|
+
captureDay
|
75
|
+
captureMode
|
76
|
+
complementaryCode
|
77
|
+
complementaryInfo
|
78
|
+
currencyCode
|
79
|
+
customerLanguage
|
80
|
+
expirationdate
|
81
|
+
keyVersion
|
82
|
+
maskedPan
|
83
|
+
merchantId
|
84
|
+
normalReturnUrl
|
85
|
+
orderId
|
86
|
+
paymentMeanBrand
|
87
|
+
paymentMeanBrandList
|
88
|
+
paymentMeanType
|
89
|
+
responseCode
|
90
|
+
transactionDateTime
|
91
|
+
transactionReference
|
92
|
+
]
|
93
|
+
end
|
94
|
+
|
95
|
+
# attributes required for working of the class.
|
96
|
+
def required_attributes
|
97
|
+
%w[
|
98
|
+
amount
|
99
|
+
transactionReference
|
100
|
+
orderId
|
101
|
+
responseCode
|
102
|
+
]
|
103
|
+
end
|
104
|
+
|
105
|
+
def response_codes
|
106
|
+
{
|
107
|
+
:success => [00],
|
108
|
+
:pending => [
|
109
|
+
90,
|
110
|
+
99],
|
111
|
+
:cancelled => [
|
112
|
+
14, #invalid CSC or CVV
|
113
|
+
17, #cancelled by user
|
114
|
+
75], #number attempts to enter cardnumer exceeded.
|
115
|
+
:failed => [
|
116
|
+
02,
|
117
|
+
03,
|
118
|
+
05,
|
119
|
+
12,
|
120
|
+
30,
|
121
|
+
34,
|
122
|
+
40,
|
123
|
+
63,
|
124
|
+
94,
|
125
|
+
97]
|
126
|
+
}
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
Spree::Order.class_eval do
|
2
|
+
# StateMachine::Machine.ignore_method_conflicts = true
|
3
|
+
# Spree::Order.state_machines[:state] = StateMachine::Machine.new(Spree::Order, :initial => 'cart', :use_transactions => false) do
|
4
|
+
# event :next do
|
5
|
+
# transition :from => 'cart', :to => 'address'
|
6
|
+
# transition :from => 'address', :to => 'delivery'
|
7
|
+
# transition :from => 'delivery', :to => 'complete'
|
8
|
+
# transition :from => 'confirm', :to => 'complete'
|
9
|
+
# end
|
10
|
+
|
11
|
+
# event :cancel do
|
12
|
+
# transition :to => 'canceled', :if => :allow_cancel?
|
13
|
+
# end
|
14
|
+
# event :return do
|
15
|
+
# transition :to => 'returned', :from => 'awaiting_return'
|
16
|
+
# end
|
17
|
+
# event :resume do
|
18
|
+
# transition :to => 'resumed', :from => 'canceled', :if => :allow_resume?
|
19
|
+
# end
|
20
|
+
# event :authorize_return do
|
21
|
+
# transition :to => 'awaiting_return'
|
22
|
+
# end
|
23
|
+
|
24
|
+
# before_transition :to => ['delivery'] do |order|
|
25
|
+
# order.shipments.each { |s| s.destroy unless s.shipping_method.available_to_order?(order) }
|
26
|
+
# end
|
27
|
+
|
28
|
+
# after_transition :to => 'complete', :do => :finalize!
|
29
|
+
# after_transition :to => 'delivery', :do => :create_tax_charge!
|
30
|
+
# after_transition :to => 'resumed', :do => :after_resume
|
31
|
+
# after_transition :to => 'canceled', :do => :after_cancel
|
32
|
+
# end
|
33
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Spree
|
2
|
+
class PaymentMethod::Omnikassa < PaymentMethod
|
3
|
+
preference :merchant_id, :string, :default => "002020000000001"
|
4
|
+
preference :key_version, :integer, :default => 1
|
5
|
+
preference :secret_key, :string, :default => "002020000000001_KEY1"
|
6
|
+
|
7
|
+
def actions
|
8
|
+
%w{capture}
|
9
|
+
end
|
10
|
+
|
11
|
+
def can_capture?(payment)
|
12
|
+
['checkout', 'pending'].include?(payment.state)
|
13
|
+
end
|
14
|
+
|
15
|
+
def capture(payment)
|
16
|
+
#payments with state "checkout" must be moved into state "pending" first:
|
17
|
+
payment.update_attribute(:state, "pending") if payment.state == "checkout"
|
18
|
+
payment.complete
|
19
|
+
true
|
20
|
+
end
|
21
|
+
|
22
|
+
def source_required?
|
23
|
+
false
|
24
|
+
end
|
25
|
+
|
26
|
+
def url
|
27
|
+
if self.environment == "production"
|
28
|
+
"https://payment-webinit.omnikassa.rabobank.nl/paymentServlet"
|
29
|
+
else
|
30
|
+
"https://payment-webinit.simu.omnikassa.rabobank.nl/paymentServlet"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.fetch_payment_method
|
35
|
+
name = "Omnikassa"
|
36
|
+
Spree::PaymentMethod.find(:first, :conditions => [ "lower(name) = ?", name.downcase ]) || raise(ActiveRecord::RecordNotFound)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<% content_for :head do %>
|
2
|
+
<%= javascript_include_tag states_path %>
|
3
|
+
<% end %>
|
4
|
+
<div id="checkout" data-hook>
|
5
|
+
<%= render :partial => 'spree/shared/error_messages', :locals => { :target => @order } %>
|
6
|
+
|
7
|
+
<h1 data-hook="checkout_title"><%= t(:checkout) %></h1>
|
8
|
+
<ul id="checkout-steps-<%= @order.state %>" class="breadcrumbs progress-steps">
|
9
|
+
<% checkout_progress_states.each do |state| %>
|
10
|
+
<li class="<%= state.classes.join(" ") %>">
|
11
|
+
<%= state.text %>
|
12
|
+
</li>
|
13
|
+
<% end %>
|
14
|
+
</ul>
|
15
|
+
|
16
|
+
<%= form_tag(@payment_request.payment_method.url, :method => :post) do %>
|
17
|
+
<div class="row" data-hook="checkout_content">
|
18
|
+
<div class="six columns" data-hook="checkout_form_wrapper">
|
19
|
+
<p><%= t(:payment_options) %></p>
|
20
|
+
<div data-hook="checkout_payment_step">
|
21
|
+
<%= image_submit_tag("payment_logos.png") %>
|
22
|
+
<p class="note"><%= t(:payment_goes_offsite) %></p>
|
23
|
+
<%= hidden_field_tag "Data", @payment_request.data %>
|
24
|
+
<%= hidden_field_tag "InterfaceVersion", @payment_request.interface_version %>
|
25
|
+
<%= hidden_field_tag "Seal", @payment_request.seal %>
|
26
|
+
<div data-hook="coupon_code_field" data-hook></div>
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
<div class="six columns">
|
30
|
+
<%= render :partial => 'summary', :locals => { :order => @order } %>
|
31
|
+
<%= submit_tag t(:save_and_continue), :class => 'continue button fullwidth' %>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
</div>
|
35
|
+
<% end %>
|
36
|
+
</div>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module SpreeOmnikassa
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
|
5
|
+
def add_javascripts
|
6
|
+
append_file "app/assets/javascripts/store/all.js", "//= require store/spree_omnikassa\n"
|
7
|
+
append_file "app/assets/javascripts/admin/all.js", "//= require admin/spree_omnikassa\n"
|
8
|
+
end
|
9
|
+
|
10
|
+
def add_stylesheets
|
11
|
+
inject_into_file "app/assets/stylesheets/store/all.css", " *= require store/spree_omnikassa\n", :before => /\*\//, :verbose => true
|
12
|
+
inject_into_file "app/assets/stylesheets/admin/all.css", " *= require admin/spree_omnikassa\n", :before => /\*\//, :verbose => true
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_migrations
|
16
|
+
run 'bundle exec rake railties:install:migrations FROM=spree_omnikassa'
|
17
|
+
end
|
18
|
+
|
19
|
+
def run_migrations
|
20
|
+
res = ask "Would you like to run the migrations now? [Y/n]"
|
21
|
+
if res == "" || res.downcase == "y"
|
22
|
+
run 'bundle exec rake db:migrate'
|
23
|
+
else
|
24
|
+
puts "Skiping rake db:migrate, don't forget to run it!"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spree_core'
|
2
|
+
|
3
|
+
module SpreeOmnikassa
|
4
|
+
class Engine < Rails::Engine
|
5
|
+
engine_name 'spree_omnikassa'
|
6
|
+
|
7
|
+
config.autoload_paths += %W(#{config.root}/lib)
|
8
|
+
|
9
|
+
# use rspec for tests
|
10
|
+
config.generators do |g|
|
11
|
+
g.test_framework :rspec
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.activate
|
15
|
+
Dir.glob(File.join(File.dirname(__FILE__), "../app/**/*_decorator*.rb")) do |c|
|
16
|
+
Rails.configuration.cache_classes ? require(c) : load(c)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
config.to_prepare &method(:activate).to_proc
|
21
|
+
|
22
|
+
initializer "spree.register.payment_methods" do |app|
|
23
|
+
app.config.spree.payment_methods << Spree::PaymentMethod::Omnikassa
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/script/rails
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Spree::CheckoutController do
|
4
|
+
before(:each) do
|
5
|
+
@pm = Spree::PaymentMethod::Omnikassa.new(:name => "Omnikassa", :environment => "test")
|
6
|
+
@pm.save
|
7
|
+
@pm.preferred_merchant_id = @merchant_id
|
8
|
+
@pm.preferred_key_version = @key_version
|
9
|
+
@pm.preferred_secret_key = @secret_key
|
10
|
+
@routes = Spree::Core::Engine.routes # render_views
|
11
|
+
end
|
12
|
+
let(:order) { mock_model(Spree::Order,
|
13
|
+
:checkout_allowed? => true,
|
14
|
+
:completed? => false,
|
15
|
+
:update_attributes => true,
|
16
|
+
:payment? => false,
|
17
|
+
:insufficient_stock_lines => [],
|
18
|
+
:coupon_code => nil,
|
19
|
+
:state => "payment",
|
20
|
+
:total => BigDecimal("123.45"),
|
21
|
+
:payments => []).as_null_object }
|
22
|
+
before { controller.stub :current_order => order, :current_user => Spree::User.anonymous! }
|
23
|
+
|
24
|
+
it 'should show omnikassa form on payment' do
|
25
|
+
get :edit, {:state => 'payment'}
|
26
|
+
response.should render_template('spree/checkout/omnikassa_edit')
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Spree::OmnikassaPaymentsController do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@routes = Spree::Core::Engine.routes
|
7
|
+
|
8
|
+
@merchant_id = "123abc"
|
9
|
+
@key_version = "1"
|
10
|
+
@secret_key = "002020000000001_KEY1"
|
11
|
+
|
12
|
+
@pm = Spree::PaymentMethod::Omnikassa.new(:name => "Omnikassa", :environment => "test")
|
13
|
+
@pm.save
|
14
|
+
@pm.preferred_merchant_id = @merchant_id
|
15
|
+
@pm.preferred_key_version = @key_version
|
16
|
+
@pm.preferred_secret_key = @secret_key
|
17
|
+
|
18
|
+
Spree::Order.stub(:create_user)
|
19
|
+
Spree::Order.any_instance.stub(:payment_required?).and_return(true)
|
20
|
+
@order = Spree::Order.new(:email => "foo@example.com", :state => "delivery")
|
21
|
+
@order.save!
|
22
|
+
|
23
|
+
@data = "amount=24900|captureDay=0|captureMode=AUTHOR_CAPTURE|currencyCode=978|merchantId=002020000000001|orderId=#{@order.id}|transactionDateTime=2012-04-25T14:41:01+02:00|transactionReference=0020200000000011028|keyVersion=1|authorisationId=0020000006791167|paymentMeanBrand=IDEAL|paymentMeanType=CREDIT_TRANSFER|responseCode=00"
|
24
|
+
@seal = ::Digest::SHA2.hexdigest(@data + @secret_key)
|
25
|
+
|
26
|
+
@params = {
|
27
|
+
"InterfaceVersion" => "HP_1.0",
|
28
|
+
"Data" => @data,
|
29
|
+
"Encode" => "",
|
30
|
+
"Seal" => @seal
|
31
|
+
}
|
32
|
+
@payment_response = Spree::OmnikassaPaymentResponse.new(@params['Seal'], @params['Data'])
|
33
|
+
@payment = Spree::Payment.new(
|
34
|
+
:amount => @payment_response.attributes[:amount],
|
35
|
+
:payment_method_id => 200123
|
36
|
+
)
|
37
|
+
@payment.order_id = @payment_response.attributes[:order_id]
|
38
|
+
@payment.id = 1234
|
39
|
+
|
40
|
+
Spree::Payment.stub(:new).and_return(@payment)
|
41
|
+
|
42
|
+
Spree::OmnikassaPaymentResponse.any_instance.stub(:payment).and_return(@payment)
|
43
|
+
end
|
44
|
+
|
45
|
+
response_args = %w[
|
46
|
+
Data
|
47
|
+
Seal
|
48
|
+
]
|
49
|
+
|
50
|
+
response_codes = {
|
51
|
+
:success => [00],
|
52
|
+
:pending => [
|
53
|
+
90,
|
54
|
+
99],
|
55
|
+
:cancelled => [
|
56
|
+
14, #invalid CSC or CVV
|
57
|
+
17, #cancelled by user
|
58
|
+
75], #number attempts to enter cardnumer exceeded.
|
59
|
+
:failed => [
|
60
|
+
02,
|
61
|
+
03,
|
62
|
+
05,
|
63
|
+
12,
|
64
|
+
30,
|
65
|
+
34,
|
66
|
+
40,
|
67
|
+
63,
|
68
|
+
94,
|
69
|
+
97]
|
70
|
+
}
|
71
|
+
|
72
|
+
describe "#homecoming" do
|
73
|
+
it 'should redirect to root_url' do
|
74
|
+
post :homecoming, @params
|
75
|
+
response.should redirect_to(root_url)
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "fields" do
|
79
|
+
describe "success" do
|
80
|
+
before :each do
|
81
|
+
Spree::OmnikassaPaymentResponse.any_instance.stub(:response_level).and_return(:success)
|
82
|
+
end
|
83
|
+
it 'should set a flash' do
|
84
|
+
post :homecoming, @params
|
85
|
+
flash[:info].should_not be_nil
|
86
|
+
flash[:info].downcase.should match /success/
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should remove order_id from session' do
|
92
|
+
session[:order_id] = 123
|
93
|
+
post :homecoming, @params
|
94
|
+
session[:order_id].should be_nil
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe '#reply' do
|
99
|
+
it 'should handle a post' do
|
100
|
+
post :reply, @params
|
101
|
+
response.status.should == 200
|
102
|
+
end
|
103
|
+
|
104
|
+
response_args.each do |field|
|
105
|
+
it "should recieve param #{field}" do
|
106
|
+
post :reply, @params
|
107
|
+
controller.params[field].should_not be_nil
|
108
|
+
end
|
109
|
+
end #describe fields
|
110
|
+
|
111
|
+
describe 'success (00)' do
|
112
|
+
before :each do
|
113
|
+
Spree::OmnikassaPaymentResponse.any_instance.stub(:response_level).and_return(:success)
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'should set payment state to completed' do
|
117
|
+
post :reply, @params
|
118
|
+
@payment.state.should == "completed"
|
119
|
+
end
|
120
|
+
it 'should log the response with level :info' do
|
121
|
+
Rails.logger.should_receive(:info).with( /OmnikassaPaymentResponse posted: payment: .*; params: .*/ )
|
122
|
+
post :reply, @params
|
123
|
+
end
|
124
|
+
it 'should set the order state to completed' do
|
125
|
+
post :reply, @params
|
126
|
+
@payment_response.order.state.should == "complete"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
describe "pending (#{response_codes[:pending].join(',')})" do
|
130
|
+
before :each do
|
131
|
+
Spree::OmnikassaPaymentResponse.any_instance.stub(:response_level).and_return(:pending)
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'should set payment state to pending' do
|
135
|
+
post :reply, @params
|
136
|
+
@payment.state == "pending"
|
137
|
+
end
|
138
|
+
it 'should log the response with level :info' do
|
139
|
+
Rails.logger.should_receive(:info).with( /OmnikassaPaymentResponse posted: payment: .*; params: .*/ )
|
140
|
+
post :reply, @params
|
141
|
+
end
|
142
|
+
it 'should set the order state to payment' do
|
143
|
+
post :reply, @params
|
144
|
+
@payment_response.order.state.should == "payment"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
describe "cancelled (#{response_codes[:cancelled].join(',')})" do
|
148
|
+
before :each do
|
149
|
+
Spree::OmnikassaPaymentResponse.any_instance.stub(:response_level).and_return(:cancelled)
|
150
|
+
end
|
151
|
+
it 'should set payment state to failed' do
|
152
|
+
post :reply, @params
|
153
|
+
@payment.state == "failed"
|
154
|
+
end
|
155
|
+
it 'should log the response with level :info' do
|
156
|
+
Rails.logger.should_receive(:info).with( /OmnikassaPaymentResponse posted: payment: .*; params: .*/ )
|
157
|
+
post :reply, @params
|
158
|
+
end
|
159
|
+
it 'should set the order state to cancelled' do
|
160
|
+
Spree::Order.any_instance.should_receive(:cancel)
|
161
|
+
post :reply, @params
|
162
|
+
end
|
163
|
+
end
|
164
|
+
describe "failed (#{response_codes[:failed].join(',')})" do
|
165
|
+
before :each do
|
166
|
+
Spree::OmnikassaPaymentResponse.any_instance.stub(:response_level).and_return(:failed)
|
167
|
+
end
|
168
|
+
it 'should set payment state to failed' do
|
169
|
+
post :reply, @params
|
170
|
+
@payment.state == "failed"
|
171
|
+
end
|
172
|
+
it 'should log the response with level :error' do
|
173
|
+
Rails.logger.should_receive(:error).with( /OmnikassaPaymentResponse posted: payment: .*; params: .*/ )
|
174
|
+
post :reply, @params
|
175
|
+
end
|
176
|
+
it 'should set the order state to cancelled' do
|
177
|
+
Spree::Order.any_instance.should_receive(:cancel)
|
178
|
+
post :reply, @params
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'should add a payment to order if not exists' do
|
183
|
+
@payment.started_processing!
|
184
|
+
Spree::OmnikassaPaymentsController.any_instance.should_receive(:add_payment_if_not_exists)
|
185
|
+
post :reply, @params
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
=begin
|
191
|
+
Spree Payment states from http://guides.spreecommerce.com/payments.html#payment
|
192
|
+
checkout Checkout has not been completed
|
193
|
+
processing The payment is being processed (temporary – intended to prevent double submission)
|
194
|
+
pending The payment has been processed but not yet complete (ex. authorized but not captured)
|
195
|
+
completed The payment is completed – only payments in this state count against the order total
|
196
|
+
failed The payment was rejected (ex. credit card was declined)
|
197
|
+
void The payment should not be counted against the order
|
198
|
+
=end
|