spree_gateway 3.8.0 → 3.9.4
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/.travis.yml +6 -11
- data/Gemfile +3 -1
- data/README.md +2 -2
- data/Rakefile +2 -2
- data/app/models/spree/gateway/stripe_ach_gateway.rb +1 -1
- data/app/models/spree/gateway/stripe_elements_gateway.rb +54 -0
- data/app/models/spree/gateway/stripe_gateway.rb +5 -0
- data/app/models/{spree → spree_gateway}/apple_pay_order_decorator.rb +2 -2
- data/app/models/{spree → spree_gateway}/apple_pay_payment_decorator.rb +2 -2
- data/app/models/spree_gateway/credit_card_decorator.rb +10 -0
- data/app/models/spree_gateway/order_decorator.rb +28 -0
- data/app/models/{spree → spree_gateway}/payment_decorator.rb +9 -2
- data/app/views/spree/checkout/_payment_confirm.html.erb +39 -0
- data/config/locales/en.yml +4 -0
- data/config/routes.rb +12 -0
- data/db/migrate/20200422114908_add_intent_key_to_payment.rb +5 -0
- data/lib/controllers/spree/api/v2/storefront/intents_controller.rb +27 -0
- data/lib/spree_frontend/controllers/spree/checkout_controller_decorator.rb +19 -0
- data/lib/spree_gateway/engine.rb +10 -0
- data/lib/spree_gateway/version.rb +1 -1
- data/lib/views/frontend/spree/checkout/payment/_stripe_elements.html.erb +2 -1
- data/spec/features/admin/stripe_elements_payment_spec.rb +20 -29
- data/spec/features/stripe_checkout_spec.rb +37 -23
- data/spec/features/stripe_elements_3ds_checkout_spec.rb +225 -0
- data/spec/models/gateway/authorize_net_spec.rb +1 -1
- data/spec/models/gateway/balanced_gateway_spec.rb +1 -1
- data/spec/models/gateway/banwire_spec.rb +1 -1
- data/spec/models/gateway/beanstream_spec.rb +1 -1
- data/spec/models/gateway/braintree_gateway_spec.rb +24 -13
- data/spec/models/gateway/card_save_spec.rb +1 -1
- data/spec/models/gateway/{data_cache_spec.rb → data_cash_spec.rb} +1 -1
- data/spec/models/gateway/epay_spec.rb +1 -1
- data/spec/models/gateway/eway_rapid_spec.rb +1 -1
- data/spec/models/gateway/eway_spec.rb +1 -1
- data/spec/models/gateway/moneris_spec.rb +1 -1
- data/spec/models/gateway/pay_junction_spec.rb +1 -1
- data/spec/models/gateway/pay_pal_spec.rb +1 -1
- data/spec/models/gateway/payflow_pro_spec.rb +1 -1
- data/spec/models/gateway/paymill_spec.rb +1 -1
- data/spec/models/gateway/pin_gateway_spec.rb +1 -1
- data/spec/models/gateway/quickpay_spec.rb +1 -1
- data/spec/models/gateway/sage_pay_spec.rb +1 -1
- data/spec/models/gateway/secure_pay_au_spec.rb +1 -1
- data/spec/models/gateway/stripe_ach_gateway_spec.rb +2 -1
- data/spec/models/gateway/stripe_gateway_spec.rb +1 -0
- data/spec/models/gateway/usa_epay_transaction_spec.rb +2 -2
- data/spec/models/gateway/worldpay_spec.rb +1 -1
- data/spec/models/spree/order_spec.rb +4 -2
- data/spec/support/order_walktrough.rb +73 -0
- data/spec/support/within_stripe_3ds_popup.rb +10 -0
- data/spree_gateway.gemspec +9 -3
- metadata +34 -28
- data/Appraisals +0 -14
- data/gemfiles/spree_4_1.gemfile +0 -8
- data/gemfiles/spree_4_2.gemfile +0 -8
- data/gemfiles/spree_master.gemfile +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a29093f977d40e708b032c608a9e25f1949352bee57b9321fa36488000d7711f
|
4
|
+
data.tar.gz: 5f5d7ff9014be360d444df942dc24d1313ef0881e786ac37a49f4fe884b5d0fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 807b40308555c5149f146fa3fc38c52f10c47ec765a1988f0562adcc296115d43670f09052a80a2493edd166d6d195092e7861ae07457c8c47eedb0cca90559b
|
7
|
+
data.tar.gz: 0ce03934963ea212e16aed6148eff226362d90544789ec1fa283c69dbff81c1d2834c91bce4aab81794935c5d3e825ffb89f07b95d66d1d9994128b11f8e31de
|
data/.travis.yml
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
os: linux
|
2
2
|
dist: bionic
|
3
3
|
|
4
|
+
cache: bundler
|
5
|
+
|
4
6
|
addons:
|
5
7
|
apt:
|
6
8
|
sources:
|
@@ -11,25 +13,18 @@ addons:
|
|
11
13
|
services:
|
12
14
|
- mysql
|
13
15
|
- postgresql
|
16
|
+
- redis-server
|
14
17
|
|
15
18
|
language: ruby
|
16
19
|
|
17
20
|
rvm:
|
18
|
-
- 2.
|
21
|
+
- 2.7
|
22
|
+
- 3.0
|
19
23
|
|
20
24
|
env:
|
21
25
|
- DB=mysql
|
22
26
|
- DB=postgres
|
23
27
|
|
24
|
-
gemfile:
|
25
|
-
# - gemfiles/spree_4_1.gemfile
|
26
|
-
- gemfiles/spree_4_2.gemfile
|
27
|
-
- gemfiles/spree_master.gemfile
|
28
|
-
|
29
|
-
jobs:
|
30
|
-
allow_failures:
|
31
|
-
- gemfile: gemfiles/spree_master.gemfile
|
32
|
-
|
33
28
|
before_install:
|
34
29
|
- mysql -u root -e "GRANT ALL ON *.* TO 'travis'@'%';"
|
35
30
|
|
@@ -41,4 +36,4 @@ before_script:
|
|
41
36
|
|
42
37
|
script:
|
43
38
|
- bundle exec rake test_app
|
44
|
-
- bundle exec rake spec
|
39
|
+
- bundle exec rake spec
|
data/Gemfile
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
3
|
gem 'rails-controller-testing'
|
4
|
-
gem 'spree', github: 'spree/spree', branch: '
|
4
|
+
gem 'spree', github: 'spree/spree', branch: 'main'
|
5
|
+
gem 'spree_backend', github: 'spree/spree', branch: 'main'
|
6
|
+
gem 'spree_frontend', github: 'spree/spree', branch: 'main'
|
5
7
|
|
6
8
|
gemspec
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Spree Gateway
|
2
2
|
|
3
|
-
[](https://travis-ci.org/spree/spree_gateway)
|
4
4
|
[](https://codeclimate.com/github/spree/spree_gateway)
|
5
5
|
|
6
6
|
Community supported Spree Payment Method Gateways. It works as a wrapper for
|
@@ -100,6 +100,6 @@ We are [available for hire][spark].
|
|
100
100
|
|
101
101
|
[1]: http://www.fsf.org/licensing/essays/free-sw.html
|
102
102
|
[2]: https://github.com/spree/spree_gateway/issues
|
103
|
-
[3]: https://github.com/spree/spree_gateway/blob/
|
103
|
+
[3]: https://github.com/spree/spree_gateway/blob/main/LICENSE.md
|
104
104
|
[4]: https://github.com/spree
|
105
105
|
[5]: https://github.com/spree/spree_gateway/graphs/contributors
|
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@ require 'bundler'
|
|
2
2
|
Bundler::GemHelper.install_tasks
|
3
3
|
|
4
4
|
require 'rspec/core/rake_task'
|
5
|
-
require 'spree/testing_support/
|
5
|
+
require 'spree/testing_support/extension_rake'
|
6
6
|
|
7
7
|
RSpec::Core::RakeTask.new
|
8
8
|
|
@@ -11,5 +11,5 @@ task :default => [:spec]
|
|
11
11
|
desc "Generates a dummy app for testing"
|
12
12
|
task :test_app do
|
13
13
|
ENV['LIB_NAME'] = 'spree_gateway'
|
14
|
-
Rake::Task['
|
14
|
+
Rake::Task['extension:test_app'].invoke
|
15
15
|
end
|
@@ -1,7 +1,61 @@
|
|
1
1
|
module Spree
|
2
2
|
class Gateway::StripeElementsGateway < Gateway::StripeGateway
|
3
|
+
preference :intents, :boolean, default: true
|
4
|
+
|
3
5
|
def method_type
|
4
6
|
'stripe_elements'
|
5
7
|
end
|
8
|
+
|
9
|
+
def provider_class
|
10
|
+
if get_preference(:intents)
|
11
|
+
ActiveMerchant::Billing::StripePaymentIntentsGateway
|
12
|
+
else
|
13
|
+
ActiveMerchant::Billing::StripeGateway
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def create_profile(payment)
|
18
|
+
return unless payment.source.gateway_customer_profile_id.nil?
|
19
|
+
|
20
|
+
options = {
|
21
|
+
email: payment.order.email,
|
22
|
+
login: preferred_secret_key
|
23
|
+
}.merge! address_for(payment)
|
24
|
+
|
25
|
+
source = update_source!(payment.source)
|
26
|
+
creditcard = source.gateway_payment_profile_id.present? ? source.gateway_payment_profile_id : source
|
27
|
+
response = provider.store(creditcard, options)
|
28
|
+
if response.success?
|
29
|
+
if get_preference(:intents)
|
30
|
+
payment.source.update!(
|
31
|
+
cc_type: payment.source.cc_type,
|
32
|
+
gateway_customer_profile_id: response.params['id'],
|
33
|
+
gateway_payment_profile_id: response.params['sources']['data'].first['id']
|
34
|
+
)
|
35
|
+
else
|
36
|
+
response_cc_type = response.params['sources']['data'].first['brand']
|
37
|
+
cc_type = CARD_TYPE_MAPPING.include?(response_cc_type) ? CARD_TYPE_MAPPING[response_cc_type] : payment.source.cc_type
|
38
|
+
payment.source.update!({
|
39
|
+
cc_type: cc_type, # side-effect of update_source!
|
40
|
+
gateway_customer_profile_id: response.params['id'],
|
41
|
+
gateway_payment_profile_id: response.params['default_source'] || response.params['default_card']
|
42
|
+
})
|
43
|
+
end
|
44
|
+
else
|
45
|
+
payment.send(:gateway_error, response.message)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def options_for_purchase_or_auth(money, creditcard, gateway_options)
|
52
|
+
money, creditcard, options = super
|
53
|
+
options[:execute_threed] = get_preference(:intents)
|
54
|
+
return money, creditcard, options
|
55
|
+
end
|
56
|
+
|
57
|
+
def public_preference_keys
|
58
|
+
%i[publishable_key test_mode intents]
|
59
|
+
end
|
6
60
|
end
|
7
61
|
end
|
@@ -54,6 +54,7 @@ module Spree
|
|
54
54
|
|
55
55
|
def create_profile(payment)
|
56
56
|
return unless payment.source.gateway_customer_profile_id.nil?
|
57
|
+
|
57
58
|
options = {
|
58
59
|
email: payment.order.email,
|
59
60
|
login: preferred_secret_key,
|
@@ -142,5 +143,9 @@ module Spree
|
|
142
143
|
url = 'https://spreecommerce.org'
|
143
144
|
"#{name_with_version} #{url}"
|
144
145
|
end
|
146
|
+
|
147
|
+
def public_preference_keys
|
148
|
+
%i[publishable_key test_mode]
|
149
|
+
end
|
145
150
|
end
|
146
151
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module SpreeGateway
|
2
2
|
module ApplePayOrderDecorator
|
3
3
|
def confirmation_required?
|
4
4
|
return false if paid_with_apple_pay?
|
@@ -17,4 +17,4 @@ module Spree
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
Spree::Order.prepend
|
20
|
+
::Spree::Order.prepend(::SpreeGateway::ApplePayOrderDecorator)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module SpreeGateway
|
2
2
|
module ApplePayPaymentDecorator
|
3
3
|
def apple_pay?
|
4
4
|
payment_method.is_a? Spree::Gateway::StripeApplePayGateway
|
@@ -6,4 +6,4 @@ module Spree
|
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
-
Spree::Payment.prepend
|
9
|
+
::Spree::Payment.prepend(::SpreeGateway::ApplePayPaymentDecorator)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module SpreeGateway
|
2
|
+
module OrderDecorator
|
3
|
+
def self.prepended(base)
|
4
|
+
return if base.checkout_steps.key?(:payment_confirm)
|
5
|
+
|
6
|
+
base.insert_checkout_step(
|
7
|
+
:payment_confirm,
|
8
|
+
before: :complete,
|
9
|
+
if: ->(order) { order.intents? }
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
def process_payments!
|
14
|
+
# Payments are processed in confirm_payment step where after successful
|
15
|
+
# 3D Secure authentication `intent_client_key` is saved for payment.
|
16
|
+
# In case authentication is unsuccessful, `intent_client_key` is removed.
|
17
|
+
return if intents? && payments.valid.last.intent_client_key.present?
|
18
|
+
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
def intents?
|
23
|
+
payments.valid.map { |p| p.payment_method&.has_preference?(:intents) && p.payment_method&.get_preference(:intents) }.any?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
::Spree::Order.prepend(::SpreeGateway::OrderDecorator)
|
@@ -1,5 +1,12 @@
|
|
1
|
-
module
|
1
|
+
module SpreeGateway
|
2
2
|
module PaymentDecorator
|
3
|
+
def handle_response(response, success_state, failure_state)
|
4
|
+
if response.success? && response.respond_to?(:params)
|
5
|
+
self.intent_client_key = response.params['client_secret'] if response.params['client_secret']
|
6
|
+
end
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
3
10
|
def verify!(**options)
|
4
11
|
process_verification(options)
|
5
12
|
end
|
@@ -26,4 +33,4 @@ module Spree
|
|
26
33
|
end
|
27
34
|
end
|
28
35
|
|
29
|
-
Spree::Payment.prepend
|
36
|
+
::Spree::Payment.prepend(::SpreeGateway::PaymentDecorator)
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<div id='errorBox' class='errorExplanation alert alert-danger' style='display:none'></div>
|
2
|
+
<div id='successBox' class='alert alert-success' style='display:none'></div>
|
3
|
+
<div id='infoBox' class='alert alert-info'><%= t('spree.please_wait_for_confirmation_popup') %></div>
|
4
|
+
|
5
|
+
<% if @client_secret.present? && @pk_key.present? %>
|
6
|
+
<script type="text/javascript" src="https://js.stripe.com/v3/"></script>
|
7
|
+
<script>
|
8
|
+
var form = document.getElementById('checkout_form_payment_confirm');
|
9
|
+
|
10
|
+
function confirmCardPaymentResponseHandler(response) {
|
11
|
+
$.post("/api/v2/storefront/intents/handle_response", { response: response, order_token: "<%= @order.token %>" }).done(function (result) {
|
12
|
+
// conditional needs for spree 3.7
|
13
|
+
if(form.elements["commit"]) {
|
14
|
+
form.elements["commit"].disabled = false;
|
15
|
+
}
|
16
|
+
$('#successBox').html(result.message);
|
17
|
+
$('#successBox').show();
|
18
|
+
form.submit();
|
19
|
+
}).fail(function(result) {
|
20
|
+
if(form.elements["commit"]) {
|
21
|
+
form.elements["commit"].disabled = false;
|
22
|
+
}
|
23
|
+
$('#errorBox').html(result.responseJSON.error);
|
24
|
+
$('#errorBox').show();
|
25
|
+
});
|
26
|
+
}
|
27
|
+
|
28
|
+
var stripeElements = Stripe("<%= @pk_key %>");
|
29
|
+
stripeElements.confirmCardPayment("<%= @client_secret %>").then(function(result) {
|
30
|
+
$('#infoBox').hide();
|
31
|
+
confirmCardPaymentResponseHandler(result);
|
32
|
+
});
|
33
|
+
|
34
|
+
document.addEventListener('DOMContentLoaded', function(){
|
35
|
+
form.elements["commit"].value = "continue"
|
36
|
+
form.elements["commit"].disabled = true
|
37
|
+
});
|
38
|
+
</script>
|
39
|
+
<% end %>
|
data/config/locales/en.yml
CHANGED
@@ -10,6 +10,10 @@ en:
|
|
10
10
|
spree:
|
11
11
|
check: Check
|
12
12
|
payment_has_been_cancelled: The payment has been cancelled.
|
13
|
+
please_wait_for_confirmation_popup: Please wait for payment confirmation popup to appear.
|
14
|
+
payment_successfully_authorized: The payment was successfully authorized.
|
15
|
+
order_state:
|
16
|
+
payment_confirm: Verify payment
|
13
17
|
log_entry:
|
14
18
|
braintree:
|
15
19
|
message: Message
|
data/config/routes.rb
CHANGED
@@ -4,3 +4,15 @@
|
|
4
4
|
Rails.application.routes.draw do
|
5
5
|
get '/.well-known/apple-developer-merchantid-domain-association' => 'spree/apple_pay_domain_verification#show'
|
6
6
|
end
|
7
|
+
|
8
|
+
Spree::Core::Engine.add_routes do
|
9
|
+
namespace :api, defaults: { format: 'json' } do
|
10
|
+
namespace :v2 do
|
11
|
+
namespace :storefront do
|
12
|
+
namespace :intents do
|
13
|
+
post :handle_response
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Spree
|
2
|
+
module Api
|
3
|
+
module V2
|
4
|
+
module Storefront
|
5
|
+
class IntentsController < ::Spree::Api::V2::BaseController
|
6
|
+
include Spree::Api::V2::Storefront::OrderConcern
|
7
|
+
|
8
|
+
def handle_response
|
9
|
+
if params['response']['error']
|
10
|
+
invalidate_payment
|
11
|
+
render_error_payload(params['response']['error']['message'])
|
12
|
+
else
|
13
|
+
render_serialized_payload { { message: I18n.t('spree.payment_successfully_authorized') } }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def invalidate_payment
|
20
|
+
payment = spree_current_order.payments.find_by!(response_code: params['response']['error']['payment_intent']['id'])
|
21
|
+
payment.update(state: 'failed', intent_client_key: nil)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Spree
|
2
|
+
module CheckoutControllerDecorator
|
3
|
+
def self.prepended(base)
|
4
|
+
base.before_action :process_payments_and_set_keys, only: :edit, if: proc { params[:state] == 'payment_confirm' }
|
5
|
+
end
|
6
|
+
|
7
|
+
def process_payments_and_set_keys
|
8
|
+
@order.tap do |order|
|
9
|
+
order.process_payments!
|
10
|
+
order.reload.payments.valid.where.not(intent_client_key: nil).last.tap do |payment|
|
11
|
+
@client_secret = payment.intent_client_key
|
12
|
+
@pk_key = payment.payment_method.preferred_publishable_key
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
::Spree::CheckoutController.prepend Spree::CheckoutControllerDecorator
|
data/lib/spree_gateway/engine.rb
CHANGED
@@ -41,9 +41,18 @@ module SpreeGateway
|
|
41
41
|
Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/spree/*_decorator*.rb')) do |c|
|
42
42
|
Rails.application.config.cache_classes ? require(c) : load(c)
|
43
43
|
end
|
44
|
+
Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/spree_gateway/*_decorator*.rb')) do |c|
|
45
|
+
Rails.application.config.cache_classes ? require(c) : load(c)
|
46
|
+
end
|
44
47
|
Dir.glob(File.join(File.dirname(__FILE__), '../../lib/active_merchant/**/*_decorator*.rb')) do |c|
|
45
48
|
Rails.application.config.cache_classes ? require(c) : load(c)
|
46
49
|
end
|
50
|
+
|
51
|
+
if self.frontend_available?
|
52
|
+
Dir.glob(File.join(File.dirname(__FILE__), '../../lib/spree_frontend/controllers/spree/*_decorator*.rb')) do |c|
|
53
|
+
Rails.application.config.cache_classes ? require(c) : load(c)
|
54
|
+
end
|
55
|
+
end
|
47
56
|
end
|
48
57
|
|
49
58
|
def self.backend_available?
|
@@ -61,6 +70,7 @@ module SpreeGateway
|
|
61
70
|
paths['app/controllers'] << 'lib/controllers'
|
62
71
|
|
63
72
|
if self.frontend_available?
|
73
|
+
paths["app/controllers"] << "lib/spree_frontend/controllers"
|
64
74
|
paths["app/views"] << "lib/views/frontend"
|
65
75
|
end
|
66
76
|
|