solidus_stripe 4.2.0 → 4.3.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/.circleci/config.yml +5 -0
- data/.gem_release.yml +1 -1
- data/.github/stale.yml +4 -4
- data/.github_changelog_generator +2 -0
- data/.gitignore +3 -2
- data/.rubocop.yml +1 -3
- data/CHANGELOG.md +94 -17
- data/Gemfile +3 -9
- data/LICENSE +2 -1
- data/README.md +52 -47
- data/app/assets/javascripts/spree/frontend/solidus_stripe/stripe-cart-page-checkout.js +1 -0
- data/app/assets/javascripts/spree/frontend/solidus_stripe/stripe-payment-request-button-shared.js +2 -1
- data/app/controllers/solidus_stripe/payment_request_controller.rb +11 -1
- data/app/decorators/models/spree/refund_decorator.rb +1 -1
- data/app/models/solidus_stripe/address_from_params_service.rb +20 -8
- data/app/models/solidus_stripe/create_intents_payment_service.rb +2 -1
- data/app/models/spree/payment_method/stripe_credit_card.rb +26 -4
- data/bin/rails +4 -12
- data/bin/rails-engine +13 -0
- data/bin/rails-sandbox +16 -0
- data/bin/sandbox +2 -0
- data/config/locales/en.yml +5 -0
- data/lib/generators/solidus_stripe/install/install_generator.rb +1 -5
- data/lib/solidus_stripe/configuration.rb +21 -0
- data/lib/solidus_stripe/engine.rb +3 -14
- data/lib/solidus_stripe/testing_support/card_input_helper.rb +34 -0
- data/lib/solidus_stripe/{factories.rb → testing_support/factories.rb} +0 -0
- data/lib/solidus_stripe/version.rb +1 -1
- data/lib/solidus_stripe.rb +5 -5
- data/lib/views/frontend/spree/checkout/payment/v2/_javascript.html.erb +1 -1
- data/lib/views/frontend/spree/checkout/payment/v3/_form_elements.html.erb +2 -1
- data/solidus_stripe.gemspec +5 -5
- data/spec/features/stripe_checkout_spec.rb +31 -111
- data/spec/models/solidus_stripe/address_from_params_service_spec.rb +17 -6
- data/spec/models/solidus_stripe/create_intents_payment_service_spec.rb +1 -1
- data/spec/models/spree/payment_method/stripe_credit_card_spec.rb +29 -0
- data/spec/requests/payment_requests_spec.rb +152 -0
- data/spec/spec_helper.rb +16 -5
- data/spec/support/solidus_address_helper.rb +2 -2
- metadata +24 -16
data/bin/rails-engine
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# This command will automatically be run when you run "rails" with Rails gems
|
|
3
|
+
# installed from the root of your application.
|
|
4
|
+
|
|
5
|
+
ENGINE_ROOT = File.expand_path('..', __dir__)
|
|
6
|
+
ENGINE_PATH = File.expand_path('../lib/solidus_stripe/engine', __dir__)
|
|
7
|
+
|
|
8
|
+
# Set up gems listed in the Gemfile.
|
|
9
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
|
10
|
+
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
|
11
|
+
|
|
12
|
+
require 'rails/all'
|
|
13
|
+
require 'rails/engine/commands'
|
data/bin/rails-sandbox
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
app_root = 'sandbox'
|
|
4
|
+
|
|
5
|
+
unless File.exist? "#{app_root}/bin/rails"
|
|
6
|
+
warn 'Creating the sandbox app...'
|
|
7
|
+
Dir.chdir "#{__dir__}/.." do
|
|
8
|
+
system "#{__dir__}/sandbox" or begin
|
|
9
|
+
warn 'Automatic creation of the sandbox app failed'
|
|
10
|
+
exit 1
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
Dir.chdir app_root
|
|
16
|
+
exec 'bin/rails', *ARGV
|
data/bin/sandbox
CHANGED
|
@@ -72,9 +72,11 @@ unbundled bundle exec rails generate spree:install \
|
|
|
72
72
|
--user_class=Spree::User \
|
|
73
73
|
--enforce_available_locales=true \
|
|
74
74
|
--with-authentication=false \
|
|
75
|
+
--payment-method=none \
|
|
75
76
|
$@
|
|
76
77
|
|
|
77
78
|
unbundled bundle exec rails generate solidus:auth:install
|
|
79
|
+
unbundled bundle exec rails generate ${extension_name}:install
|
|
78
80
|
|
|
79
81
|
echo
|
|
80
82
|
echo "🚀 Sandbox app successfully created for $extension_name!"
|
|
@@ -9,16 +9,12 @@ module SolidusStripe
|
|
|
9
9
|
append_file 'vendor/assets/javascripts/spree/frontend/all.js', "//= require spree/frontend/solidus_stripe\n"
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def add_migrations
|
|
13
|
-
run 'bundle exec rake railties:install:migrations FROM=solidus_stripe'
|
|
14
|
-
end
|
|
15
|
-
|
|
16
12
|
def add_migrations
|
|
17
13
|
run 'bin/rails railties:install:migrations FROM=solidus_stripe'
|
|
18
14
|
end
|
|
19
15
|
|
|
20
16
|
def run_migrations
|
|
21
|
-
run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask('Would you like to run the migrations now? [Y/n]')) # rubocop:disable
|
|
17
|
+
run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask('Would you like to run the migrations now? [Y/n]')) # rubocop:disable Layout/LineLength
|
|
22
18
|
if run_migrations
|
|
23
19
|
run 'bin/rails db:migrate'
|
|
24
20
|
else
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SolidusStripe
|
|
4
|
+
class Configuration
|
|
5
|
+
# Define here the settings for this extensions, e.g.:
|
|
6
|
+
#
|
|
7
|
+
# attr_accessor :my_setting
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class << self
|
|
11
|
+
def configuration
|
|
12
|
+
@configuration ||= Configuration.new
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
alias config configuration
|
|
16
|
+
|
|
17
|
+
def configure
|
|
18
|
+
yield configuration
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require '
|
|
3
|
+
require 'solidus_core'
|
|
4
|
+
require 'solidus_support'
|
|
4
5
|
|
|
5
6
|
module SolidusStripe
|
|
6
7
|
class Engine < Rails::Engine
|
|
@@ -15,20 +16,8 @@ module SolidusStripe
|
|
|
15
16
|
g.test_framework :rspec
|
|
16
17
|
end
|
|
17
18
|
|
|
18
|
-
if SolidusSupport.backend_available?
|
|
19
|
-
paths["app/views"] << "lib/views/backend"
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
if SolidusSupport.frontend_available?
|
|
23
|
-
paths["app/views"] << "lib/views/frontend"
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
if SolidusSupport.api_available?
|
|
27
|
-
paths["app/views"] << "lib/views/api"
|
|
28
|
-
end
|
|
29
|
-
|
|
30
19
|
initializer "spree.payment_method.add_stripe_credit_card", after: "spree.register.payment_methods" do |app|
|
|
31
|
-
app.config.spree.payment_methods << Spree::PaymentMethod::StripeCreditCard
|
|
20
|
+
app.config.spree.payment_methods << "Spree::PaymentMethod::StripeCreditCard"
|
|
32
21
|
end
|
|
33
22
|
end
|
|
34
23
|
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SolidusCardInputHelper
|
|
4
|
+
def fill_in_card(card = {})
|
|
5
|
+
card[:number] ||= "4242 4242 4242 4242"
|
|
6
|
+
card[:code] ||= "123"
|
|
7
|
+
card[:exp_month] ||= "01"
|
|
8
|
+
card[:exp_year] ||= "#{Time.zone.now.year + 1}"
|
|
9
|
+
|
|
10
|
+
if preferred_v3_elements || preferred_v3_intents
|
|
11
|
+
within_frame find('#card_number iframe') do
|
|
12
|
+
fill_in_number("cardnumber", card)
|
|
13
|
+
end
|
|
14
|
+
within_frame(find '#card_cvc iframe') { fill_in 'cvc', with: card[:code] }
|
|
15
|
+
within_frame(find '#card_expiry iframe') do
|
|
16
|
+
fill_in_expiration("exp-date", card)
|
|
17
|
+
end
|
|
18
|
+
else
|
|
19
|
+
fill_in_number("Card Number", card)
|
|
20
|
+
fill_in "Card Code", with: card[:code]
|
|
21
|
+
fill_in_expiration("Expiration", card)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def fill_in_number(field_name, card)
|
|
28
|
+
card[:number].split('').each { |n| find_field(field_name).native.send_keys(n) }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def fill_in_expiration(field_name, card)
|
|
32
|
+
"#{card[:exp_month]}#{card[:exp_year].last(2)}".split('').each { |n| find_field(field_name).native.send_keys(n) }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
File without changes
|
data/lib/solidus_stripe.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require
|
|
3
|
+
require 'active_merchant'
|
|
4
|
+
|
|
5
|
+
require 'solidus_stripe/configuration'
|
|
6
|
+
require 'solidus_stripe/version'
|
|
7
|
+
require 'solidus_stripe/engine'
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
<%- if @order.has_checkout_step?('address') -%>
|
|
67
67
|
<script>
|
|
68
68
|
Spree.stripeAdditionalInfo = {
|
|
69
|
-
name: "<%= @order.bill_address.full_name %>",
|
|
69
|
+
name: "<%= SolidusSupport.combined_first_and_last_name_in_address? ? @order.bill_address.name : @order.bill_address.full_name %>",
|
|
70
70
|
address_line1: "<%= @order.bill_address.address1 %>",
|
|
71
71
|
address_line2: "<%= @order.bill_address.address2 %>",
|
|
72
72
|
address_city: "<%= @order.bill_address.city %>",
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
<div id="payment-request-button" data-stripe-config="<%= payment_method.stripe_config(current_order).to_json %>" data-v3-api="<%= stripe_v3_api %>"></div>
|
|
2
2
|
|
|
3
3
|
<% param_prefix = "payment_source[#{payment_method.id}]" %>
|
|
4
|
+
<% name = SolidusSupport.combined_first_and_last_name_in_address? ? @order.name : "#{@order.billing_firstname} #{@order.billing_lastname}" %>
|
|
4
5
|
|
|
5
6
|
<div class="field field-required">
|
|
6
7
|
<%= label_tag "name_on_card_#{payment_method.id}", t('spree.name_on_card') %>
|
|
7
|
-
<%= text_field_tag "#{param_prefix}[name]",
|
|
8
|
+
<%= text_field_tag "#{param_prefix}[name]", name, { id: "name_on_card_#{payment_method.id}", autocomplete: "cc-name" } %>
|
|
8
9
|
</div>
|
|
9
10
|
|
|
10
11
|
<div class="field field-required" data-hook="card_number">
|
data/solidus_stripe.gemspec
CHANGED
|
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
|
17
17
|
spec.metadata['source_code_uri'] = 'https://github.com/solidusio/solidus_stripe'
|
|
18
18
|
spec.metadata['changelog_uri'] = 'https://github.com/solidusio/solidus_stripe/blob/master/CHANGELOG.md'
|
|
19
19
|
|
|
20
|
-
spec.required_ruby_version =
|
|
20
|
+
spec.required_ruby_version = '>= 2.4.0'
|
|
21
21
|
|
|
22
22
|
# Specify which files should be added to the gem when it is released.
|
|
23
23
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
@@ -29,9 +29,9 @@ Gem::Specification.new do |spec|
|
|
|
29
29
|
spec.executables = files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
30
30
|
spec.require_paths = ["lib"]
|
|
31
31
|
|
|
32
|
-
spec.add_dependency 'solidus_core', ['>= 2.3', '<
|
|
33
|
-
spec.add_dependency 'solidus_support', '~> 0.
|
|
34
|
-
spec.add_dependency 'activemerchant', '>= 1.
|
|
32
|
+
spec.add_dependency 'solidus_core', ['>= 2.3', '< 4']
|
|
33
|
+
spec.add_dependency 'solidus_support', '~> 0.8'
|
|
34
|
+
spec.add_dependency 'activemerchant', '>= 1.105'
|
|
35
35
|
|
|
36
|
-
spec.add_development_dependency 'solidus_dev_support'
|
|
36
|
+
spec.add_development_dependency 'solidus_dev_support', '~> 2.3'
|
|
37
37
|
end
|
|
@@ -56,6 +56,10 @@ RSpec.describe "Stripe checkout", type: :feature do
|
|
|
56
56
|
# Delivery
|
|
57
57
|
expect(page).to have_current_path("/checkout/delivery")
|
|
58
58
|
expect(page).to have_content("UPS Ground")
|
|
59
|
+
click_on "Save and Continue"
|
|
60
|
+
|
|
61
|
+
# Payment
|
|
62
|
+
expect(page).to have_current_path("/checkout/payment")
|
|
59
63
|
end
|
|
60
64
|
|
|
61
65
|
# This will fetch a token from Stripe.com and then pass that to the webserver.
|
|
@@ -65,15 +69,8 @@ RSpec.describe "Stripe checkout", type: :feature do
|
|
|
65
69
|
let(:preferred_v3_elements) { false }
|
|
66
70
|
let(:preferred_v3_intents) { false }
|
|
67
71
|
|
|
68
|
-
before do
|
|
69
|
-
click_on "Save and Continue"
|
|
70
|
-
expect(page).to have_current_path("/checkout/payment")
|
|
71
|
-
end
|
|
72
|
-
|
|
73
72
|
it "can process a valid payment", js: true do
|
|
74
|
-
|
|
75
|
-
fill_in "Card Code", with: "123"
|
|
76
|
-
fill_in "Expiration", with: "01 / #{Time.now.year + 1}"
|
|
73
|
+
fill_in_card
|
|
77
74
|
click_button "Save and Continue"
|
|
78
75
|
expect(page).to have_current_path("/checkout/confirm")
|
|
79
76
|
click_button "Place Order"
|
|
@@ -81,9 +78,7 @@ RSpec.describe "Stripe checkout", type: :feature do
|
|
|
81
78
|
end
|
|
82
79
|
|
|
83
80
|
it "can re-use saved cards", js: true do
|
|
84
|
-
|
|
85
|
-
fill_in "Card Code", with: "123"
|
|
86
|
-
fill_in "Expiration", with: "01 / #{Time.now.year + 1}"
|
|
81
|
+
fill_in_card
|
|
87
82
|
click_button "Save and Continue"
|
|
88
83
|
|
|
89
84
|
expect(page).to have_current_path("/checkout/confirm")
|
|
@@ -128,36 +123,31 @@ RSpec.describe "Stripe checkout", type: :feature do
|
|
|
128
123
|
end
|
|
129
124
|
|
|
130
125
|
it "shows an error with a missing credit card number", js: true do
|
|
131
|
-
|
|
126
|
+
fill_in_card({ number: "", code: "" })
|
|
132
127
|
click_button "Save and Continue"
|
|
133
128
|
expect(page).to have_content("Could not find payment information")
|
|
134
129
|
end
|
|
135
130
|
|
|
136
131
|
it "shows an error with a missing expiration date", js: true do
|
|
137
|
-
|
|
132
|
+
fill_in_card({ exp_month: "", exp_year: "" })
|
|
138
133
|
click_button "Save and Continue"
|
|
139
134
|
expect(page).to have_content("Your card's expiration year is invalid.")
|
|
140
135
|
end
|
|
141
136
|
|
|
142
137
|
it "shows an error with an invalid credit card number", js: true do
|
|
143
|
-
|
|
144
|
-
fill_in "Expiration", with: "01 / #{Time.now.year + 1}"
|
|
138
|
+
fill_in_card({ number: "1111 1111 1111 1111" })
|
|
145
139
|
click_button "Save and Continue"
|
|
146
140
|
expect(page).to have_content("Your card number is incorrect.")
|
|
147
141
|
end
|
|
148
142
|
|
|
149
143
|
it "shows an error with invalid security fields", js: true do
|
|
150
|
-
|
|
151
|
-
fill_in "Expiration", with: "01 / #{Time.now.year + 1}"
|
|
152
|
-
fill_in "Card Code", with: "12"
|
|
144
|
+
fill_in_card({ code: "12" })
|
|
153
145
|
click_button "Save and Continue"
|
|
154
146
|
expect(page).to have_content("Your card's security code is invalid.")
|
|
155
147
|
end
|
|
156
148
|
|
|
157
149
|
it "shows an error with invalid expiry fields", js: true do
|
|
158
|
-
|
|
159
|
-
fill_in "Expiration", with: "00 / #{Time.now.year + 1}"
|
|
160
|
-
fill_in "Card Code", with: "123"
|
|
150
|
+
fill_in_card({ exp_month: "00" })
|
|
161
151
|
click_button "Save and Continue"
|
|
162
152
|
expect(page).to have_content("Your card's expiration month is invalid.")
|
|
163
153
|
end
|
|
@@ -165,53 +155,31 @@ RSpec.describe "Stripe checkout", type: :feature do
|
|
|
165
155
|
|
|
166
156
|
shared_examples "Stripe Elements invalid payments" do
|
|
167
157
|
it "shows an error with a missing credit card number" do
|
|
168
|
-
|
|
169
|
-
within_frame(find '#card_expiry iframe') do
|
|
170
|
-
'0132'.split('').each { |n| find_field('exp-date').native.send_keys(n) }
|
|
171
|
-
end
|
|
158
|
+
fill_in_card({ number: "" })
|
|
172
159
|
click_button "Save and Continue"
|
|
173
160
|
expect(page).to have_content("Your card number is incomplete.")
|
|
174
161
|
end
|
|
175
162
|
|
|
176
163
|
it "shows an error with a missing expiration date" do
|
|
177
|
-
|
|
178
|
-
'4242 4242 4242 4242'.split('').each { |n| find_field('cardnumber').native.send_keys(n) }
|
|
179
|
-
end
|
|
180
|
-
within_frame(find '#card_cvc iframe') { fill_in 'cvc', with: '123' }
|
|
164
|
+
fill_in_card({ exp_month: "", exp_year: "" })
|
|
181
165
|
click_button "Save and Continue"
|
|
182
166
|
expect(page).to have_content("Your card's expiration date is incomplete.")
|
|
183
167
|
end
|
|
184
168
|
|
|
185
169
|
it "shows an error with an invalid credit card number" do
|
|
186
|
-
|
|
187
|
-
'1111 1111 1111 1111'.split('').each { |n| find_field('cardnumber').native.send_keys(n) }
|
|
188
|
-
end
|
|
189
|
-
within_frame(find '#card_cvc iframe') { fill_in 'cvc', with: '123' }
|
|
190
|
-
within_frame(find '#card_expiry iframe') do
|
|
191
|
-
'0132'.split('').each { |n| find_field('exp-date').native.send_keys(n) }
|
|
192
|
-
end
|
|
170
|
+
fill_in_card({ number: "1111 1111 1111 1111" })
|
|
193
171
|
click_button "Save and Continue"
|
|
194
172
|
expect(page).to have_content("Your card number is invalid.")
|
|
195
173
|
end
|
|
196
174
|
|
|
197
175
|
it "shows an error with invalid security fields" do
|
|
198
|
-
|
|
199
|
-
'4242 4242 4242 4242'.split('').each { |n| find_field('cardnumber').native.send_keys(n) }
|
|
200
|
-
end
|
|
201
|
-
within_frame(find '#card_cvc iframe') { fill_in 'cvc', with: '12' }
|
|
202
|
-
within_frame(find '#card_expiry iframe') do
|
|
203
|
-
'0132'.split('').each { |n| find_field('exp-date').native.send_keys(n) }
|
|
204
|
-
end
|
|
176
|
+
fill_in_card({ code: "12" })
|
|
205
177
|
click_button "Save and Continue"
|
|
206
178
|
expect(page).to have_content("Your card's security code is incomplete.")
|
|
207
179
|
end
|
|
208
180
|
|
|
209
181
|
it "shows an error with invalid expiry fields" do
|
|
210
|
-
|
|
211
|
-
'4242 4242 4242 4242'.split('').each { |n| find_field('cardnumber').native.send_keys(n) }
|
|
212
|
-
end
|
|
213
|
-
within_frame(find '#card_cvc iframe') { fill_in 'cvc', with: '123' }
|
|
214
|
-
within_frame(find '#card_expiry iframe') { fill_in 'exp-date', with: "013" }
|
|
182
|
+
fill_in_card({ exp_month: "01", exp_year: "3" })
|
|
215
183
|
click_button "Save and Continue"
|
|
216
184
|
expect(page).to have_content("Your card's expiration date is incomplete.")
|
|
217
185
|
end
|
|
@@ -221,19 +189,8 @@ RSpec.describe "Stripe checkout", type: :feature do
|
|
|
221
189
|
let(:preferred_v3_elements) { true }
|
|
222
190
|
let(:preferred_v3_intents) { false }
|
|
223
191
|
|
|
224
|
-
before do
|
|
225
|
-
click_on "Save and Continue"
|
|
226
|
-
expect(page).to have_current_path("/checkout/payment")
|
|
227
|
-
end
|
|
228
|
-
|
|
229
192
|
it "can process a valid payment" do
|
|
230
|
-
|
|
231
|
-
'4242 4242 4242 4242'.split('').each { |n| find_field('cardnumber').native.send_keys(n) }
|
|
232
|
-
end
|
|
233
|
-
within_frame(find '#card_cvc iframe') { fill_in 'cvc', with: '123' }
|
|
234
|
-
within_frame(find '#card_expiry iframe') do
|
|
235
|
-
'0132'.split('').each { |n| find_field('exp-date').native.send_keys(n) }
|
|
236
|
-
end
|
|
193
|
+
fill_in_card
|
|
237
194
|
click_button "Save and Continue"
|
|
238
195
|
expect(page).to have_current_path("/checkout/confirm")
|
|
239
196
|
click_button "Place Order"
|
|
@@ -244,13 +201,7 @@ RSpec.describe "Stripe checkout", type: :feature do
|
|
|
244
201
|
stub_authorization!
|
|
245
202
|
|
|
246
203
|
it "completes the order, captures the payment and cancels the order" do
|
|
247
|
-
|
|
248
|
-
'4242 4242 4242 4242'.split('').each { |n| find_field('cardnumber').native.send_keys(n) }
|
|
249
|
-
end
|
|
250
|
-
within_frame(find '#card_cvc iframe') { fill_in 'cvc', with: '123' }
|
|
251
|
-
within_frame(find '#card_expiry iframe') do
|
|
252
|
-
'0132'.split('').each { |n| find_field('exp-date').native.send_keys(n) }
|
|
253
|
-
end
|
|
204
|
+
fill_in_card
|
|
254
205
|
click_button "Save and Continue"
|
|
255
206
|
expect(page).to have_current_path("/checkout/confirm")
|
|
256
207
|
click_button "Place Order"
|
|
@@ -314,7 +265,9 @@ RSpec.describe "Stripe checkout", type: :feature do
|
|
|
314
265
|
expect(page).to have_content "Completed"
|
|
315
266
|
end
|
|
316
267
|
|
|
317
|
-
|
|
268
|
+
page.accept_alert do
|
|
269
|
+
find('input[value="Cancel"]').click
|
|
270
|
+
end
|
|
318
271
|
|
|
319
272
|
expect(page).to have_content "Order canceled"
|
|
320
273
|
|
|
@@ -332,11 +285,6 @@ RSpec.describe "Stripe checkout", type: :feature do
|
|
|
332
285
|
let(:preferred_v3_elements) { false }
|
|
333
286
|
let(:preferred_v3_intents) { true }
|
|
334
287
|
|
|
335
|
-
before do
|
|
336
|
-
click_on "Save and Continue"
|
|
337
|
-
expect(page).to have_current_path("/checkout/payment")
|
|
338
|
-
end
|
|
339
|
-
|
|
340
288
|
context "when using a valid 3D Secure card" do
|
|
341
289
|
it "successfully completes the checkout" do
|
|
342
290
|
authenticate_3d_secure_card(card_3d_secure)
|
|
@@ -350,17 +298,8 @@ RSpec.describe "Stripe checkout", type: :feature do
|
|
|
350
298
|
end
|
|
351
299
|
|
|
352
300
|
context "when using a card without enough money" do
|
|
353
|
-
let(:card_number) { "4000 0000 0000 9995" }
|
|
354
|
-
|
|
355
301
|
it "fails the payment" do
|
|
356
|
-
|
|
357
|
-
card_number.split('').each { |n| find_field('cardnumber').native.send_keys(n) }
|
|
358
|
-
end
|
|
359
|
-
within_frame(find '#card_cvc iframe') { fill_in 'cvc', with: '123' }
|
|
360
|
-
within_frame(find '#card_expiry iframe') do
|
|
361
|
-
'0132'.split('').each { |n| find_field('exp-date').native.send_keys(n) }
|
|
362
|
-
end
|
|
363
|
-
|
|
302
|
+
fill_in_card({ number: "4000 0000 0000 9995" })
|
|
364
303
|
click_button "Save and Continue"
|
|
365
304
|
|
|
366
305
|
expect(page).to have_content "Your card has insufficient funds."
|
|
@@ -368,17 +307,8 @@ RSpec.describe "Stripe checkout", type: :feature do
|
|
|
368
307
|
end
|
|
369
308
|
|
|
370
309
|
context "when entering the wrong 3D verification code" do
|
|
371
|
-
let(:card_number) { "4000 0084 0000 1629" }
|
|
372
|
-
|
|
373
310
|
it "fails the payment" do
|
|
374
|
-
|
|
375
|
-
card_number.split('').each { |n| find_field('cardnumber').native.send_keys(n) }
|
|
376
|
-
end
|
|
377
|
-
within_frame(find '#card_cvc iframe') { fill_in 'cvc', with: '123' }
|
|
378
|
-
within_frame(find '#card_expiry iframe') do
|
|
379
|
-
'0132'.split('').each { |n| find_field('exp-date').native.send_keys(n) }
|
|
380
|
-
end
|
|
381
|
-
|
|
311
|
+
fill_in_card({ number: "4000 0084 0000 1629" })
|
|
382
312
|
click_button "Save and Continue"
|
|
383
313
|
|
|
384
314
|
within_3d_secure_modal do
|
|
@@ -457,7 +387,9 @@ RSpec.describe "Stripe checkout", type: :feature do
|
|
|
457
387
|
expect(page).to have_content "Completed"
|
|
458
388
|
end
|
|
459
389
|
|
|
460
|
-
|
|
390
|
+
page.accept_alert do
|
|
391
|
+
find('input[value="Cancel"]').click
|
|
392
|
+
end
|
|
461
393
|
|
|
462
394
|
expect(page).to have_content "Order canceled"
|
|
463
395
|
|
|
@@ -472,19 +404,13 @@ RSpec.describe "Stripe checkout", type: :feature do
|
|
|
472
404
|
stub_authorization!
|
|
473
405
|
|
|
474
406
|
context "when paying first with regular card, then with 3D-Secure card" do
|
|
475
|
-
let(:regular_card) { "4242 4242 4242 4242"}
|
|
407
|
+
let(:regular_card) { "4242 4242 4242 4242" }
|
|
476
408
|
|
|
477
409
|
it "voids the first stripe payment and successfully pays with 3DS card" do
|
|
478
|
-
|
|
479
|
-
regular_card.split('').each { |n| find_field('cardnumber').native.send_keys(n) }
|
|
480
|
-
end
|
|
481
|
-
within_frame(find '#card_cvc iframe') { fill_in 'cvc', with: '123' }
|
|
482
|
-
within_frame(find '#card_expiry iframe') do
|
|
483
|
-
'0132'.split('').each { |n| find_field('exp-date').native.send_keys(n) }
|
|
484
|
-
end
|
|
410
|
+
fill_in_card({ number: regular_card })
|
|
485
411
|
click_button "Save and Continue"
|
|
486
412
|
|
|
487
|
-
expect(page).to have_content "Ending in
|
|
413
|
+
expect(page).to have_content "Ending in #{regular_card.last(4)}"
|
|
488
414
|
|
|
489
415
|
click_link "Payment"
|
|
490
416
|
|
|
@@ -538,7 +464,7 @@ RSpec.describe "Stripe checkout", type: :feature do
|
|
|
538
464
|
end
|
|
539
465
|
|
|
540
466
|
def within_3d_secure_modal
|
|
541
|
-
within_frame "
|
|
467
|
+
within_frame find("iframe[src*='authorize-with-url-inner']") do
|
|
542
468
|
within_frame "__stripeJSChallengeFrame" do
|
|
543
469
|
within_frame "acsFrame" do
|
|
544
470
|
yield
|
|
@@ -548,13 +474,7 @@ RSpec.describe "Stripe checkout", type: :feature do
|
|
|
548
474
|
end
|
|
549
475
|
|
|
550
476
|
def authenticate_3d_secure_card(card_number)
|
|
551
|
-
|
|
552
|
-
card_number.split('').each { |n| find_field('cardnumber').native.send_keys(n) }
|
|
553
|
-
end
|
|
554
|
-
within_frame(find '#card_cvc iframe') { fill_in 'cvc', with: '123' }
|
|
555
|
-
within_frame(find '#card_expiry iframe') do
|
|
556
|
-
'0132'.split('').each { |n| find_field('exp-date').native.send_keys(n) }
|
|
557
|
-
end
|
|
477
|
+
fill_in_card({ number: card_number })
|
|
558
478
|
click_button "Save and Continue"
|
|
559
479
|
|
|
560
480
|
within_3d_secure_modal do
|
|
@@ -34,15 +34,26 @@ RSpec.describe SolidusStripe::AddressFromParamsService do
|
|
|
34
34
|
|
|
35
35
|
context "when the user has an address compatible with the params" do
|
|
36
36
|
before do
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
name_attributes = if SolidusSupport.combined_first_and_last_name_in_address?
|
|
38
|
+
{
|
|
39
|
+
name: 'Clark Kent'
|
|
40
|
+
}
|
|
41
|
+
else
|
|
42
|
+
{
|
|
43
|
+
firstname: 'Clark',
|
|
44
|
+
lastname: 'Kent',
|
|
45
|
+
}
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
address_attributes = {
|
|
49
|
+
city: params[:city],
|
|
39
50
|
zipcode: params[:postalCode],
|
|
40
|
-
firstname: 'Clark',
|
|
41
|
-
lastname: 'Kent',
|
|
42
51
|
address1: params[:addressLine].first,
|
|
43
52
|
address2: nil,
|
|
44
|
-
phone: '555-555-0199'
|
|
45
|
-
)
|
|
53
|
+
phone: '555-555-0199',
|
|
54
|
+
}.merge!(name_attributes)
|
|
55
|
+
|
|
56
|
+
user.addresses << create(:address, address_attributes)
|
|
46
57
|
end
|
|
47
58
|
|
|
48
59
|
it "returns an existing user's address" do
|
|
@@ -96,7 +96,7 @@ RSpec.describe SolidusStripe::CreateIntentsPaymentService do
|
|
|
96
96
|
|
|
97
97
|
context "when there are previous pending payments" do
|
|
98
98
|
let!(:payment) do
|
|
99
|
-
create(:payment, order: order).tap do |payment|
|
|
99
|
+
create(:payment, order: order, amount: order.total).tap do |payment|
|
|
100
100
|
payment.update!(state: :pending)
|
|
101
101
|
end
|
|
102
102
|
end
|
|
@@ -284,4 +284,33 @@ describe Spree::PaymentMethod::StripeCreditCard do
|
|
|
284
284
|
end
|
|
285
285
|
end
|
|
286
286
|
end
|
|
287
|
+
|
|
288
|
+
describe '#options_for_purchase_or_auth' do
|
|
289
|
+
let(:card) do
|
|
290
|
+
FactoryBot.create(
|
|
291
|
+
:credit_card,
|
|
292
|
+
gateway_customer_profile_id: 'cus_abcde',
|
|
293
|
+
imported: false
|
|
294
|
+
)
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
before do
|
|
298
|
+
allow(subject).to receive(:options_for_purchase_or_auth).and_call_original
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
context 'transaction_options' do
|
|
302
|
+
it 'includes basic values and keys' do
|
|
303
|
+
options = subject.send(:options_for_purchase_or_auth, 19.99, card, {})
|
|
304
|
+
expect(options[0]).to eq(19.99)
|
|
305
|
+
expect(options[1]).to eq(card)
|
|
306
|
+
expect(options[2].keys).to eq([:description, :currency, :customer])
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
it 'includes statement_descriptor_suffix within options' do
|
|
310
|
+
transaction_options = { statement_descriptor_suffix: 'FFFFFFF' }
|
|
311
|
+
options = subject.send(:options_for_purchase_or_auth, 19.99, card, transaction_options)
|
|
312
|
+
expect(options.last[:statement_descriptor_suffix]).to eq('FFFFFFF')
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
end
|
|
287
316
|
end
|