spree_gateway 3.7.4 → 3.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +36 -37
  3. data/Appraisals +3 -8
  4. data/app/models/spree/check.rb +41 -0
  5. data/app/models/spree/credit_card_decorator.rb +10 -0
  6. data/app/models/spree/gateway/stripe_ach_gateway.rb +60 -0
  7. data/app/models/spree/gateway/stripe_elements_gateway.rb +50 -0
  8. data/app/models/spree/gateway/stripe_gateway.rb +1 -0
  9. data/app/models/spree/order_decorator.rb +28 -0
  10. data/app/models/spree/payment_decorator.rb +36 -0
  11. data/app/views/spree/checkout/_payment_confirm.html.erb +39 -0
  12. data/config/initializers/spree_permitted_attributes.rb +5 -0
  13. data/config/locales/en.yml +23 -0
  14. data/config/routes.rb +12 -0
  15. data/db/migrate/20200317135551_add_spree_check_payment_source.rb +22 -0
  16. data/db/migrate/20200422114908_add_intent_key_to_payment.rb +5 -0
  17. data/gemfiles/{spree_3_5.gemfile → spree_4_1.gemfile} +1 -1
  18. data/lib/active_merchant/billing/stripe_gateway_decorator.rb +13 -0
  19. data/lib/controllers/spree/api/v2/storefront/intents_controller.rb +27 -0
  20. data/lib/spree_frontend/controllers/spree/checkout_controller_decorator.rb +19 -0
  21. data/lib/spree_gateway/engine.rb +8 -0
  22. data/lib/spree_gateway/version.rb +1 -1
  23. data/lib/views/backend/spree/admin/payments/source_forms/_stripe_ach.html.erb +86 -0
  24. data/lib/views/backend/spree/admin/payments/source_forms/_stripe_apple_pay.html.erb +0 -0
  25. data/lib/views/backend/spree/admin/payments/source_views/_stripe_ach.html.erb +21 -0
  26. data/lib/views/backend/spree/admin/payments/source_views/_stripe_apple_pay.html.erb +1 -0
  27. data/lib/views/frontend/spree/checkout/payment/_stripe_ach.html.erb +81 -0
  28. data/lib/views/frontend/spree/checkout/payment/_stripe_ach_verify.html.erb +16 -0
  29. data/lib/views/frontend/spree/checkout/payment/_stripe_apple_pay.html.erb +10 -1
  30. data/lib/views/frontend/spree/checkout/payment/_stripe_elements.html.erb +2 -1
  31. data/spec/factories/check_factory.rb +10 -0
  32. data/spec/features/admin/stripe_elements_payment_spec.rb +32 -32
  33. data/spec/features/stripe_checkout_spec.rb +30 -19
  34. data/spec/features/stripe_elements_3ds_checkout_spec.rb +224 -0
  35. data/spec/models/gateway/stripe_ach_gateway_spec.rb +186 -0
  36. data/spec/models/gateway/stripe_gateway_spec.rb +1 -0
  37. data/spec/spec_helper.rb +7 -65
  38. data/spec/support/order_walktrough.rb +73 -0
  39. data/spec/support/within_stripe_3ds_popup.rb +10 -0
  40. data/spree_gateway.gemspec +10 -22
  41. metadata +44 -282
  42. data/gemfiles/spree_4_0.gemfile +0 -8
  43. data/spec/support/capybara_helper.rb +0 -15
@@ -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,22 @@
1
+ class AddSpreeCheckPaymentSource < ActiveRecord::Migration[5.1]
2
+ def change
3
+ create_table :spree_checks do |t|
4
+ t.references :payment_method
5
+ t.references :user
6
+ t.string "account_holder_name"
7
+ t.string "account_holder_type"
8
+ t.string "routing_number"
9
+ t.string "account_number"
10
+ t.string "account_type", default: 'checking'
11
+ t.string "status"
12
+ t.string "last_digits"
13
+ t.string "gateway_customer_profile_id"
14
+ t.string "gateway_payment_profile_id"
15
+
16
+ t.datetime "created_at", null: false
17
+ t.datetime "updated_at", null: false
18
+ t.datetime "deleted_at"
19
+ end
20
+ add_index :spree_payment_methods, :id
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ class AddIntentKeyToPayment < ActiveRecord::Migration[4.2]
2
+ def change
3
+ add_column :spree_payments, :intent_client_key, :string
4
+ end
5
+ end
@@ -3,6 +3,6 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "rails-controller-testing"
6
- gem "spree", "~> 3.5.0"
6
+ gem "spree", "~> 4.1.0"
7
7
 
8
8
  gemspec path: "../"
@@ -1,6 +1,19 @@
1
1
  module ActiveMerchant
2
2
  module Billing
3
3
  module StripeGatewayDecorator
4
+ def verify(source, **options)
5
+ customer = source.gateway_customer_profile_id
6
+ bank_account_token = source.gateway_payment_profile_id
7
+
8
+ commit(:post, "customers/#{CGI.escape(customer)}/sources/#{bank_account_token}/verify", amounts: options[:amounts])
9
+ end
10
+
11
+ def retrieve(source, **options)
12
+ customer = source.gateway_customer_profile_id
13
+ bank_account_token = source.gateway_payment_profile_id
14
+ commit(:get, "customers/#{CGI.escape(customer)}/bank_accounts/#{bank_account_token}")
15
+ end
16
+
4
17
  private
5
18
 
6
19
  def headers(options = {})
@@ -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
@@ -32,6 +32,7 @@ module SpreeGateway
32
32
  app.config.spree.payment_methods << Spree::Gateway::StripeGateway
33
33
  app.config.spree.payment_methods << Spree::Gateway::StripeElementsGateway
34
34
  app.config.spree.payment_methods << Spree::Gateway::StripeApplePayGateway
35
+ app.config.spree.payment_methods << Spree::Gateway::StripeAchGateway
35
36
  app.config.spree.payment_methods << Spree::Gateway::UsaEpayTransaction
36
37
  app.config.spree.payment_methods << Spree::Gateway::Worldpay
37
38
  end
@@ -43,6 +44,12 @@ module SpreeGateway
43
44
  Dir.glob(File.join(File.dirname(__FILE__), '../../lib/active_merchant/**/*_decorator*.rb')) do |c|
44
45
  Rails.application.config.cache_classes ? require(c) : load(c)
45
46
  end
47
+
48
+ if self.frontend_available?
49
+ Dir.glob(File.join(File.dirname(__FILE__), '../../lib/spree_frontend/controllers/spree/*_decorator*.rb')) do |c|
50
+ Rails.application.config.cache_classes ? require(c) : load(c)
51
+ end
52
+ end
46
53
  end
47
54
 
48
55
  def self.backend_available?
@@ -60,6 +67,7 @@ module SpreeGateway
60
67
  paths['app/controllers'] << 'lib/controllers'
61
68
 
62
69
  if self.frontend_available?
70
+ paths["app/controllers"] << "lib/spree_frontend/controllers"
63
71
  paths["app/views"] << "lib/views/frontend"
64
72
  end
65
73
 
@@ -1,5 +1,5 @@
1
1
  module SpreeGateway
2
2
  def self.version
3
- '3.7.4'
3
+ '3.9.3'
4
4
  end
5
5
  end
@@ -0,0 +1,86 @@
1
+ <fieldset data-id="bank_transfer">
2
+ <div id="bank_transfer_form<%= payment_method.id %>" class="margint" data-hook>
3
+ <% param_prefix = "payment_source[#{payment_method.id}]" %>
4
+
5
+ <div data-hook="account_holder_name" class="form-group">
6
+ <%= label_tag "account_holder_name#{payment_method.id}", raw(Spree.t('stripe.ach.account_holder_name') + required_span_tag) %>
7
+ <%= text_field_tag "#{param_prefix}[account_holder_name]", '', class: 'required form-control', id: "account_holder_name#{payment_method.id}" %>
8
+ </div>
9
+
10
+ <div data-hook="account_holder_type">
11
+ <%= label_tag "account_holder_type#{payment_method.id}", raw(Spree.t('stripe.ach.account_holder_type') + required_span_tag) %>
12
+ <%= select_tag "#{param_prefix}[account_holder_type]", options_for_select(%w(Individual Company)), {id: "account_holder_type#{payment_method.id}", class: 'required form-control'} %>
13
+ </div>
14
+
15
+ <div data-hook="routing_number">
16
+ <%= label_tag "routing_number#{payment_method.id}", raw(Spree.t('stripe.ach.routing_number') + required_span_tag)%>
17
+ <%= text_field_tag "#{param_prefix}[routing_number]", '', class: 'required form-control', id: "routing_number#{payment_method.id}", maxlength: 9 %>
18
+ </div>
19
+ <div data-hook="account_number">
20
+ <%= label_tag "account_number#{payment_method.id}", raw(Spree.t('stripe.ach.account_number') + required_span_tag) %>
21
+ <%= text_field_tag "#{param_prefix}[account_number]", '', class: 'required form-control', id: "account_number#{payment_method.id}" %>
22
+ </div>
23
+ <div data-hook="account_number">
24
+ <%= label_tag "verify_account_number#{payment_method.id}", raw(Spree.t('stripe.ach.verify_account_number') + required_span_tag) %>
25
+ <%= text_field_tag "#{param_prefix}[verify_account_number]", '', class: 'required form-control', id: "verify_account_number#{payment_method.id}" %>
26
+ </div>
27
+ </div>
28
+ </fieldset>
29
+
30
+ <script type="text/javascript" src="https://js.stripe.com/v3/"></script>
31
+ <script type="text/javascript">
32
+ var stripe = Stripe("<%= payment_method.preferred_publishable_key %>");
33
+ </script>
34
+
35
+ <script>
36
+ stripeResponseHandler = function(response) {
37
+ var token, paymentMethodId;
38
+ if (response.error) {
39
+ $('#stripeError').html(response.error.message);
40
+ const param_map = {
41
+ account_holder_name: '#account_holder_name',
42
+ account_holder_type: '#account_holder_type',
43
+ account_number: '#account_number',
44
+ routing_number: '#routing_number'
45
+ }
46
+ if (response.error.param){
47
+ errorField = Spree.stripePaymentMethod.find(param_map[response.error.param])
48
+ errorField.addClass('error');
49
+ errorField.parent().addClass('has-error');
50
+ }
51
+ return $('#stripeError').show();
52
+ } else {
53
+ Spree.stripePaymentMethod.find('#account_holder_name, #account_holder_type, #account_number, #routing_number').prop("disabled", true);
54
+ token = response.token['id'];
55
+ paymentMethodId = Spree.stripePaymentMethod.prop('id').split("_")[2];
56
+ Spree.stripePaymentMethod.append("<input type='hidden' class='stripeToken' name='payment_source[" + paymentMethodId + "][gateway_payment_profile_id]' value='" + token + "'/>");
57
+ return Spree.stripePaymentMethod.parents("form").trigger('submit');
58
+ }
59
+ };
60
+
61
+ window.addEventListener('DOMContentLoaded', function() {
62
+ Spree.stripePaymentMethod = $('#payment_method_' + <%= payment_method.id %>);
63
+
64
+ Spree.ready(function() {
65
+ Spree.stripePaymentMethod.prepend("<div id='stripeError' class='errorExplanation alert alert-danger' style='display:none'></div>");
66
+ return $('#new_payment [data-hook=buttons]').click(function() {
67
+ var params;
68
+ $('#stripeError').hide();
69
+ Spree.stripePaymentMethod.find('#account_holder_name, #account_holder_type, #account_number, #routing_number').removeClass('error');
70
+ if (Spree.stripePaymentMethod.is(':visible')) {
71
+ params = $.extend({
72
+ country: 'US',
73
+ currency: 'usd',
74
+ account_holder_name: $('.account_holder_name:visible').val(),
75
+ account_holder_type: $('.account_holder_type:visible').val(),
76
+ routing_number: $('.routing_number:visible').val(),
77
+ account_number: $('.account_number:visible').val()
78
+ }, Spree.stripeAdditionalInfo);
79
+ stripe.createToken('bank_account', params).then(stripeResponseHandler);
80
+ return false;
81
+ }
82
+ });
83
+ });
84
+ });
85
+ </script>
86
+
@@ -0,0 +1,21 @@
1
+ <fieldset data-hook="bank_transfer">
2
+ <legend><%= Spree.t(:bank_transfer) %></legend>
3
+ <table class="table table-condensed table-bordered">
4
+ <tr>
5
+ <th width="20%"><%= Spree.t('stripe.ach.account_holder_name') %>:</th>
6
+ <td><%= payment.source.account_holder_name %></td>
7
+ </tr>
8
+ <tr>
9
+ <th><%= Spree.t('stripe.ach.account_holder_type') %>:</th>
10
+ <td><%= payment.source.account_holder_type %></td>
11
+ </tr>
12
+ <tr>
13
+ <th><%= Spree.t('stripe.ach.routing_number') %>:</th>
14
+ <td><%= payment.source.routing_number %></td>
15
+ </tr>
16
+ <tr>
17
+ <th><%= Spree.t('stripe.ach.account_number') %>:</th>
18
+ <td><%= payment.source.account_number %></td>
19
+ </tr>
20
+ </table>
21
+ </fieldset>
@@ -0,0 +1 @@
1
+ <%= render "spree/admin/payments/source_views/gateway", payment: payment %>
@@ -0,0 +1,81 @@
1
+ <div class="payment-gateway">
2
+ <% param_prefix = "payment_source[#{payment_method.id}]" %>
3
+ <div class="payment-gateway-half-fields">
4
+ <div class="mb-4 payment-gateway-field checkout-content-inner-field">
5
+ <%= text_field_tag "#{param_prefix}[account_holder_name]", "#{@order.bill_address_firstname} #{@order.bill_address_lastname}", { id: "account_holder_name", class: 'spree-flat-input', placeholder: Spree.t('stripe.ach.account_holder_name')} %>
6
+ </div>
7
+ <div class="mb-4 payment-gateway-field checkout-content-inner-field">
8
+ <%= select_tag "#{param_prefix}[account_holder_type]", options_for_select(%w(Individual Company)), {id: "account_holder_type", class: 'spree-flat-input', placeholder: Spree.t('stripe.ach.account_holder_type')} %>
9
+ </div>
10
+
11
+ <div class="mb-4 payment-gateway-field checkout-content-inner-field" data-hook="account_number">
12
+ <%= text_field_tag "#{param_prefix}[routing_number]", '', {id: 'routing_number', class: 'spree-flat-input', autocomplete: "off", placeholder: Spree.t('stripe.ach.routing_number'), maxlength: 9} %>
13
+ </div>
14
+ <div class="mb-4 payment-gateway-field checkout-content-inner-field" data-hook="account_number">
15
+ <%= text_field_tag "#{param_prefix}[account_number]", '', {id: 'account_number', class: 'spree-flat-input', autocomplete: "off", placeholder: Spree.t('stripe.ach.account_number')} %>
16
+ </div>
17
+ <div class="mb-4 payment-gateway-field checkout-content-inner-field" data-hook="account_number">
18
+ <%= text_field_tag "#{param_prefix}[verify_account_number]", '', {id: 'verify_account_number', class: 'spree-flat-input', autocomplete: "off", placeholder: Spree.t('stripe.ach.verify_account_number')} %>
19
+ </div>
20
+ </div>
21
+ </div>
22
+
23
+ <script type="text/javascript" src="https://js.stripe.com/v3/"></script>
24
+ <script type="text/javascript">
25
+ var stripe = Stripe("<%= payment_method.preferred_publishable_key %>");
26
+ </script>
27
+
28
+ <script>
29
+ stripeResponseHandler = function(response) {
30
+ var paymentMethodId, token, bank_acc_status;
31
+ if (response.error) {
32
+ $('#stripeError').html(response.error.message);
33
+ var param_map = {
34
+ account_holder_name: '#account_holder_name',
35
+ account_holder_type: '#account_holder_type',
36
+ account_number: '#account_number',
37
+ routing_number: '#routing_number'
38
+ }
39
+ if (response.error.param){
40
+ errorField = Spree.stripePaymentMethod.find(param_map[response.error.param])
41
+ errorField.addClass('error');
42
+ errorField.parent().addClass('has-error');
43
+ }
44
+ return $('#stripeError').show();
45
+ } else {
46
+ token = response.token['id'];
47
+ bank_acc_status = response.token.bank_account['status'];
48
+ paymentMethodId = Spree.stripePaymentMethod.prop('id').split("_")[2];
49
+ Spree.stripePaymentMethod.append("<input type='hidden' class='stripeToken' name='payment_source[" + paymentMethodId + "][gateway_payment_profile_id]' value='" + token + "'/>");
50
+ Spree.stripePaymentMethod.append("<input type='hidden' class='stripeStatus' name='payment_source[" + paymentMethodId + "][status]' value='" + bank_acc_status + "'/>")
51
+ return Spree.stripePaymentMethod.parents("form").trigger('submit');
52
+ }
53
+ };
54
+
55
+ window.addEventListener('DOMContentLoaded', function () {
56
+ Spree.stripePaymentMethod = $('#payment_method_' + <%= payment_method.id %>);
57
+ Spree.stripePaymentMethod.prepend("<div id='stripeError' class='errorExplanation alert alert-danger' style='display:none'></div>");
58
+
59
+ $('#checkout_form_payment [data-hook=buttons]').click(function (e) {
60
+ var params;
61
+ $('#stripeError').hide();
62
+ Spree.stripePaymentMethod.find('#account_holder_name, #account_holder_type, #account_number, #routing_number').removeClass('error');
63
+ if (Spree.stripePaymentMethod.is(':visible')) {
64
+ e.preventDefault();
65
+
66
+ params = $.extend({
67
+ country: 'US',
68
+ currency: 'usd',
69
+ account_holder_name: $('#account_holder_name:visible').val(),
70
+ account_holder_type: $('#account_holder_type:visible').val(),
71
+ routing_number: $('#routing_number:visible').val(),
72
+ account_number: $('#account_number:visible').val()
73
+ }, Spree.stripeAdditionalInfo);
74
+
75
+ stripe.createToken('bank_account', params).then(stripeResponseHandler);
76
+
77
+ return false;
78
+ }
79
+ });
80
+ });
81
+ </script>
@@ -0,0 +1,16 @@
1
+ <p class="payment-type checkout-content-header">
2
+ <%= Spree.t('stripe.ach.verify_bank_account').upcase %>
3
+ </p>
4
+
5
+ <div class="payment-gateway">
6
+ <div class="payment-gateway-half-fields">
7
+ <input type="hidden" name="order[payment_id]" value= <%= payment.id %> />
8
+ <input type='hidden' name='verifyAch' value=true />
9
+ <div class="mb-4 payment-gateway-field checkout-content-inner-field">
10
+ <%= number_field_tag "amounts[]", nil, { id: "deposit1", class: 'spree-flat-input', placeholder: Spree.t('stripe.ach.first_deposit') } %>
11
+ </div>
12
+ <div class="mb-4 payment-gateway-field checkout-content-inner-field">
13
+ <%= number_field_tag "amounts[]", nil, { id: "deposit2", class: 'spree-flat-input', placeholder: Spree.t('stripe.ach.second_deposit') } %>
14
+ </div>
15
+ </div>
16
+ </div>
@@ -9,7 +9,6 @@
9
9
  <script>
10
10
  var stripeApplePay = Stripe("<%= payment_method.preferred_publishable_key %>");
11
11
  var elements = stripeApplePay.elements();
12
-
13
12
  var paymentRequest = stripeApplePay.paymentRequest({
14
13
  country: '<%= payment_method.preferred_country_code.try(:upcase) %>',
15
14
  currency: '<%= @order.currency.downcase %>',
@@ -64,6 +63,15 @@
64
63
  form.appendChild(hiddenInput);
65
64
  };
66
65
 
66
+ function hideApplePayRadioButtonForNonAppleDevices() {
67
+ var isSafari = !!navigator.userAgent.match(/Version\/[\d\.]+.*Safari/);
68
+ var isiOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
69
+
70
+ if (!isSafari && !isiOS) {
71
+ $('input[name$="order[payments_attributes][][payment_method_id]"][value="<%= payment_method.id %>"]').closest('li').hide()
72
+ }
73
+ }
74
+
67
75
  paymentRequest.on('token', function(ev) {
68
76
  var form = document.getElementById('checkout_form_payment');
69
77
  var token = ev.token;
@@ -83,6 +91,7 @@
83
91
 
84
92
  window.addEventListener('DOMContentLoaded', function() {
85
93
  Spree.stripeApplePayPaymentMethod = $('#payment_method_' + <%= payment_method.id %>);
94
+ hideApplePayRadioButtonForNonAppleDevices();
86
95
 
87
96
  prButton.on('ready', function () {
88
97
  Spree.stripeApplePayPaymentMethod.prepend("<div id='stripeApplePayError' class='errorExplanation alert alert-danger' style='display:none'></div>");
@@ -103,7 +103,8 @@
103
103
  }
104
104
  });
105
105
  };
106
-
106
+
107
107
  </script>
108
108
 
109
109
  <%= render 'spree/checkout/payment/stripe_additional_info' %>
110
+
@@ -0,0 +1,10 @@
1
+ FactoryBot.define do
2
+ factory :check, class: Spree::Check do
3
+ account_holder_name { 'John Doe' }
4
+ account_holder_type { 'Individual' }
5
+ account_type { 'checking' }
6
+ routing_number { '110000000' }
7
+ account_number { '000123456789' }
8
+ association(:payment_method, factory: :credit_card_payment_method)
9
+ end
10
+ end
@@ -1,53 +1,43 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Admin Panel Stripe elements payment', type: :feature, :js => true do
3
+ describe 'Admin Panel Stripe elements payment', type: :feature do
4
4
  stub_authorization!
5
5
 
6
- let!(:country) { create(:country, :states_required => true) }
7
- let!(:state) { create(:state, :country => country) }
6
+ let!(:country) { create(:country, states_required: true) }
7
+ let!(:state) { create(:state, country: country) }
8
8
  let!(:shipping_method) { create(:shipping_method) }
9
- let!(:stock_location) { create(:stock_location) }
10
- let!(:mug) { create(:product, :name => 'RoR Mug') }
11
- let!(:zone) { create(:zone) }
9
+ let!(:stock_location) { create(:stock_location) }
10
+ let!(:mug) { create(:product, name: 'RoR Mug') }
11
+ let!(:zone) { create(:zone) }
12
12
  let!(:stripe_elements_payment_method) do
13
13
  Spree::Gateway::StripeElementsGateway.create!(
14
- :name => 'Stripe Element',
15
- :preferred_secret_key => 'sk_test_VCZnDv3GLU15TRvn8i2EsaAN',
16
- :preferred_publishable_key => 'pk_test_Cuf0PNtiAkkMpTVC2gwYDMIg'
14
+ name: 'Stripe Element',
15
+ preferred_secret_key: 'sk_test_VCZnDv3GLU15TRvn8i2EsaAN',
16
+ preferred_publishable_key: 'pk_test_Cuf0PNtiAkkMpTVC2gwYDMIg'
17
17
  )
18
18
  end
19
-
19
+
20
20
  let!(:order) { OrderWalkthrough.up_to(:payment) }
21
21
  before { visit spree.new_admin_order_payment_path(order.number) }
22
22
 
23
23
  it 'can process a valid payment' do
24
24
  fill_in_stripe_payment
25
25
  wait_for { !page.has_current_path?(spree.admin_order_payments_path(order.number)) }
26
-
26
+
27
27
  expect(page.body).to have_content('Payment has been successfully created!')
28
28
  expect(page).to have_current_path spree.admin_order_payments_path(order.number)
29
29
  end
30
-
31
- if Spree.version.to_f >= 4.1
32
- it 'shows an error with an invalid card name' do
33
- fill_in_stripe_payment(true)
34
30
 
35
- expect(page).to have_content("Credit card Name can't be blank")
36
- expect(page).to have_current_path spree.admin_order_payments_path(order.number)
37
- end
38
- else
39
- it 'can proces valid payment with invalid card name' do
40
- fill_in_stripe_payment(true)
41
- wait_for { !page.has_current_path?(spree.admin_order_payments_path(order.number)) }
31
+ it 'shows an error with an invalid card name' do
32
+ fill_in_stripe_payment(true)
42
33
 
43
- expect(page.body).to have_content('Payment has been successfully created!')
44
- expect(page).to have_current_path spree.admin_order_payments_path(order.number)
45
- end
34
+ expect(page).to have_content("Credit card Name can't be blank")
35
+ expect(page).to have_current_path spree.admin_order_payments_path(order.number)
46
36
  end
47
37
 
48
38
  it 'shows an error with an invalid card number' do
49
39
  fill_in_stripe_payment(false, true)
50
-
40
+
51
41
  expect(page).to have_content('The card number is not a valid credit card number.')
52
42
  expect(page).to have_current_path spree.new_admin_order_payment_path(order.number)
53
43
  end
@@ -62,7 +52,7 @@ describe 'Admin Panel Stripe elements payment', type: :feature, :js => true do
62
52
  it 'shows an error with an invalid card expiration' do
63
53
  fill_in_stripe_payment(false, false, false, true)
64
54
 
65
- if Spree.version.to_f >= 4.1
55
+ if Spree.version.to_f >= 4.1 || Spree.version.to_f >= 3.7
66
56
  expect(page).to have_content('Credit card Month is not a number')
67
57
  expect(page).to have_content('Credit card Year is not a number')
68
58
  expect(page).to have_current_path spree.admin_order_payments_path(order.number)
@@ -75,20 +65,30 @@ describe 'Admin Panel Stripe elements payment', type: :feature, :js => true do
75
65
  def fill_in_stripe_payment(invalid_name = false, invalid_number = false, invalid_code = false, invalid_expiration = false)
76
66
  fill_in 'Name *', with: invalid_name ? '' : 'Stripe Elements Gateway Payment'
77
67
  fill_in_card_number(invalid_number)
78
- fill_in 'Card Code *', with: invalid_code ? '1' : '123'
68
+ fill_in_cvc(invalid_code)
79
69
  fill_in_card_expiration(invalid_expiration)
80
70
 
81
- click_button "Update"
71
+ click_button 'Update'
82
72
  end
83
73
 
84
74
  def fill_in_card_number(invalid_number)
85
75
  number = invalid_number ? '123' : '4242 4242 4242 4242'
86
- fill_in_field('Card Number *', '#card_number1', number)
76
+ fill_in_field('Card Number *', "#card_number#{stripe_elements_payment_method.id}", number)
87
77
  end
88
78
 
89
79
  def fill_in_card_expiration(invalid_expiration)
90
- card_expiry = invalid_expiration ? '01 / ' : "01 / #{Time.current.year + 1}"
91
- fill_in_field('Expiration *', '#card_expiry1', card_expiry)
80
+ valid_expiry = Spree.version.to_f >= 4.2 ? "01/#{Time.current.year + 1}" : "01 / #{Time.current.year + 1}"
81
+ invalid_expiry = Spree.version.to_f >= 4.2 ? '01/' : '01 / '
82
+
83
+ card_expiry = invalid_expiration ? invalid_expiry : valid_expiry
84
+ fill_in_field('Expiration *', "#card_expiry#{stripe_elements_payment_method.id}", card_expiry)
85
+ end
86
+
87
+ def fill_in_cvc(invalid_code)
88
+ value = invalid_code ? '1' : '123'
89
+ label = Spree.version.to_f >= 4.2 ? 'Card Varification Code (CVC) *' : 'Card Code *'
90
+
91
+ fill_in label, with: value
92
92
  end
93
93
 
94
94
  def fill_in_field(field_name, field_id, number)