solidus-adyen 0.2.2 → 1.0.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.
- checksums.yaml +4 -4
- data/.ruby-version +1 -0
- data/.travis.yml +1 -0
- data/Gemfile +12 -4
- data/README.md +11 -11
- data/app/controllers/spree/adyen/hpps_controller.rb +1 -1
- data/app/controllers/spree/adyen_redirect_controller.rb +30 -7
- data/app/models/adyen_notification.rb +12 -1
- data/app/models/concerns/spree/adyen/payment.rb +0 -1
- data/app/models/spree/adyen/notification_processor.rb +9 -2
- data/app/models/spree/gateway/adyen_hpp.rb +5 -0
- data/bin/bootstrap.sh +8 -0
- data/config/locales/en.yml +1 -0
- data/lib/spree/adyen.rb +1 -1
- data/lib/spree/adyen/{form.rb → hpp.rb} +31 -22
- data/lib/spree/adyen/version.rb +1 -1
- data/lib/tasks/solidus-adyen/factory_girl.rake +17 -0
- data/solidus-adyen.gemspec +5 -6
- data/spec/controllers/spree/adyen/hpps_controller_spec.rb +2 -2
- data/spec/controllers/spree/adyen_redirect_controller_spec.rb +1 -0
- data/spec/factories/spree_gateway_adyen_hpp.rb +4 -1
- data/spec/lib/spree/adyen/form_spec.rb +33 -3
- data/spec/lib/tasks/requests/notification_processing_spec.rb +59 -29
- data/spec/models/adyen_notification_spec.rb +18 -0
- data/spec/models/spree/adyen/hpp_source_spec.rb +1 -1
- data/spec/models/spree/adyen/notification_processor_spec.rb +5 -0
- metadata +23 -35
- data/bin/regen.sh +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 30642824e2cf52ec60990cff981d9031976d872b
|
4
|
+
data.tar.gz: c591f80c5901703cc01569d15af3617f62077140
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 376c387db2a66a64c0a543bd3e470328fe3e6462b89f36b6e115cb3306a998c3d7dfbabdce96a2698b5b668a23ae49a18e0c2f99d54a2a3ad3853209213d91da
|
7
|
+
data.tar.gz: 5bc39e85ba846957b6ee7b0ad0fef4a9a5f129f5727d05412da6c5c0e689a4521ce62ce453a786200f955c52de80973bf560d715cca875d4c8ef33684c1ef678
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.2.2
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,12 +1,20 @@
|
|
1
|
-
source "
|
1
|
+
source "https://rubygems.org"
|
2
2
|
|
3
|
-
|
4
|
-
gem "
|
3
|
+
group :development, :test do
|
4
|
+
gem "solidus"
|
5
|
+
gem "solidus_auth_devise"
|
6
|
+
|
7
|
+
gem "pg"
|
8
|
+
gem "mysql2"
|
9
|
+
gem "sqlite3"
|
10
|
+
end
|
5
11
|
|
6
12
|
group :test do
|
13
|
+
gem "database_cleaner"
|
14
|
+
gem "factory_girl"
|
7
15
|
gem "timecop"
|
8
|
-
gem "webmock"
|
9
16
|
gem "vcr"
|
17
|
+
gem "webmock", "~> 1.24"
|
10
18
|
end
|
11
19
|
|
12
20
|
gemspec
|
data/README.md
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
# Solidus-Adyen [](https://travis-ci.org/StemboltHQ/solidus-adyen)
|
1
|
+
# Solidus-Adyen [](https://travis-ci.org/StemboltHQ/solidus-adyen)
|
2
|
+
|
3
|
+
**NOTICE** From July 2016 Adyen will no longer support SHA1 HPP's, this extension is _not_ only compatible with the SHA256 skins.
|
4
|
+
|
2
5
|
Adds support for Adyen Hosted Payment Page payments to Solidus stores using the
|
3
6
|
[Adyen](https://github.com/wvanbergen/adyen/) gem.
|
4
7
|
|
@@ -14,7 +17,7 @@ notification is received from Adyen.
|
|
14
17
|
# Installation
|
15
18
|
Add this line to your application's Gemfile:
|
16
19
|
```ruby
|
17
|
-
gem 'solidus-adyen', '~> 0.
|
20
|
+
gem 'solidus-adyen', '~> 1.0.0'
|
18
21
|
```
|
19
22
|
|
20
23
|
Then run:
|
@@ -196,20 +199,17 @@ in the view.
|
|
196
199
|
|
197
200
|
# Testing
|
198
201
|
```bash
|
199
|
-
$ bundle exec rake test_app
|
202
|
+
$ DB=postgres bundle exec rake test_app
|
200
203
|
$ rspec
|
204
|
+
$ cd spec/dummy
|
205
|
+
$ rake solidus-adyen:factory_girl:lint
|
201
206
|
```
|
202
207
|
|
203
208
|
# Development
|
204
209
|
My prefered method of setting up a sandbox is with
|
205
210
|
```bash
|
206
|
-
$
|
207
|
-
$
|
208
|
-
$ rake railties:install:migrations
|
209
|
-
$ rake db:migrate
|
210
|
-
$ rake db:seed
|
211
|
-
$ rake db:spree_sample:load
|
212
|
-
$ ./bin/rails s
|
211
|
+
$ ./bin/bootstrap.sh
|
212
|
+
$ ./spec/dummy/bin/rails s
|
213
213
|
```
|
214
214
|
You will need to reverse tunnel or make your server publicly available by some
|
215
215
|
other means - and update the server communication as well as the skin's url
|
@@ -217,7 +217,7 @@ with the proper end point to receive notifications.
|
|
217
217
|
|
218
218
|
# Test Credit Card Info
|
219
219
|
|
220
|
-
https://
|
220
|
+
https://docs.adyen.com/support/integration#testcardnumbers
|
221
221
|
|
222
222
|
# Terminology and other API information
|
223
223
|
[More info about Adyen can be found here](https://docs.adyen.com/display/TD/3D+Secure).
|
@@ -43,7 +43,7 @@ module Spree
|
|
43
43
|
state: "checkout"
|
44
44
|
)
|
45
45
|
|
46
|
-
if
|
46
|
+
if complete
|
47
47
|
redirect_to_order
|
48
48
|
else
|
49
49
|
#TODO void/cancel payment
|
@@ -52,13 +52,21 @@ module Spree
|
|
52
52
|
end
|
53
53
|
|
54
54
|
# If an authorization notification is received before the redirection the
|
55
|
-
# payment is created there.In this case we just need to assign the addition
|
55
|
+
# payment is created there. In this case we just need to assign the addition
|
56
56
|
# parameters received about the source.
|
57
57
|
#
|
58
58
|
# We do this because there is a chance that we never get redirected back
|
59
59
|
# so we need to make sure we complete the payment and order.
|
60
60
|
def confirm_order_already_completed
|
61
|
-
|
61
|
+
if psp_reference
|
62
|
+
payment = @order.payments.find_by!(response_code: psp_reference)
|
63
|
+
else
|
64
|
+
# If no psp_reference is present but the order is complete then the
|
65
|
+
# notification must have completed the order and created the payment.
|
66
|
+
# Therefore select the last Adyen payment.
|
67
|
+
payment =
|
68
|
+
@order.payments.where(source_type: "Spree::Adyen::HppSource").last
|
69
|
+
end
|
62
70
|
|
63
71
|
payment.source.update(source_params)
|
64
72
|
|
@@ -66,12 +74,14 @@ module Spree
|
|
66
74
|
end
|
67
75
|
|
68
76
|
def redirect_to_order
|
77
|
+
@current_order = nil
|
69
78
|
flash.notice = Spree.t(:order_processed_successfully)
|
79
|
+
flash['order_completed'] = true
|
70
80
|
redirect_to order_path(@order)
|
71
81
|
end
|
72
82
|
|
73
83
|
def check_signature
|
74
|
-
unless ::Adyen::
|
84
|
+
unless ::Adyen::HPP::Signature.verify(response_params, @payment_method.shared_secret)
|
75
85
|
raise "Payment Method not found."
|
76
86
|
end
|
77
87
|
end
|
@@ -90,15 +100,23 @@ module Spree
|
|
90
100
|
end
|
91
101
|
|
92
102
|
def source_params
|
103
|
+
adyen_permitted_params
|
104
|
+
end
|
105
|
+
|
106
|
+
def response_params
|
107
|
+
adyen_permitted_params
|
108
|
+
end
|
109
|
+
|
110
|
+
def adyen_permitted_params
|
93
111
|
params.permit(
|
94
112
|
:authResult,
|
95
|
-
:pspReference,
|
96
113
|
:merchantReference,
|
97
|
-
:
|
114
|
+
:merchantReturnData,
|
98
115
|
:merchantSig,
|
99
116
|
:paymentMethod,
|
117
|
+
:pspReference,
|
100
118
|
:shopperLocale,
|
101
|
-
:
|
119
|
+
:skinCode)
|
102
120
|
end
|
103
121
|
|
104
122
|
def order_number
|
@@ -108,5 +126,10 @@ module Spree
|
|
108
126
|
def psp_reference
|
109
127
|
params[:pspReference]
|
110
128
|
end
|
129
|
+
|
130
|
+
def complete
|
131
|
+
@order.contents.advance
|
132
|
+
@order.complete
|
133
|
+
end
|
111
134
|
end
|
112
135
|
end
|
@@ -83,7 +83,18 @@ class AdyenNotification < ActiveRecord::Base
|
|
83
83
|
end
|
84
84
|
|
85
85
|
def payment
|
86
|
-
|
86
|
+
reference = original_reference || psp_reference
|
87
|
+
payment_with_reference = Spree::Payment.find_by response_code: reference
|
88
|
+
return payment_with_reference if payment_with_reference
|
89
|
+
|
90
|
+
# If no reference take the last payment in the associated order where the
|
91
|
+
# response_code was nil.
|
92
|
+
if order
|
93
|
+
order
|
94
|
+
.payments
|
95
|
+
.where(source_type: "Spree::Adyen::HppSource", response_code: nil)
|
96
|
+
.last
|
97
|
+
end
|
87
98
|
end
|
88
99
|
|
89
100
|
# Returns true if this notification is an AUTHORISATION notification
|
@@ -77,7 +77,7 @@ module Spree
|
|
77
77
|
|
78
78
|
elsif notification.refund?
|
79
79
|
payment.refunds.create!(
|
80
|
-
amount: notification.value / 100, # cents to dollars
|
80
|
+
amount: notification.value / 100.0, # cents to dollars
|
81
81
|
transaction_id: notification.psp_reference,
|
82
82
|
refund_reason_id: ::Spree::RefundReason.first.id # FIXME
|
83
83
|
)
|
@@ -89,6 +89,13 @@ module Spree
|
|
89
89
|
|
90
90
|
# normal event is defined as just AUTHORISATION
|
91
91
|
def handle_normal_event
|
92
|
+
# Payment may not have psp_reference. Add this from notification if it
|
93
|
+
# doesn't have one.
|
94
|
+
unless self.payment.response_code
|
95
|
+
payment.response_code = notification.psp_reference
|
96
|
+
payment.save
|
97
|
+
end
|
98
|
+
|
92
99
|
if notification.auto_captured?
|
93
100
|
complete_payment!
|
94
101
|
|
@@ -132,6 +139,7 @@ module Spree
|
|
132
139
|
order: order
|
133
140
|
)
|
134
141
|
|
142
|
+
order.contents.advance
|
135
143
|
order.complete
|
136
144
|
payment
|
137
145
|
end
|
@@ -142,7 +150,6 @@ module Spree
|
|
142
150
|
notification.order.present? &&
|
143
151
|
payment.nil?
|
144
152
|
end
|
145
|
-
|
146
153
|
end
|
147
154
|
end
|
148
155
|
end
|
@@ -7,6 +7,7 @@ module Spree
|
|
7
7
|
preference :api_username, :string
|
8
8
|
preference :api_password, :string
|
9
9
|
preference :merchant_account, :string
|
10
|
+
preference :restricted_brand_codes, :string, default: ''
|
10
11
|
|
11
12
|
def merchant_account
|
12
13
|
ENV["ADYEN_MERCHANT_ACCOUNT"] || preferred_merchant_account
|
@@ -73,6 +74,10 @@ module Spree
|
|
73
74
|
psp_reference)
|
74
75
|
end
|
75
76
|
|
77
|
+
def restricted_brand_codes
|
78
|
+
preferred_restricted_brand_codes.split(',').compact.uniq
|
79
|
+
end
|
80
|
+
|
76
81
|
private
|
77
82
|
|
78
83
|
def handle_response response, original_reference
|
data/bin/bootstrap.sh
ADDED
data/config/locales/en.yml
CHANGED
data/lib/spree/adyen.rb
CHANGED
@@ -2,8 +2,8 @@ require "json"
|
|
2
2
|
|
3
3
|
module Spree
|
4
4
|
module Adyen
|
5
|
-
module
|
6
|
-
|
5
|
+
module HPP
|
6
|
+
HPP = ::Adyen::HPP
|
7
7
|
UrlHelper = Object.new.extend ActionView::Helpers::UrlHelper
|
8
8
|
|
9
9
|
class << self
|
@@ -41,15 +41,21 @@ module Spree
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def endpoint_url endpoint, order, payment_method, opts = {}
|
44
|
-
|
44
|
+
adyen_request = hpp_request order, payment_method, opts
|
45
45
|
|
46
|
-
URI::
|
47
|
-
host: base.host,
|
48
|
-
path: base.path,
|
49
|
-
query: params(order, payment_method).merge(opts).to_query)
|
46
|
+
URI::parse("#{adyen_request.url(endpoint)}?#{adyen_request.flat_payment_parameters.to_query}")
|
50
47
|
end
|
51
48
|
|
52
49
|
private
|
50
|
+
def hpp_request order, payment_method, opts
|
51
|
+
server = payment_method.preferences.fetch(:server)
|
52
|
+
parameters = params(order, payment_method).merge(opts)
|
53
|
+
|
54
|
+
HPP::Request.new(parameters, environment: server,
|
55
|
+
skin: { skin_code: payment_method.skin_code },
|
56
|
+
shared_secret: payment_method.shared_secret)
|
57
|
+
end
|
58
|
+
|
53
59
|
def payment_methods order, payment_method
|
54
60
|
url = directory_url(order, payment_method)
|
55
61
|
|
@@ -60,18 +66,16 @@ module Spree
|
|
60
66
|
)
|
61
67
|
end
|
62
68
|
|
63
|
-
def url payment_method, endpoint
|
64
|
-
server = payment_method.preferences.fetch(:server)
|
65
|
-
Form.url(server, endpoint)
|
66
|
-
end
|
67
|
-
|
68
69
|
def form_payment_methods_and_urls response, order, payment_method
|
69
70
|
response.fetch("paymentMethods").map do |brand|
|
71
|
+
next unless payment_method_allows_brand_code?(payment_method, brand['brandCode'])
|
72
|
+
|
70
73
|
issuers = brand.fetch("issuers", []).map do |issuer|
|
71
74
|
form_issuer(issuer, order, payment_method, brand)
|
72
75
|
end
|
76
|
+
|
73
77
|
form_payment_method(brand, order, payment_method, issuers)
|
74
|
-
end
|
78
|
+
end.compact
|
75
79
|
end
|
76
80
|
|
77
81
|
def form_issuer issuer, order, payment_method, brand
|
@@ -100,16 +104,20 @@ module Spree
|
|
100
104
|
end
|
101
105
|
|
102
106
|
def params order, payment_method
|
103
|
-
|
104
|
-
order.guest_token,
|
105
|
-
payment_method.id
|
106
|
-
].
|
107
|
-
join("|")
|
108
|
-
|
109
|
-
Form.flat_payment_parameters default_params.
|
107
|
+
default_params.
|
110
108
|
merge(order_params order).
|
111
109
|
merge(payment_method_params payment_method).
|
112
|
-
merge(merchant_return_data
|
110
|
+
merge(merchant_return_data order, payment_method)
|
111
|
+
end
|
112
|
+
|
113
|
+
def merchant_return_data order, payment_method
|
114
|
+
{ merchantReturnData: [order.guest_token, payment_method.id].join("|") }
|
115
|
+
end
|
116
|
+
|
117
|
+
def payment_method_allows_brand_code? payment_method, brand_code
|
118
|
+
return true if payment_method.restricted_brand_codes.empty?
|
119
|
+
|
120
|
+
payment_method.restricted_brand_codes.include?(brand_code)
|
113
121
|
end
|
114
122
|
|
115
123
|
# TODO set this in the adyen config
|
@@ -123,7 +131,8 @@ module Spree
|
|
123
131
|
merchant_reference: order.number.to_s,
|
124
132
|
country_code: order.billing_address.country.iso,
|
125
133
|
payment_amount: (order.total * 100).to_int,
|
126
|
-
shopper_locale: I18n.locale.to_s.gsub("-", "_")
|
134
|
+
shopper_locale: I18n.locale.to_s.gsub("-", "_"),
|
135
|
+
shopper_email: order.email
|
127
136
|
}
|
128
137
|
end
|
129
138
|
|
data/lib/spree/adyen/version.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
namespace :"solidus-adyen" do
|
2
|
+
namespace :factory_girl do
|
3
|
+
desc "Verify that all FactoryGirl factories are valid"
|
4
|
+
task lint: :environment do
|
5
|
+
if Rails.env.test?
|
6
|
+
begin
|
7
|
+
DatabaseCleaner.start
|
8
|
+
FactoryGirl.lint
|
9
|
+
ensure
|
10
|
+
DatabaseCleaner.clean
|
11
|
+
end
|
12
|
+
else
|
13
|
+
system("bundle exec rake soldius-adyen:factory_girl:lint RAILS_ENV='test'")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/solidus-adyen.gemspec
CHANGED
@@ -18,31 +18,30 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_runtime_dependency "adyen", "~>
|
22
|
-
spec.add_runtime_dependency "solidus_core", "~> 1.
|
21
|
+
spec.add_runtime_dependency "adyen", "~> 2.2.0"
|
22
|
+
spec.add_runtime_dependency "solidus_core", "~> 1.1"
|
23
23
|
spec.add_runtime_dependency "bourbon"
|
24
24
|
|
25
|
-
spec.add_development_dependency "sass-rails"
|
25
|
+
spec.add_development_dependency "sass-rails"
|
26
26
|
spec.add_development_dependency "coffee-rails"
|
27
27
|
|
28
28
|
spec.add_development_dependency "pg"
|
29
29
|
|
30
30
|
spec.add_development_dependency "rspec-rails", "~> 3.3"
|
31
31
|
spec.add_development_dependency "rspec-activemodel-mocks"
|
32
|
-
spec.add_development_dependency "factory_girl"
|
33
32
|
spec.add_development_dependency "shoulda-matchers"
|
34
33
|
|
35
34
|
spec.add_development_dependency "simplecov"
|
36
35
|
spec.add_development_dependency "simplecov-rcov"
|
37
36
|
|
38
37
|
spec.add_development_dependency "awesome_print"
|
39
|
-
spec.add_development_dependency "pry-rails"
|
40
38
|
spec.add_development_dependency "better_errors"
|
41
39
|
spec.add_development_dependency "binding_of_caller"
|
40
|
+
spec.add_development_dependency "pry-byebug"
|
42
41
|
spec.add_development_dependency "pry-stack_explorer"
|
42
|
+
spec.add_development_dependency "pry-rails"
|
43
43
|
|
44
44
|
spec.add_development_dependency "capybara"
|
45
45
|
spec.add_development_dependency "poltergeist"
|
46
46
|
spec.add_development_dependency "launchy"
|
47
|
-
spec.add_development_dependency "database_cleaner"
|
48
47
|
end
|
@@ -10,7 +10,7 @@ RSpec.describe Spree::Adyen::HppsController, type: :controller do
|
|
10
10
|
payment_url: "www.test-payment-url.com/amex"}] }
|
11
11
|
|
12
12
|
before do
|
13
|
-
allow(Spree::Adyen::
|
13
|
+
allow(Spree::Adyen::HPP).to receive(:payment_methods_from_directory).
|
14
14
|
with(order, payment_method).
|
15
15
|
and_return(parsed_directory_response)
|
16
16
|
end
|
@@ -33,7 +33,7 @@ RSpec.describe Spree::Adyen::HppsController, type: :controller do
|
|
33
33
|
format: :json }
|
34
34
|
|
35
35
|
it { is_expected.to have_http_status :ok }
|
36
|
-
|
36
|
+
|
37
37
|
it "renders a json response" do
|
38
38
|
subject
|
39
39
|
expect(response.body).to eq parsed_directory_response.to_json
|
@@ -2,7 +2,6 @@ FactoryGirl.define do
|
|
2
2
|
factory :spree_gateway_adyen_hpp, aliases: [:hpp_gateway],
|
3
3
|
class: "Spree::Gateway::AdyenHPP" do
|
4
4
|
name "Adyen"
|
5
|
-
environment "test"
|
6
5
|
display_on "both"
|
7
6
|
preferences(
|
8
7
|
skin_code: "XXXXX",
|
@@ -11,6 +10,10 @@ FactoryGirl.define do
|
|
11
10
|
days_to_ship: 3
|
12
11
|
)
|
13
12
|
|
13
|
+
trait :with_restricted_brand_codes do
|
14
|
+
preferred_restricted_brand_codes 'paypal'
|
15
|
+
end
|
16
|
+
|
14
17
|
trait :env_configured do
|
15
18
|
preferred_test_mode true
|
16
19
|
preferred_days_to_ship 1
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
RSpec.describe Spree::Adyen::
|
3
|
+
RSpec.describe Spree::Adyen::HPP do
|
4
4
|
let(:order) { create :order, total: 39.98 }
|
5
5
|
let(:payment_method) { create :hpp_gateway, preferences: preferences }
|
6
6
|
let(:preferences){
|
@@ -29,10 +29,11 @@ RSpec.describe Spree::Adyen::Form do
|
|
29
29
|
country_code: order.billing_address.country.iso,
|
30
30
|
merchant_return_data: merchant_return_data,
|
31
31
|
payment_amount: 3998,
|
32
|
-
shopper_locale: locale
|
32
|
+
shopper_locale: locale,
|
33
|
+
shopper_email: order.email
|
33
34
|
}
|
34
35
|
|
35
|
-
|
36
|
+
::Adyen::HPP::Request.new(redirect_params, skin: { skin_code: 'XXXXXX' }).redirect_url
|
36
37
|
end
|
37
38
|
|
38
39
|
let(:merchant_return_data) do
|
@@ -170,6 +171,35 @@ RSpec.describe Spree::Adyen::Form do
|
|
170
171
|
]
|
171
172
|
end
|
172
173
|
end
|
174
|
+
|
175
|
+
context "when payment_method specifies restricted brand_codes" do
|
176
|
+
let(:adyen_response) {
|
177
|
+
{
|
178
|
+
"paymentMethods" => [
|
179
|
+
{
|
180
|
+
"brandCode" => "mc",
|
181
|
+
"name" => "MasterCard"
|
182
|
+
}, {
|
183
|
+
"brandCode" => "paypal",
|
184
|
+
"name" => "PayPal"
|
185
|
+
}
|
186
|
+
]
|
187
|
+
}
|
188
|
+
}
|
189
|
+
|
190
|
+
let(:payment_method) { create(:hpp_gateway, :with_restricted_brand_codes) }
|
191
|
+
|
192
|
+
it "will only return paypal brand_code" do
|
193
|
+
expect(subject).to eq [
|
194
|
+
{
|
195
|
+
name: "PayPal",
|
196
|
+
brand_code: "paypal",
|
197
|
+
payment_url: payment_url,
|
198
|
+
issuers: []
|
199
|
+
}
|
200
|
+
]
|
201
|
+
end
|
202
|
+
end
|
173
203
|
end
|
174
204
|
|
175
205
|
describe "details_url" do
|
@@ -88,42 +88,72 @@ RSpec.describe "Notification processing", type: :request do
|
|
88
88
|
|
89
89
|
describe "full redirect, auth, capture flow", truncation: true do
|
90
90
|
it "creates a payment, completes order, captures payment" do
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
91
|
+
VCR.use_cassette "adyen capture" do
|
92
|
+
expect { initial_authorization }.
|
93
|
+
to change { order.payments.count }.by(1).
|
94
|
+
and change { order.reload.state}.to("complete").
|
95
|
+
and change { AdyenNotification.count }.by(1)
|
96
96
|
|
97
|
-
|
98
|
-
get "/checkout/payment/adyen", checkout_params, headers
|
99
|
-
expect(response).to have_http_status :redirect
|
97
|
+
capture_request
|
100
98
|
end
|
99
|
+
end
|
100
|
+
end
|
101
101
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
102
|
+
context "no psp reference in redirect" do
|
103
|
+
describe "full redirect, auth, capture flow", truncation: true do
|
104
|
+
let(:checkout_params) do
|
105
|
+
{
|
106
|
+
"merchantReference" => "R207199925",
|
107
|
+
"skinCode" => "xxxxxxxx",
|
108
|
+
"shopperLocale" => "en",
|
109
|
+
"paymentMethod" => "amex",
|
110
|
+
"authResult" => "AUTHORISED",
|
111
|
+
"merchantReturnData" => "adKbcFeXxOVE76UJRDF88g|#{payment_method.id}",
|
112
|
+
"merchantSig" => "SBdhua18U+8xkPmK/a/8VprF230="
|
113
|
+
}
|
109
114
|
end
|
110
115
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
].map(&:join)
|
118
|
-
# typically get a duplicate auth notification
|
119
|
-
authorize_request.call
|
120
|
-
end.
|
121
|
-
to change { order.payments.count }.by(1).
|
122
|
-
and change { order.reload.state}.to("complete").
|
123
|
-
and change { AdyenNotification.count }.by(1)
|
116
|
+
it "adds in psp reference to payment" do
|
117
|
+
VCR.use_cassette "adyen capture" do
|
118
|
+
expect { initial_authorization }.
|
119
|
+
to change { order.payments.count }.by(1).
|
120
|
+
and change { order.reload.state}.to("complete").
|
121
|
+
and change { AdyenNotification.count }.by(1)
|
124
122
|
|
125
|
-
|
123
|
+
capture_request
|
124
|
+
expect(order.payments.first.response_code).to eq "7914483013255061"
|
125
|
+
end
|
126
126
|
end
|
127
127
|
end
|
128
128
|
end
|
129
|
+
|
130
|
+
def initial_authorization
|
131
|
+
# these come in at the same time
|
132
|
+
[
|
133
|
+
Thread.new { authorize_request },
|
134
|
+
Thread.new { redirect_request }
|
135
|
+
].map(&:join)
|
136
|
+
# typically get a duplicate auth notification
|
137
|
+
authorize_request
|
138
|
+
end
|
139
|
+
|
140
|
+
def authorize_request
|
141
|
+
post "/adyen/notify", auth_params, headers
|
142
|
+
expect(response).to have_http_status :ok
|
143
|
+
expect(response.body).to eq "[accepted]"
|
144
|
+
end
|
145
|
+
|
146
|
+
def redirect_request
|
147
|
+
response_code = get "/checkout/payment/adyen", checkout_params, headers
|
148
|
+
expect(response_code).to eq 302
|
149
|
+
end
|
150
|
+
|
151
|
+
def capture_request
|
152
|
+
expect do
|
153
|
+
post "/adyen/notify", capture_params, headers
|
154
|
+
end.
|
155
|
+
to change { order.payments.last.reload.state }.
|
156
|
+
from("processing").
|
157
|
+
to("completed")
|
158
|
+
end
|
129
159
|
end
|
@@ -25,6 +25,24 @@ RSpec.describe AdyenNotification do
|
|
25
25
|
let(:attr) { :psp_reference }
|
26
26
|
include_examples "finds the payment"
|
27
27
|
end
|
28
|
+
|
29
|
+
context "payment with no reference" do
|
30
|
+
let!(:payment) { create :payment, response_code: nil }
|
31
|
+
|
32
|
+
context "normal notification" do
|
33
|
+
let!(:notification) {
|
34
|
+
described_class.new :merchant_reference => payment.order.number
|
35
|
+
}
|
36
|
+
include_examples "finds the payment"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "no connected order" do
|
41
|
+
let!(:notification) {
|
42
|
+
described_class.new :merchant_reference => "notarealorder"
|
43
|
+
}
|
44
|
+
it { is_expected.to eq nil }
|
45
|
+
end
|
28
46
|
end
|
29
47
|
|
30
48
|
describe "#build" do
|
@@ -200,6 +200,11 @@ RSpec.describe Spree::Adyen::NotificationProcessor do
|
|
200
200
|
from(0).
|
201
201
|
to(1)
|
202
202
|
end
|
203
|
+
|
204
|
+
it "creates a refund of the correct value" do
|
205
|
+
subject
|
206
|
+
expect(payment.reload.refunds.last.amount).to eq 23.99
|
207
|
+
end
|
203
208
|
end
|
204
209
|
|
205
210
|
context "when refunded from Solidus" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solidus-adyen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dylan Kendal
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-06-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: adyen
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 2.2.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 2.2.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: solidus_core
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
33
|
+
version: '1.1'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.
|
40
|
+
version: '1.1'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bourbon
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -56,16 +56,16 @@ dependencies:
|
|
56
56
|
name: sass-rails
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: coffee-rails
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,20 +122,6 @@ dependencies:
|
|
122
122
|
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: factory_girl
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - ">="
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '0'
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - ">="
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '0'
|
139
125
|
- !ruby/object:Gem::Dependency
|
140
126
|
name: shoulda-matchers
|
141
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -193,7 +179,7 @@ dependencies:
|
|
193
179
|
- !ruby/object:Gem::Version
|
194
180
|
version: '0'
|
195
181
|
- !ruby/object:Gem::Dependency
|
196
|
-
name:
|
182
|
+
name: better_errors
|
197
183
|
requirement: !ruby/object:Gem::Requirement
|
198
184
|
requirements:
|
199
185
|
- - ">="
|
@@ -207,7 +193,7 @@ dependencies:
|
|
207
193
|
- !ruby/object:Gem::Version
|
208
194
|
version: '0'
|
209
195
|
- !ruby/object:Gem::Dependency
|
210
|
-
name:
|
196
|
+
name: binding_of_caller
|
211
197
|
requirement: !ruby/object:Gem::Requirement
|
212
198
|
requirements:
|
213
199
|
- - ">="
|
@@ -221,7 +207,7 @@ dependencies:
|
|
221
207
|
- !ruby/object:Gem::Version
|
222
208
|
version: '0'
|
223
209
|
- !ruby/object:Gem::Dependency
|
224
|
-
name:
|
210
|
+
name: pry-byebug
|
225
211
|
requirement: !ruby/object:Gem::Requirement
|
226
212
|
requirements:
|
227
213
|
- - ">="
|
@@ -249,7 +235,7 @@ dependencies:
|
|
249
235
|
- !ruby/object:Gem::Version
|
250
236
|
version: '0'
|
251
237
|
- !ruby/object:Gem::Dependency
|
252
|
-
name:
|
238
|
+
name: pry-rails
|
253
239
|
requirement: !ruby/object:Gem::Requirement
|
254
240
|
requirements:
|
255
241
|
- - ">="
|
@@ -263,7 +249,7 @@ dependencies:
|
|
263
249
|
- !ruby/object:Gem::Version
|
264
250
|
version: '0'
|
265
251
|
- !ruby/object:Gem::Dependency
|
266
|
-
name:
|
252
|
+
name: capybara
|
267
253
|
requirement: !ruby/object:Gem::Requirement
|
268
254
|
requirements:
|
269
255
|
- - ">="
|
@@ -277,7 +263,7 @@ dependencies:
|
|
277
263
|
- !ruby/object:Gem::Version
|
278
264
|
version: '0'
|
279
265
|
- !ruby/object:Gem::Dependency
|
280
|
-
name:
|
266
|
+
name: poltergeist
|
281
267
|
requirement: !ruby/object:Gem::Requirement
|
282
268
|
requirements:
|
283
269
|
- - ">="
|
@@ -291,7 +277,7 @@ dependencies:
|
|
291
277
|
- !ruby/object:Gem::Version
|
292
278
|
version: '0'
|
293
279
|
- !ruby/object:Gem::Dependency
|
294
|
-
name:
|
280
|
+
name: launchy
|
295
281
|
requirement: !ruby/object:Gem::Requirement
|
296
282
|
requirements:
|
297
283
|
- - ">="
|
@@ -308,14 +294,15 @@ description: Adyen HPP payments for Solidus Stores
|
|
308
294
|
email:
|
309
295
|
- dylan@stembolt.com
|
310
296
|
executables:
|
297
|
+
- bootstrap.sh
|
311
298
|
- checkout.rb
|
312
|
-
- regen.sh
|
313
299
|
extensions: []
|
314
300
|
extra_rdoc_files: []
|
315
301
|
files:
|
316
302
|
- ".gitignore"
|
317
303
|
- ".rubocop.yml"
|
318
304
|
- ".rubocop_todo.yml"
|
305
|
+
- ".ruby-version"
|
319
306
|
- ".travis.yml"
|
320
307
|
- CHANGELOG.md
|
321
308
|
- Gemfile
|
@@ -353,8 +340,8 @@ files:
|
|
353
340
|
- app/views/spree/adyen/communication/_communication.html.erb
|
354
341
|
- app/views/spree/adyen/hpps/directory.html.erb
|
355
342
|
- app/views/spree/checkout/payment/_adyen.html.erb
|
343
|
+
- bin/bootstrap.sh
|
356
344
|
- bin/checkout.rb
|
357
|
-
- bin/regen.sh
|
358
345
|
- config/initializers/solidus_adyen.rb
|
359
346
|
- config/locales/en.yml
|
360
347
|
- config/routes.rb
|
@@ -368,10 +355,11 @@ files:
|
|
368
355
|
- lib/solidus-adyen.rb
|
369
356
|
- lib/spree/adyen.rb
|
370
357
|
- lib/spree/adyen/engine.rb
|
371
|
-
- lib/spree/adyen/
|
358
|
+
- lib/spree/adyen/hpp.rb
|
372
359
|
- lib/spree/adyen/hpp_check.rb
|
373
360
|
- lib/spree/adyen/url.rb
|
374
361
|
- lib/spree/adyen/version.rb
|
362
|
+
- lib/tasks/solidus-adyen/factory_girl.rake
|
375
363
|
- solidus-adyen.gemspec
|
376
364
|
- spec/cassettes/adyen_capture.yml
|
377
365
|
- spec/controllers/concerns/spree/adyen/admin/refunds_controller_spec.rb
|
@@ -415,7 +403,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
415
403
|
version: '0'
|
416
404
|
requirements: []
|
417
405
|
rubyforge_project:
|
418
|
-
rubygems_version: 2.4.5
|
406
|
+
rubygems_version: 2.4.5
|
419
407
|
signing_key:
|
420
408
|
specification_version: 4
|
421
409
|
summary: Adyen HPP payments for Solidus Stores
|
data/bin/regen.sh
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
rm -rf spec/dummy && bundle install && rake test_app && cd spec/dummy && rake db:migrate && rails s
|