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
data/README.md
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
Solidus Stripe
|
2
|
+
===============
|
3
|
+
|
4
|
+
[](https://circleci.com/gh/solidusio/solidus_stripe)
|
5
|
+
|
6
|
+
Stripe Payment Method for Solidus. It works as a wrapper for the ActiveMerchant Stripe gateway.
|
7
|
+
|
8
|
+
---
|
9
|
+
|
10
|
+
Installation
|
11
|
+
------------
|
12
|
+
|
13
|
+
In your Gemfile:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem "solidus_stripe", github: "solidusio/solidus_stripe"
|
17
|
+
```
|
18
|
+
|
19
|
+
Then run from the command line:
|
20
|
+
|
21
|
+
```shell
|
22
|
+
bundle install
|
23
|
+
bundle exec rails g solidus_stripe:install
|
24
|
+
bundle exec rails db:migrate
|
25
|
+
```
|
26
|
+
|
27
|
+
Usage
|
28
|
+
-----
|
29
|
+
|
30
|
+
Navigate to *Settings > Payments > Payment Methods* in the admin panel.
|
31
|
+
You can now create a new payment method that uses Stripe by selecting
|
32
|
+
`Stripe credit card` under Type in the New Payment Method form and saving.
|
33
|
+
The Stripe payment method's extra fields will be now shown in the form.
|
34
|
+
|
35
|
+
**Configure via database configuration**
|
36
|
+
|
37
|
+
If you want to store your Stripe credentials in the database just
|
38
|
+
fill the new fields in the form, selecting `custom` (default) in the
|
39
|
+
Preference Source field.
|
40
|
+
|
41
|
+
**Configure via static configuration**
|
42
|
+
|
43
|
+
If you want to store your credentials into your codebase or use ENV
|
44
|
+
variables you can create the following static configuration:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
# config/initializers/spree.rb
|
48
|
+
|
49
|
+
Spree.config do |config|
|
50
|
+
# ...
|
51
|
+
|
52
|
+
config.static_model_preferences.add(
|
53
|
+
Spree::PaymentMethod::StripeCreditCard,
|
54
|
+
'stripe_env_credentials',
|
55
|
+
secret_key: ENV['STRIPE_SECRET_KEY'],
|
56
|
+
publishable_key: ENV['STRIPE_PUBLISHABLE_KEY'],
|
57
|
+
v3_elements: false,
|
58
|
+
server: Rails.env.production? ? 'production' : 'test',
|
59
|
+
test_mode: !Rails.env.production?
|
60
|
+
)
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
Once your server has been restarted, you can select in the Preference
|
65
|
+
Source field a new entry called `stripe_env_credentials`. After saving,
|
66
|
+
your application will start using the static configuration to process
|
67
|
+
Stripe payments.
|
68
|
+
|
69
|
+
|
70
|
+
Migrating from solidus_gateway
|
71
|
+
------------------------------
|
72
|
+
|
73
|
+
If you were previously using `solidus_gateway` gem you might want to
|
74
|
+
check out our [Wiki page](https://github.com/solidusio/solidus_stripe/wiki/Migrating-from-solidus_gateway)
|
75
|
+
that describes how to handle this migration.
|
76
|
+
|
77
|
+
Testing
|
78
|
+
-------
|
79
|
+
|
80
|
+
Then just run the following to automatically build a dummy app if necessary and
|
81
|
+
run the tests:
|
82
|
+
|
83
|
+
```shell
|
84
|
+
bundle exec rake
|
85
|
+
```
|
86
|
+
|
87
|
+
Releasing
|
88
|
+
---------
|
89
|
+
|
90
|
+
We use [gem-release](https://github.com/svenfuchs/gem-release) to release this
|
91
|
+
extension with ease.
|
92
|
+
|
93
|
+
Supposing you are on the master branch and you are working on a fork of this
|
94
|
+
extension, `upstream` is the main remote and you have write access to it, you
|
95
|
+
can simply run:
|
96
|
+
|
97
|
+
```
|
98
|
+
gem bump --version minor --tag --release --remote upstream
|
99
|
+
```
|
100
|
+
|
101
|
+
This command will:
|
102
|
+
|
103
|
+
- bump the gem version to the next minor (changing the `version.rb` file)
|
104
|
+
- commit the change and push it to upstream master
|
105
|
+
- create a git tag
|
106
|
+
- push the tag to the upstream remote
|
107
|
+
- release the new version on RubyGems
|
108
|
+
|
109
|
+
Or you can run these commands individually:
|
110
|
+
|
111
|
+
```
|
112
|
+
gem bump --version minor --remote upstream
|
113
|
+
gem tag --remote upstream
|
114
|
+
gem release
|
115
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler'
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
require 'spree/testing_support/common_rake'
|
8
|
+
|
9
|
+
RSpec::Core::RakeTask.new
|
10
|
+
|
11
|
+
task :default do
|
12
|
+
if Dir["spec/dummy"].empty?
|
13
|
+
Rake::Task[:test_app].invoke
|
14
|
+
Dir.chdir("../../")
|
15
|
+
end
|
16
|
+
Rake::Task[:spec].invoke
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Generates a dummy app for testing"
|
20
|
+
task :test_app do
|
21
|
+
ENV['LIB_NAME'] = 'solidus_stripe'
|
22
|
+
Rake::Task['common:test_app'].invoke
|
23
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spree
|
4
|
+
class PaymentMethod
|
5
|
+
class StripeCreditCard < Spree::PaymentMethod::CreditCard
|
6
|
+
preference :secret_key, :string
|
7
|
+
preference :publishable_key, :string
|
8
|
+
preference :v3_elements, :boolean
|
9
|
+
|
10
|
+
CARD_TYPE_MAPPING = {
|
11
|
+
'American Express' => 'american_express',
|
12
|
+
'Diners Club' => 'diners_club',
|
13
|
+
'Visa' => 'visa'
|
14
|
+
}
|
15
|
+
|
16
|
+
def partial_name
|
17
|
+
'stripe'
|
18
|
+
end
|
19
|
+
|
20
|
+
def v3_elements?
|
21
|
+
!!preferred_v3_elements
|
22
|
+
end
|
23
|
+
|
24
|
+
def gateway_class
|
25
|
+
ActiveMerchant::Billing::StripeGateway
|
26
|
+
end
|
27
|
+
|
28
|
+
def payment_profiles_supported?
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
def purchase(money, creditcard, transaction_options)
|
33
|
+
gateway.purchase(*options_for_purchase_or_auth(money, creditcard, transaction_options))
|
34
|
+
end
|
35
|
+
|
36
|
+
def authorize(money, creditcard, transaction_options)
|
37
|
+
gateway.authorize(*options_for_purchase_or_auth(money, creditcard, transaction_options))
|
38
|
+
end
|
39
|
+
|
40
|
+
def capture(money, response_code, transaction_options)
|
41
|
+
gateway.capture(money, response_code, transaction_options)
|
42
|
+
end
|
43
|
+
|
44
|
+
def credit(money, _creditcard, response_code, _transaction_options)
|
45
|
+
gateway.refund(money, response_code, {})
|
46
|
+
end
|
47
|
+
|
48
|
+
def void(response_code, _creditcard, _transaction_options)
|
49
|
+
gateway.void(response_code, {})
|
50
|
+
end
|
51
|
+
|
52
|
+
def cancel(response_code)
|
53
|
+
gateway.void(response_code, {})
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_profile(payment)
|
57
|
+
return unless payment.source.gateway_customer_profile_id.nil?
|
58
|
+
|
59
|
+
options = {
|
60
|
+
email: payment.order.email,
|
61
|
+
login: preferred_secret_key,
|
62
|
+
}.merge! address_for(payment)
|
63
|
+
|
64
|
+
source = update_source!(payment.source)
|
65
|
+
if source.number.blank? && source.gateway_payment_profile_id.present?
|
66
|
+
creditcard = source.gateway_payment_profile_id
|
67
|
+
else
|
68
|
+
creditcard = source
|
69
|
+
end
|
70
|
+
|
71
|
+
response = gateway.store(creditcard, options)
|
72
|
+
if response.success?
|
73
|
+
payment.source.update_attributes!({
|
74
|
+
cc_type: payment.source.cc_type, # side-effect of update_source!
|
75
|
+
gateway_customer_profile_id: response.params['id'],
|
76
|
+
gateway_payment_profile_id: response.params['default_source'] || response.params['default_card']
|
77
|
+
})
|
78
|
+
|
79
|
+
else
|
80
|
+
payment.send(:gateway_error, response.message)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
# In this gateway, what we call 'secret_key' is the 'login'
|
87
|
+
def options
|
88
|
+
options = super
|
89
|
+
options.merge(login: preferred_secret_key)
|
90
|
+
end
|
91
|
+
|
92
|
+
def options_for_purchase_or_auth(money, creditcard, transaction_options)
|
93
|
+
options = {}
|
94
|
+
options[:description] = "Spree Order ID: #{transaction_options[:order_id]}"
|
95
|
+
options[:currency] = transaction_options[:currency]
|
96
|
+
|
97
|
+
if customer = creditcard.gateway_customer_profile_id
|
98
|
+
options[:customer] = customer
|
99
|
+
end
|
100
|
+
if token_or_card_id = creditcard.gateway_payment_profile_id
|
101
|
+
# The Stripe ActiveMerchant gateway supports passing the token directly as the creditcard parameter
|
102
|
+
# The Stripe ActiveMerchant gateway supports passing the customer_id and credit_card id
|
103
|
+
# https://github.com/Shopify/active_merchant/issues/770
|
104
|
+
creditcard = token_or_card_id
|
105
|
+
end
|
106
|
+
[money, creditcard, options]
|
107
|
+
end
|
108
|
+
|
109
|
+
def address_for(payment)
|
110
|
+
{}.tap do |options|
|
111
|
+
if address = payment.order.bill_address
|
112
|
+
options[:address] = {
|
113
|
+
address1: address.address1,
|
114
|
+
address2: address.address2,
|
115
|
+
city: address.city,
|
116
|
+
zip: address.zipcode
|
117
|
+
}
|
118
|
+
|
119
|
+
if country = address.country
|
120
|
+
options[:address][:country] = country.name
|
121
|
+
end
|
122
|
+
|
123
|
+
if state = address.state
|
124
|
+
options[:address].merge!(state: state.name)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def update_source!(source)
|
131
|
+
source.cc_type = CARD_TYPE_MAPPING[source.cc_type] if CARD_TYPE_MAPPING.include?(source.cc_type)
|
132
|
+
source
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
data/bin/rails
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class UpdateStripePaymentMethodTypeToCreditCard < SolidusSupport::Migration[5.1]
|
4
|
+
def up
|
5
|
+
Spree::PaymentMethod.where(type: 'Spree::Gateway::StripeGateway').update_all(type: 'Spree::PaymentMethod::StripeCreditCard')
|
6
|
+
|
7
|
+
Spree::Preference.where("#{ActiveRecord::Base.connection.quote_column_name('key')} LIKE 'spree/gateway/stripe_gateway'").each do |pref|
|
8
|
+
pref.key = pref.key.gsub('spree/gateway/stripe_gateway', 'spree/payment_method/stripe_credit_card')
|
9
|
+
pref.save
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def down
|
14
|
+
Spree::PaymentMethod.where(type: 'Spree::PaymentMethod::StripeCreditCard').update_all(type: 'Spree::Gateway::StripeGateway')
|
15
|
+
|
16
|
+
Spree::Preference.where("#{ActiveRecord::Base.connection.quote_column_name('key')} LIKE 'spree/payment_method/stripe_credit_card'").each do |pref|
|
17
|
+
pref.key = pref.key.gsub('spree/payment_method/stripe_credit_card', 'spree/gateway/stripe_gateway')
|
18
|
+
pref.save
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/db/seeds.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
secret_key = ENV['STRIPE_SEEDS_SECRET_KEY']
|
4
|
+
publishable_key = ENV['STRIPE_SEEDS_PUBLISHABLE_KEY']
|
5
|
+
|
6
|
+
puts "Loading seed: solidus_stripe/stripe_payment_method"
|
7
|
+
|
8
|
+
if secret_key.blank? || publishable_key.blank?
|
9
|
+
puts "Failure: You have to set both STRIPE_SEEDS_SECRET_KEY and STRIPE_SEEDS_PUBLISHABLE_KEY environment variables."
|
10
|
+
else
|
11
|
+
stripe_payment_method = Spree::PaymentMethod::StripeCreditCard.new do |payment_method|
|
12
|
+
payment_method.name = 'Credit Card'
|
13
|
+
payment_method.preferred_test_mode = true
|
14
|
+
payment_method.preferred_secret_key = secret_key
|
15
|
+
payment_method.preferred_publishable_key = publishable_key
|
16
|
+
end
|
17
|
+
|
18
|
+
if stripe_payment_method.save
|
19
|
+
puts "Stripe Payment Method correctly created."
|
20
|
+
else
|
21
|
+
puts "There was some problems with creating Stripe Payment Method:"
|
22
|
+
stripe_payment_method.errors.full_messages.each do |error|
|
23
|
+
puts error
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SolidusStripe
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
6
|
+
class_option :migrate, type: :boolean, default: true
|
7
|
+
class_option :auto_run_migrations, type: :boolean, default: false
|
8
|
+
class_option :auto_run_seeds, type: :boolean, default: false
|
9
|
+
|
10
|
+
def add_stylesheets
|
11
|
+
filename = 'vendor/assets/stylesheets/spree/frontend/all.css'
|
12
|
+
if File.file? filename
|
13
|
+
inject_into_file filename, " *= require spree/frontend/solidus_stripe\n", before: '*/', verbose: true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_migrations
|
18
|
+
run 'bundle exec rake railties:install:migrations FROM=solidus_stripe'
|
19
|
+
end
|
20
|
+
|
21
|
+
def run_migrations
|
22
|
+
if options.migrate? && running_migrations?
|
23
|
+
run 'bundle exec rake db:migrate'
|
24
|
+
else
|
25
|
+
puts "Skiping rake db:migrate, don't forget to run it!"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def populate_seed_data
|
30
|
+
return unless options.auto_run_seeds?
|
31
|
+
|
32
|
+
say_status :loading, 'stripe seed data'
|
33
|
+
rake('db:seed:solidus_stripe')
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def running_migrations?
|
39
|
+
options.auto_run_migrations? || begin
|
40
|
+
response = ask 'Would you like to run the migrations now? [Y/n]'
|
41
|
+
['', 'y'].include? response.downcase
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SolidusStripe
|
4
|
+
class Engine < Rails::Engine
|
5
|
+
engine_name 'solidus_stripe'
|
6
|
+
|
7
|
+
initializer "spree.payment_method.add_stripe_credit_card", after: "spree.register.payment_methods" do |app|
|
8
|
+
app.config.spree.payment_methods << Spree::PaymentMethod::StripeCreditCard
|
9
|
+
end
|
10
|
+
|
11
|
+
if SolidusSupport.backend_available?
|
12
|
+
paths["app/views"] << "lib/views/backend"
|
13
|
+
end
|
14
|
+
|
15
|
+
if SolidusSupport.frontend_available?
|
16
|
+
paths["app/views"] << "lib/views/frontend"
|
17
|
+
end
|
18
|
+
|
19
|
+
if SolidusSupport.api_available?
|
20
|
+
paths["app/views"] << "lib/views/api"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
namespace :db do
|
4
|
+
namespace :seed do
|
5
|
+
desc 'Loads stripe sample data'
|
6
|
+
task solidus_stripe: :environment do
|
7
|
+
seed_file = Dir[SolidusStripe::Engine.root.join('db', 'seeds.rb')][0]
|
8
|
+
return unless File.exist?(seed_file)
|
9
|
+
|
10
|
+
puts "Seeding #{seed_file}..."
|
11
|
+
load(seed_file)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|