solidus_stripe 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 +7 -0
- data/.circleci/config.yml +35 -0
- data/.gem_release.yml +8 -0
- data/.gitignore +11 -0
- data/.rspec +1 -0
- data/.rubocop.yml +319 -0
- data/.travis.yml +28 -0
- data/Gemfile +25 -0
- data/LICENSE.md +26 -0
- data/README.md +115 -0
- data/Rakefile +23 -0
- data/app/models/spree/payment_method/stripe_credit_card.rb +136 -0
- data/bin/rails +7 -0
- data/db/migrate/20181010123508_update_stripe_payment_method_type_to_credit_card.rb +21 -0
- data/db/seeds.rb +26 -0
- data/lib/assets/stylesheets/spree/frontend/solidus_stripe.scss +6 -0
- data/lib/generators/solidus_stripe/install/install_generator.rb +46 -0
- data/lib/solidus_stripe.rb +7 -0
- data/lib/solidus_stripe/engine.rb +23 -0
- data/lib/solidus_stripe/version.rb +5 -0
- data/lib/tasks/solidus_stripe/db/seed.rake +14 -0
- data/lib/views/api/spree/api/payments/source_views/_stripe.json.jbuilder +3 -0
- data/lib/views/backend/spree/admin/log_entries/_stripe.html.erb +28 -0
- data/lib/views/backend/spree/admin/payments/source_forms/_stripe.html.erb +1 -0
- data/lib/views/backend/spree/admin/payments/source_views/_stripe.html.erb +1 -0
- data/lib/views/frontend/spree/checkout/existing_payment/_stripe.html.erb +1 -0
- data/lib/views/frontend/spree/checkout/payment/_stripe.html.erb +6 -0
- data/lib/views/frontend/spree/checkout/payment/v2/_javascript.html.erb +77 -0
- data/lib/views/frontend/spree/checkout/payment/v3/_stripe.html.erb +133 -0
- data/solidus_stripe.gemspec +45 -0
- data/spec/features/stripe_checkout_spec.rb +279 -0
- data/spec/models/spree/payment_method/stripe_credit_card_spec.rb +205 -0
- data/spec/spec_helper.rb +20 -0
- metadata +264 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
<tr>
|
2
|
+
<td><%= t(:message, :scope => [:spree, :log_entry, :stripe]) %></td>
|
3
|
+
<td><%= entry.parsed_details.message %></td>
|
4
|
+
</tr>
|
5
|
+
<tr>
|
6
|
+
<td><%= t(:charge_id, :scope => [:spree, :log_entry, :stripe]) %></td>
|
7
|
+
<td><%= entry.parsed_details.params['id'] %></td>
|
8
|
+
</tr>
|
9
|
+
<% if card = entry.parsed_details.params['card'] %>
|
10
|
+
<tr>
|
11
|
+
<td><%= t(:card_id, :scope => [:spree, :log_entry, :stripe]) %></td>
|
12
|
+
<td><%= card['id'] %></td>
|
13
|
+
</tr>
|
14
|
+
|
15
|
+
<tr>
|
16
|
+
<td><%= t(:cvc_check, :scope => [:spree, :log_entry, :stripe]) %></td>
|
17
|
+
<td><%= card['cvc_check'] %></td>
|
18
|
+
</tr>
|
19
|
+
|
20
|
+
<tr>
|
21
|
+
<td><%= t(:address_zip_check, :scope => [:spree, :log_entry, :stripe]) %></td>
|
22
|
+
<td><%= card['address_zip_check'] %></td>
|
23
|
+
</tr>
|
24
|
+
<% end %>
|
25
|
+
<tr>
|
26
|
+
<td><%= t(:cvv_result, :scope => [:spree, :log_entry, :stripe]) %></td>
|
27
|
+
<td><%= entry.parsed_details.cvv_result['message'].to_s %></td>
|
28
|
+
</tr>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render "spree/admin/payments/source_forms/gateway", payment_method: payment_method, previous_cards: payment_method.reusable_sources(@order) %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render "spree/admin/payments/source_views/gateway", payment: payment %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render partial: "spree/checkout/existing_payment/gateway", locals: { wallet_payment_source: wallet_payment_source, default: default } %>
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<% if payment_method.v3_elements? %>
|
2
|
+
<%= render 'spree/checkout/payment/v3/stripe', payment_method: payment_method %>
|
3
|
+
<% else %>
|
4
|
+
<%= render "spree/checkout/payment/gateway", payment_method: payment_method %>
|
5
|
+
<%= render 'spree/checkout/payment/v2/javascript', payment_method: payment_method %>
|
6
|
+
<% end %>
|
@@ -0,0 +1,77 @@
|
|
1
|
+
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
|
2
|
+
<script type="text/javascript">
|
3
|
+
Stripe.setPublishableKey("<%= payment_method.preferred_publishable_key %>");
|
4
|
+
</script>
|
5
|
+
|
6
|
+
<script>
|
7
|
+
Spree.stripePaymentMethod = $('#payment_method_' + <%= payment_method.id %>);
|
8
|
+
var mapCC, stripeResponseHandler;
|
9
|
+
|
10
|
+
mapCC = function(ccType) {
|
11
|
+
if (ccType === 'MasterCard') {
|
12
|
+
return 'mastercard';
|
13
|
+
} else if (ccType === 'Visa') {
|
14
|
+
return 'visa';
|
15
|
+
} else if (ccType === 'American Express') {
|
16
|
+
return 'amex';
|
17
|
+
} else if (ccType === 'Discover') {
|
18
|
+
return 'discover';
|
19
|
+
} else if (ccType === 'Diners Club') {
|
20
|
+
return 'dinersclub';
|
21
|
+
} else if (ccType === 'JCB') {
|
22
|
+
return 'jcb';
|
23
|
+
}
|
24
|
+
};
|
25
|
+
|
26
|
+
stripeResponseHandler = function(status, response) {
|
27
|
+
var paymentMethodId, token;
|
28
|
+
if (response.error) {
|
29
|
+
$('#stripeError').html(response.error.message);
|
30
|
+
return $('#stripeError').show();
|
31
|
+
} else {
|
32
|
+
Spree.stripePaymentMethod.find('#card_number, #card_expiry, #card_code').prop("disabled", true);
|
33
|
+
Spree.stripePaymentMethod.find(".ccType").prop("disabled", false);
|
34
|
+
Spree.stripePaymentMethod.find(".ccType").val(mapCC(response.card.brand));
|
35
|
+
token = response['id'];
|
36
|
+
paymentMethodId = Spree.stripePaymentMethod.prop('id').split("_")[2];
|
37
|
+
Spree.stripePaymentMethod.append("<input type='hidden' class='stripeToken' name='payment_source[" + paymentMethodId + "][gateway_payment_profile_id]' value='" + token + "'/>");
|
38
|
+
Spree.stripePaymentMethod.append("<input type='hidden' class='stripeToken' name='payment_source[" + paymentMethodId + "][last_digits]' value='" + response.card.last4 + "'/>");
|
39
|
+
Spree.stripePaymentMethod.append("<input type='hidden' class='stripeToken' name='payment_source[" + paymentMethodId + "][month]' value='" + response.card.exp_month + "'/>");
|
40
|
+
Spree.stripePaymentMethod.append("<input type='hidden' class='stripeToken' name='payment_source[" + paymentMethodId + "][year]' value='" + response.card.exp_year + "'/>");
|
41
|
+
return Spree.stripePaymentMethod.parents("form").get(0).submit();
|
42
|
+
}
|
43
|
+
};
|
44
|
+
|
45
|
+
$(document).ready(function() {
|
46
|
+
Spree.stripePaymentMethod.prepend("<div id='stripeError' class='errorExplanation' style='display:none'></div>");
|
47
|
+
return $('#checkout_form_payment [data-hook=buttons]').click(function() {
|
48
|
+
var expiration, params;
|
49
|
+
$('#stripeError').hide();
|
50
|
+
if (Spree.stripePaymentMethod.is(':visible')) {
|
51
|
+
expiration = $('.cardExpiry:visible').payment('cardExpiryVal');
|
52
|
+
params = $.extend({
|
53
|
+
number: $('.cardNumber:visible').val(),
|
54
|
+
cvc: $('.cardCode:visible').val(),
|
55
|
+
exp_month: expiration.month || 0,
|
56
|
+
exp_year: expiration.year || 0
|
57
|
+
}, Spree.stripeAdditionalInfo);
|
58
|
+
Stripe.card.createToken(params, stripeResponseHandler);
|
59
|
+
return false;
|
60
|
+
}
|
61
|
+
});
|
62
|
+
});
|
63
|
+
</script>
|
64
|
+
|
65
|
+
<%- if @order.has_checkout_step?('address') -%>
|
66
|
+
<script>
|
67
|
+
Spree.stripeAdditionalInfo = {
|
68
|
+
name: "<%= @order.bill_address.full_name %>",
|
69
|
+
address_line1: "<%= @order.bill_address.address1 %>",
|
70
|
+
address_line2: "<%= @order.bill_address.address2 %>",
|
71
|
+
address_city: "<%= @order.bill_address.city %>",
|
72
|
+
address_state: "<%= @order.bill_address.state_text %>",
|
73
|
+
address_zip: "<%= @order.bill_address.zipcode %>",
|
74
|
+
address_country: "<%= @order.bill_address.country %>"
|
75
|
+
}
|
76
|
+
</script>
|
77
|
+
<%- end -%>
|
@@ -0,0 +1,133 @@
|
|
1
|
+
<%= image_tag 'credit_cards/credit_card.gif', id: 'credit-card-image' %>
|
2
|
+
<% param_prefix = "payment_source[#{payment_method.id}]" %>
|
3
|
+
|
4
|
+
<div class="field field-required">
|
5
|
+
<%= label_tag "name_on_card_#{payment_method.id}", t('spree.name_on_card') %>
|
6
|
+
<%= text_field_tag "#{param_prefix}[name]", "#{@order.billing_firstname} #{@order.billing_lastname}", { id: "name_on_card_#{payment_method.id}", autocomplete: "cc-name" } %>
|
7
|
+
</div>
|
8
|
+
|
9
|
+
<div class="field field-required" data-hook="card_number">
|
10
|
+
<%= label_tag "card_number", t('spree.card_number') %>
|
11
|
+
<div id="card_number"></div>
|
12
|
+
<span id="card_type" style="display:none;">
|
13
|
+
( <span id="looks_like" ><%= t('spree.card_type_is') %> <span id="type"></span></span>
|
14
|
+
<span id="unrecognized"><%= t('spree.unrecognized_card_type') %></span>
|
15
|
+
)
|
16
|
+
</span>
|
17
|
+
</div>
|
18
|
+
|
19
|
+
<div class="field field-required" data-hook="card_expiration">
|
20
|
+
<%= label_tag "card_expiry", t('spree.expiration') %>
|
21
|
+
<div id="card_expiry"></div>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<div class="field field-required" data-hook="card_code">
|
25
|
+
<%= label_tag "card_cvc", t('spree.card_code') %>
|
26
|
+
<div id="card_cvc"></div>
|
27
|
+
<%= link_to "(#{t('spree.what_is_this')})", spree.cvv_path, target: '_blank', "data-hook" => "cvv_link", id: "cvv_link" %>
|
28
|
+
</div>
|
29
|
+
|
30
|
+
<div id="card-errors" class='errorExplanation' role="alert" style="display: none"></div>
|
31
|
+
|
32
|
+
<% if @order.bill_address %>
|
33
|
+
<%= fields_for "#{param_prefix}[address_attributes]", @order.bill_address do |f| %>
|
34
|
+
<%= render partial: 'spree/address/form_hidden', locals: { form: f } %>
|
35
|
+
<% end %>
|
36
|
+
<% end %>
|
37
|
+
|
38
|
+
<%= hidden_field_tag "#{param_prefix}[cc_type]", '', id: "cc_type", class: 'ccType' %>
|
39
|
+
|
40
|
+
<script src="https://js.stripe.com/v3/"></script>
|
41
|
+
|
42
|
+
<script>
|
43
|
+
Spree.stripePaymentMethod = $('#payment_method_' + <%= payment_method.id %>);
|
44
|
+
|
45
|
+
var stripe = Stripe("<%= payment_method.preferred_publishable_key %>");
|
46
|
+
|
47
|
+
var elements = stripe.elements({locale: 'en'});
|
48
|
+
|
49
|
+
var style = {
|
50
|
+
base: {
|
51
|
+
color: 'black',
|
52
|
+
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
|
53
|
+
fontSmoothing: 'antialiased',
|
54
|
+
fontSize: '14px',
|
55
|
+
'::placeholder': {
|
56
|
+
color: 'silver'
|
57
|
+
}
|
58
|
+
},
|
59
|
+
invalid: {
|
60
|
+
color: 'red',
|
61
|
+
iconColor: 'red'
|
62
|
+
}
|
63
|
+
};
|
64
|
+
|
65
|
+
var cardNumber = elements.create('cardNumber', {style: style});
|
66
|
+
var cardExpiry = elements.create('cardExpiry', {style: style});
|
67
|
+
var cardCvc = elements.create('cardCvc', {style: style});
|
68
|
+
|
69
|
+
cardNumber.mount('#card_number');
|
70
|
+
cardExpiry.mount('#card_expiry');
|
71
|
+
cardCvc.mount('#card_cvc');
|
72
|
+
|
73
|
+
$(function() {
|
74
|
+
var form = Spree.stripePaymentMethod.parents('form');
|
75
|
+
var submitButton = form.find('input[type="submit"]');
|
76
|
+
var errorElement = form.find('#card-errors');
|
77
|
+
var cardType = form.find('input#cc_type');
|
78
|
+
|
79
|
+
cardNumber.addEventListener('change', function(event) {
|
80
|
+
if (event.error) {
|
81
|
+
errorElement.text(event.error.message).show();
|
82
|
+
} else {
|
83
|
+
errorElement.hide().text('');
|
84
|
+
}
|
85
|
+
});
|
86
|
+
|
87
|
+
form.bind('submit', function(event) {
|
88
|
+
if (Spree.stripePaymentMethod.is(':visible')) {
|
89
|
+
event.preventDefault();
|
90
|
+
|
91
|
+
stripe.createToken(cardNumber).then(function(result) {
|
92
|
+
if (result.error) {
|
93
|
+
errorElement.text(result.error.message).show();
|
94
|
+
setTimeout(function() {
|
95
|
+
$.rails.enableElement(submitButton[0]);
|
96
|
+
submitButton.removeAttr('disabled').removeClass('disabled');
|
97
|
+
}, 100);
|
98
|
+
} else {
|
99
|
+
stripeTokenHandler(result.token);
|
100
|
+
}
|
101
|
+
});
|
102
|
+
}
|
103
|
+
});
|
104
|
+
|
105
|
+
function stripeTokenHandler(token) {
|
106
|
+
var paymentMethodId = Spree.stripePaymentMethod.prop('id').split("_")[2];
|
107
|
+
var baseSelector = `<input type='hidden' class='stripeToken' name='payment_source[${paymentMethodId}]`;
|
108
|
+
|
109
|
+
Spree.stripePaymentMethod.append(`${baseSelector}[gateway_payment_profile_id]' value='${token.id}'/>`);
|
110
|
+
Spree.stripePaymentMethod.append(`${baseSelector}[last_digits]' value='${token.card.last4}'/>`);
|
111
|
+
Spree.stripePaymentMethod.append(`${baseSelector}[month]' value='${token.card.exp_month}'/>`);
|
112
|
+
Spree.stripePaymentMethod.append(`${baseSelector}[year]' value='${token.card.exp_year}'/>`);
|
113
|
+
cardType.val(mapCC(token.card.type));
|
114
|
+
form[0].submit();
|
115
|
+
};
|
116
|
+
|
117
|
+
function mapCC(ccType) {
|
118
|
+
if (ccType === 'MasterCard') {
|
119
|
+
return 'mastercard';
|
120
|
+
} else if (ccType === 'Visa') {
|
121
|
+
return 'visa';
|
122
|
+
} else if (ccType === 'American Express') {
|
123
|
+
return 'amex';
|
124
|
+
} else if (ccType === 'Discover') {
|
125
|
+
return 'discover';
|
126
|
+
} else if (ccType === 'Diners Club') {
|
127
|
+
return 'dinersclub';
|
128
|
+
} else if (ccType === 'JCB') {
|
129
|
+
return 'jcb';
|
130
|
+
}
|
131
|
+
};
|
132
|
+
})
|
133
|
+
</script>
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'solidus_stripe/version'
|
6
|
+
|
7
|
+
# encoding: UTF-8
|
8
|
+
|
9
|
+
Gem::Specification.new do |s|
|
10
|
+
s.platform = Gem::Platform::RUBY
|
11
|
+
s.name = "solidus_stripe"
|
12
|
+
s.version = SolidusStripe::VERSION
|
13
|
+
s.summary = "Stripe Payment Method for Solidus"
|
14
|
+
s.description = s.summary
|
15
|
+
s.required_ruby_version = ">= 2.2"
|
16
|
+
|
17
|
+
s.author = "Solidus Team"
|
18
|
+
s.email = "contact@solidus.io"
|
19
|
+
s.homepage = "https://solidus.io"
|
20
|
+
s.license = 'BSD-3'
|
21
|
+
|
22
|
+
s.files = `git ls-files`.split("\n")
|
23
|
+
s.test_files = `git ls-files -- spec/*`.split("\n")
|
24
|
+
s.require_path = "lib"
|
25
|
+
s.requirements << "none"
|
26
|
+
|
27
|
+
s.add_dependency "solidus_core", [">= 2.3", "< 3"]
|
28
|
+
s.add_dependency "solidus_support", ">= 0.3.1"
|
29
|
+
|
30
|
+
# ActiveMerchant v1.58 through v1.59 introduced a breaking change
|
31
|
+
# to the stripe gateway.
|
32
|
+
#
|
33
|
+
# This was resolved in v1.60, but we still need to skip 1.58 & 1.59.
|
34
|
+
s.add_dependency "activemerchant", "~> 1.48", "!= 1.58.0", "!= 1.59.0"
|
35
|
+
|
36
|
+
s.add_development_dependency "capybara"
|
37
|
+
s.add_development_dependency "capybara-screenshot"
|
38
|
+
s.add_development_dependency "database_cleaner", "~> 1.5"
|
39
|
+
s.add_development_dependency "factory_bot", "~> 4.4"
|
40
|
+
s.add_development_dependency "gem-release", "~> 2.0"
|
41
|
+
s.add_development_dependency "rspec-rails", "~> 3.2"
|
42
|
+
s.add_development_dependency 'selenium-webdriver', '~> 3.142'
|
43
|
+
s.add_development_dependency "simplecov"
|
44
|
+
s.add_development_dependency "sqlite3"
|
45
|
+
end
|
@@ -0,0 +1,279 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe "Stripe checkout", type: :feature do
|
6
|
+
let(:zone) { FactoryBot.create(:zone) }
|
7
|
+
let(:country) { FactoryBot.create(:country) }
|
8
|
+
|
9
|
+
before do
|
10
|
+
FactoryBot.create(:store)
|
11
|
+
zone.members << Spree::ZoneMember.create!(zoneable: country)
|
12
|
+
FactoryBot.create(:free_shipping_method)
|
13
|
+
|
14
|
+
Spree::PaymentMethod::StripeCreditCard.create!(
|
15
|
+
name: "Stripe",
|
16
|
+
preferred_secret_key: "sk_test_VCZnDv3GLU15TRvn8i2EsaAN",
|
17
|
+
preferred_publishable_key: "pk_test_Cuf0PNtiAkkMpTVC2gwYDMIg",
|
18
|
+
preferred_v3_elements: preferred_v3_elements
|
19
|
+
)
|
20
|
+
|
21
|
+
FactoryBot.create(:product, name: "DL-44")
|
22
|
+
|
23
|
+
visit spree.root_path
|
24
|
+
click_link "DL-44"
|
25
|
+
click_button "Add To Cart"
|
26
|
+
|
27
|
+
expect(page).to have_current_path("/cart")
|
28
|
+
click_button "Checkout"
|
29
|
+
|
30
|
+
expect(page).to have_current_path("/checkout/registration")
|
31
|
+
click_link "Create a new account"
|
32
|
+
within("#new_spree_user") do
|
33
|
+
fill_in "Email", with: "mary@example.com"
|
34
|
+
fill_in "Password", with: "superStrongPassword"
|
35
|
+
fill_in "Password Confirmation", with: "superStrongPassword"
|
36
|
+
end
|
37
|
+
click_button "Create"
|
38
|
+
|
39
|
+
# Address
|
40
|
+
expect(page).to have_current_path("/checkout/address")
|
41
|
+
|
42
|
+
within("#billing") do
|
43
|
+
fill_in "First Name", with: "Han"
|
44
|
+
fill_in "Last Name", with: "Solo"
|
45
|
+
fill_in "Street Address", with: "YT-1300"
|
46
|
+
fill_in "City", with: "Mos Eisley"
|
47
|
+
select "United States of America", from: "Country"
|
48
|
+
select country.states.first.name, from: "order_bill_address_attributes_state_id"
|
49
|
+
fill_in "Zip", with: "12010"
|
50
|
+
fill_in "Phone", with: "(555) 555-5555"
|
51
|
+
end
|
52
|
+
click_on "Save and Continue"
|
53
|
+
|
54
|
+
# Delivery
|
55
|
+
expect(page).to have_current_path("/checkout/delivery")
|
56
|
+
expect(page).to have_content("UPS Ground")
|
57
|
+
end
|
58
|
+
|
59
|
+
# This will fetch a token from Stripe.com and then pass that to the webserver.
|
60
|
+
# The server then processes the payment using that token.
|
61
|
+
|
62
|
+
context 'when using Stripe V2 API library' do
|
63
|
+
let(:preferred_v3_elements) { false }
|
64
|
+
|
65
|
+
before do
|
66
|
+
click_on "Save and Continue"
|
67
|
+
expect(page).to have_current_path("/checkout/payment")
|
68
|
+
end
|
69
|
+
|
70
|
+
it "can process a valid payment", js: true do
|
71
|
+
fill_in "Card Number", with: "4242 4242 4242 4242"
|
72
|
+
fill_in "Card Code", with: "123"
|
73
|
+
fill_in "Expiration", with: "01 / #{Time.now.year + 1}"
|
74
|
+
click_button "Save and Continue"
|
75
|
+
expect(page).to have_current_path("/checkout/confirm")
|
76
|
+
click_button "Place Order"
|
77
|
+
expect(page).to have_content("Your order has been processed successfully")
|
78
|
+
end
|
79
|
+
|
80
|
+
it "can re-use saved cards", js: true do
|
81
|
+
fill_in "Card Number", with: "4242 4242 4242 4242"
|
82
|
+
fill_in "Card Code", with: "123"
|
83
|
+
fill_in "Expiration", with: "01 / #{Time.now.year + 1}"
|
84
|
+
click_button "Save and Continue"
|
85
|
+
|
86
|
+
expect(page).to have_current_path("/checkout/confirm")
|
87
|
+
click_button "Place Order"
|
88
|
+
expect(page).to have_content("Your order has been processed successfully")
|
89
|
+
|
90
|
+
visit spree.root_path
|
91
|
+
click_link "DL-44"
|
92
|
+
click_button "Add To Cart"
|
93
|
+
|
94
|
+
expect(page).to have_current_path("/cart")
|
95
|
+
click_button "Checkout"
|
96
|
+
|
97
|
+
# Address
|
98
|
+
expect(page).to have_current_path("/checkout/address")
|
99
|
+
|
100
|
+
within("#billing") do
|
101
|
+
fill_in "First Name", with: "Han"
|
102
|
+
fill_in "Last Name", with: "Solo"
|
103
|
+
fill_in "Street Address", with: "YT-1300"
|
104
|
+
fill_in "City", with: "Mos Eisley"
|
105
|
+
select "United States of America", from: "Country"
|
106
|
+
select country.states.first.name, from: "order_bill_address_attributes_state_id"
|
107
|
+
fill_in "Zip", with: "12010"
|
108
|
+
fill_in "Phone", with: "(555) 555-5555"
|
109
|
+
end
|
110
|
+
click_on "Save and Continue"
|
111
|
+
|
112
|
+
# Delivery
|
113
|
+
expect(page).to have_current_path("/checkout/delivery")
|
114
|
+
expect(page).to have_content("UPS Ground")
|
115
|
+
click_on "Save and Continue"
|
116
|
+
|
117
|
+
# Payment
|
118
|
+
expect(page).to have_current_path("/checkout/payment")
|
119
|
+
choose "Use an existing card on file"
|
120
|
+
click_button "Save and Continue"
|
121
|
+
|
122
|
+
# Confirm
|
123
|
+
expect(page).to have_current_path("/checkout/confirm")
|
124
|
+
click_button "Place Order"
|
125
|
+
expect(page).to have_content("Your order has been processed successfully")
|
126
|
+
end
|
127
|
+
|
128
|
+
it "shows an error with a missing credit card number", js: true do
|
129
|
+
fill_in "Expiration", with: "01 / #{Time.now.year + 1}"
|
130
|
+
click_button "Save and Continue"
|
131
|
+
expect(page).to have_content("Could not find payment information")
|
132
|
+
end
|
133
|
+
|
134
|
+
it "shows an error with a missing expiration date", js: true do
|
135
|
+
fill_in "Card Number", with: "4242 4242 4242 4242"
|
136
|
+
click_button "Save and Continue"
|
137
|
+
expect(page).to have_content("Your card's expiration year is invalid.")
|
138
|
+
end
|
139
|
+
|
140
|
+
it "shows an error with an invalid credit card number", js: true do
|
141
|
+
fill_in "Card Number", with: "1111 1111 1111 1111"
|
142
|
+
fill_in "Expiration", with: "01 / #{Time.now.year + 1}"
|
143
|
+
click_button "Save and Continue"
|
144
|
+
expect(page).to have_content("Your card number is incorrect.")
|
145
|
+
end
|
146
|
+
|
147
|
+
it "shows an error with invalid security fields", js: true do
|
148
|
+
fill_in "Card Number", with: "4242 4242 4242 4242"
|
149
|
+
fill_in "Expiration", with: "01 / #{Time.now.year + 1}"
|
150
|
+
fill_in "Card Code", with: "12"
|
151
|
+
click_button "Save and Continue"
|
152
|
+
expect(page).to have_content("Your card's security code is invalid.")
|
153
|
+
end
|
154
|
+
|
155
|
+
it "shows an error with invalid expiry fields", js: true do
|
156
|
+
fill_in "Card Number", with: "4242 4242 4242 4242"
|
157
|
+
fill_in "Expiration", with: "00 / #{Time.now.year + 1}"
|
158
|
+
fill_in "Card Code", with: "123"
|
159
|
+
click_button "Save and Continue"
|
160
|
+
expect(page).to have_content("Your card's expiration month is invalid.")
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
context 'when using Stripe V3 API libarary with Elements' do
|
165
|
+
let(:preferred_v3_elements) { true }
|
166
|
+
|
167
|
+
before do
|
168
|
+
click_on "Save and Continue"
|
169
|
+
expect(page).to have_current_path("/checkout/payment")
|
170
|
+
end
|
171
|
+
|
172
|
+
it "can process a valid payment", js: true do
|
173
|
+
within_frame find('#card_number iframe') do
|
174
|
+
'4242 4242 4242 4242'.split('').each { |n| find_field('cardnumber').native.send_keys(n) }
|
175
|
+
end
|
176
|
+
within_frame(find '#card_cvc iframe') { fill_in 'cvc', with: '123' }
|
177
|
+
within_frame(find '#card_expiry iframe') { fill_in 'exp-date', with: "0132" }
|
178
|
+
click_button "Save and Continue"
|
179
|
+
expect(page).to have_current_path("/checkout/confirm")
|
180
|
+
click_button "Place Order"
|
181
|
+
expect(page).to have_content("Your order has been processed successfully")
|
182
|
+
end
|
183
|
+
|
184
|
+
it "can re-use saved cards", js: true do
|
185
|
+
within_frame find('#card_number iframe') do
|
186
|
+
'4242 4242 4242 4242'.split('').each { |n| find_field('cardnumber').native.send_keys(n) }
|
187
|
+
end
|
188
|
+
within_frame(find '#card_cvc iframe') { fill_in 'cvc', with: '123' }
|
189
|
+
within_frame(find '#card_expiry iframe') { fill_in 'exp-date', with: "0132" }
|
190
|
+
click_button "Save and Continue"
|
191
|
+
expect(page).to have_current_path("/checkout/confirm")
|
192
|
+
click_button "Place Order"
|
193
|
+
expect(page).to have_content("Your order has been processed successfully")
|
194
|
+
|
195
|
+
visit spree.root_path
|
196
|
+
click_link "DL-44"
|
197
|
+
click_button "Add To Cart"
|
198
|
+
|
199
|
+
expect(page).to have_current_path("/cart")
|
200
|
+
click_button "Checkout"
|
201
|
+
|
202
|
+
# Address
|
203
|
+
expect(page).to have_current_path("/checkout/address")
|
204
|
+
|
205
|
+
within("#billing") do
|
206
|
+
fill_in "First Name", with: "Han"
|
207
|
+
fill_in "Last Name", with: "Solo"
|
208
|
+
fill_in "Street Address", with: "YT-1300"
|
209
|
+
fill_in "City", with: "Mos Eisley"
|
210
|
+
select "United States of America", from: "Country"
|
211
|
+
select country.states.first.name, from: "order_bill_address_attributes_state_id"
|
212
|
+
fill_in "Zip", with: "12010"
|
213
|
+
fill_in "Phone", with: "(555) 555-5555"
|
214
|
+
end
|
215
|
+
click_on "Save and Continue"
|
216
|
+
|
217
|
+
# Delivery
|
218
|
+
expect(page).to have_current_path("/checkout/delivery")
|
219
|
+
expect(page).to have_content("UPS Ground")
|
220
|
+
click_on "Save and Continue"
|
221
|
+
|
222
|
+
# Payment
|
223
|
+
expect(page).to have_current_path("/checkout/payment")
|
224
|
+
choose "Use an existing card on file"
|
225
|
+
click_button "Save and Continue"
|
226
|
+
|
227
|
+
# Confirm
|
228
|
+
expect(page).to have_current_path("/checkout/confirm")
|
229
|
+
click_button "Place Order"
|
230
|
+
expect(page).to have_content("Your order has been processed successfully")
|
231
|
+
end
|
232
|
+
|
233
|
+
it "shows an error with a missing credit card number", js: true do
|
234
|
+
within_frame(find '#card_cvc iframe') { fill_in 'cvc', with: '123' }
|
235
|
+
within_frame(find '#card_expiry iframe') { fill_in 'exp-date', with: "0132" }
|
236
|
+
click_button "Save and Continue"
|
237
|
+
expect(page).to have_content("Your card number is incomplete.")
|
238
|
+
end
|
239
|
+
|
240
|
+
it "shows an error with a missing expiration date", js: true do
|
241
|
+
within_frame find('#card_number iframe') do
|
242
|
+
'4242 4242 4242 4242'.split('').each { |n| find_field('cardnumber').native.send_keys(n) }
|
243
|
+
end
|
244
|
+
within_frame(find '#card_cvc iframe') { fill_in 'cvc', with: '123' }
|
245
|
+
click_button "Save and Continue"
|
246
|
+
expect(page).to have_content("Your card's expiration date is incomplete.")
|
247
|
+
end
|
248
|
+
|
249
|
+
it "shows an error with an invalid credit card number", js: true do
|
250
|
+
within_frame find('#card_number iframe') do
|
251
|
+
'1111 1111 1111 1111'.split('').each { |n| find_field('cardnumber').native.send_keys(n) }
|
252
|
+
end
|
253
|
+
within_frame(find '#card_cvc iframe') { fill_in 'cvc', with: '123' }
|
254
|
+
within_frame(find '#card_expiry iframe') { fill_in 'exp-date', with: "0132" }
|
255
|
+
click_button "Save and Continue"
|
256
|
+
expect(page).to have_content("Your card number is invalid.")
|
257
|
+
end
|
258
|
+
|
259
|
+
it "shows an error with invalid security fields", js: true do
|
260
|
+
within_frame find('#card_number iframe') do
|
261
|
+
'4242 4242 4242 4242'.split('').each { |n| find_field('cardnumber').native.send_keys(n) }
|
262
|
+
end
|
263
|
+
within_frame(find '#card_cvc iframe') { fill_in 'cvc', with: '12' }
|
264
|
+
within_frame(find '#card_expiry iframe') { fill_in 'exp-date', with: "0132" }
|
265
|
+
click_button "Save and Continue"
|
266
|
+
expect(page).to have_content("Your card's security code is incomplete.")
|
267
|
+
end
|
268
|
+
|
269
|
+
it "shows an error with invalid expiry fields", js: true do
|
270
|
+
within_frame find('#card_number iframe') do
|
271
|
+
'4242 4242 4242 4242'.split('').each { |n| find_field('cardnumber').native.send_keys(n) }
|
272
|
+
end
|
273
|
+
within_frame(find '#card_cvc iframe') { fill_in 'cvc', with: '123' }
|
274
|
+
within_frame(find '#card_expiry iframe') { fill_in 'exp-date', with: "013" }
|
275
|
+
click_button "Save and Continue"
|
276
|
+
expect(page).to have_content("Your card's expiration date is incomplete.")
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|