solidus_paypal_braintree 0.2.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.circleci/config.yml +40 -0
- data/.gem_release.yml +5 -0
- data/.github/stale.yml +17 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.rubocop.yml +76 -0
- data/CHANGELOG.md +258 -0
- data/Gemfile +41 -0
- data/LICENSE +2 -2
- data/README.md +208 -48
- data/Rakefile +4 -28
- data/app/assets/config/solidus_paypal_braintree_manifest.js +1 -0
- data/app/assets/images/solidus_paypal_braintree/venmo/venmo_active_blue_button_280x48.svg +19 -0
- data/app/assets/images/solidus_paypal_braintree/venmo/venmo_active_blue_button_320x48.svg +19 -0
- data/app/assets/images/solidus_paypal_braintree/venmo/venmo_active_blue_button_375x48.svg +19 -0
- data/app/assets/images/solidus_paypal_braintree/venmo/venmo_active_white_button_280x48.svg +19 -0
- data/app/assets/images/solidus_paypal_braintree/venmo/venmo_active_white_button_320x48.svg +19 -0
- data/app/assets/images/solidus_paypal_braintree/venmo/venmo_active_white_button_375x48.svg +19 -0
- data/app/assets/images/solidus_paypal_braintree/venmo/venmo_blue_acceptance_mark.svg +15 -0
- data/app/assets/images/solidus_paypal_braintree/venmo/venmo_blue_button_280x48.svg +19 -0
- data/app/assets/images/solidus_paypal_braintree/venmo/venmo_blue_button_320x48.svg +19 -0
- data/app/assets/images/solidus_paypal_braintree/venmo/venmo_blue_button_375x48.svg +19 -0
- data/app/assets/images/solidus_paypal_braintree/venmo/venmo_blue_logo.svg +18 -0
- data/app/assets/images/solidus_paypal_braintree/venmo/venmo_white_acceptance_mark.svg +20 -0
- data/app/assets/images/solidus_paypal_braintree/venmo/venmo_white_button_280x48.svg +19 -0
- data/app/assets/images/solidus_paypal_braintree/venmo/venmo_white_button_320x48.svg +19 -0
- data/app/assets/images/solidus_paypal_braintree/venmo/venmo_white_button_375x48.svg +19 -0
- data/app/assets/images/solidus_paypal_braintree/venmo/venmo_white_logo.svg +18 -0
- data/app/assets/javascripts/solidus_paypal_braintree/checkout.js +32 -3
- data/app/assets/javascripts/solidus_paypal_braintree/client.js +58 -5
- data/app/assets/javascripts/solidus_paypal_braintree/constants.js +36 -5
- data/app/assets/javascripts/solidus_paypal_braintree/frontend.js +2 -0
- data/app/assets/javascripts/solidus_paypal_braintree/hosted_form.js +15 -5
- data/app/assets/javascripts/solidus_paypal_braintree/paypal_button.js +90 -26
- data/app/assets/javascripts/solidus_paypal_braintree/paypal_messaging.js +22 -0
- data/app/assets/javascripts/solidus_paypal_braintree/venmo_button.js +86 -0
- data/app/assets/javascripts/spree/backend/solidus_paypal_braintree.js +2 -2
- data/app/assets/javascripts/spree/frontend/paypal_button.js +15 -13
- data/app/assets/stylesheets/spree/frontend/solidus_paypal_braintree.css +12 -0
- data/app/decorators/controllers/solidus_paypal_braintree/admin_payments_controller_decorator.rb +11 -0
- data/app/decorators/controllers/solidus_paypal_braintree/checkout_controller_decorator.rb +11 -0
- data/app/decorators/controllers/solidus_paypal_braintree/client_tokens_controller.rb +41 -0
- data/app/decorators/controllers/solidus_paypal_braintree/orders_controller_decorator.rb +11 -0
- data/app/decorators/models/solidus_paypal_braintree/spree/store_decorator.rb +20 -0
- data/app/decorators/models/solidus_paypal_braintree/spree/user_decorator.rb +13 -0
- data/app/helpers/solidus_paypal_braintree/braintree_admin_helper.rb +23 -0
- data/app/helpers/solidus_paypal_braintree/braintree_checkout_helper.rb +60 -0
- data/app/models/application_record.rb +2 -0
- data/app/models/solidus_paypal_braintree/address.rb +64 -0
- data/app/models/solidus_paypal_braintree/avs_result.rb +69 -0
- data/app/models/solidus_paypal_braintree/configuration.rb +39 -3
- data/app/models/solidus_paypal_braintree/customer.rb +7 -3
- data/app/models/solidus_paypal_braintree/gateway.rb +150 -43
- data/app/models/solidus_paypal_braintree/response.rb +49 -21
- data/app/models/solidus_paypal_braintree/source.rb +70 -10
- data/app/models/solidus_paypal_braintree/transaction.rb +3 -2
- data/app/models/solidus_paypal_braintree/transaction_address.rb +36 -15
- data/app/models/solidus_paypal_braintree/transaction_import.rb +18 -12
- data/app/overrides/spree/payments/payment/add_paypal_funding_source_to_payment.rb +9 -0
- data/app/views/spree/api/payments/source_views/_paypal_braintree.json.jbuilder +3 -0
- data/app/views/spree/checkout/existing_payment/_paypal_braintree.html.erb +10 -0
- data/app/views/spree/shared/_apple_pay_button.html.erb +27 -0
- data/app/views/spree/shared/_braintree_errors.html.erb +16 -0
- data/app/views/spree/shared/_braintree_hosted_fields.html.erb +25 -8
- data/app/views/spree/shared/_paypal_braintree_head_scripts.html.erb +26 -0
- data/app/views/spree/shared/_paypal_cart_button.html.erb +38 -0
- data/app/views/spree/shared/_paypal_messaging.html.erb +13 -0
- data/app/views/spree/shared/_venmo_button.html.erb +33 -0
- data/bin/console +17 -0
- data/bin/rails +15 -0
- data/bin/setup +8 -0
- data/config/locales/en.yml +66 -0
- data/config/locales/it.yml +56 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20160906201711_create_solidus_paypal_braintree_customers.rb +3 -1
- data/db/migrate/20161125172005_add_braintree_configuration_to_stores.rb +5 -7
- data/db/migrate/20170505193712_add_null_constraint_to_sources.rb +3 -1
- data/db/migrate/20190705115327_add_paypal_button_preferences_to_braintree_configurations.rb +5 -0
- data/db/migrate/20190911141712_add_3d_secure_to_braintree_configuration.rb +5 -0
- data/db/migrate/20211222170950_add_paypal_funding_source_to_solidus_paypal_braintree_sources.rb +5 -0
- data/db/migrate/20220104150301_add_venmo_to_braintree_configuration.rb +5 -0
- data/lib/controllers/backend/solidus_paypal_braintree/configurations_controller.rb +23 -5
- data/lib/controllers/frontend/solidus_paypal_braintree/checkouts_controller.rb +25 -21
- data/lib/controllers/frontend/solidus_paypal_braintree/transactions_controller.rb +56 -50
- data/lib/generators/solidus_paypal_braintree/install/install_generator.rb +7 -6
- data/lib/solidus_paypal_braintree/country_mapper.rb +4 -2
- data/lib/solidus_paypal_braintree/engine.rb +34 -22
- data/lib/solidus_paypal_braintree/factories.rb +41 -6
- data/lib/solidus_paypal_braintree/request_protection.rb +21 -0
- data/lib/solidus_paypal_braintree/version.rb +3 -1
- data/lib/solidus_paypal_braintree.rb +5 -1
- data/lib/views/backend/solidus_paypal_braintree/configurations/list.html.erb +38 -5
- data/lib/views/backend/spree/admin/payments/source_forms/_paypal_braintree.html.erb +2 -2
- data/lib/views/backend/spree/admin/payments/source_views/_paypal_braintree.html.erb +7 -2
- data/lib/views/backend/spree/admin/shared/preference_fields/_preference_select.html.erb +13 -0
- data/lib/views/backend_v1.2/spree/admin/payments/source_forms/_paypal_braintree.html.erb +2 -2
- data/lib/views/backend_v2.4/spree/admin/shared/preference_fields/_hash.html.erb +12 -0
- data/lib/views/frontend/solidus_paypal_braintree/payments/_payment.html.erb +12 -0
- data/lib/views/frontend/spree/checkout/payment/_paypal_braintree.html.erb +10 -77
- data/lib/views/frontend/spree/shared/_paypal_checkout_button.html.erb +32 -0
- data/solidus_paypal_braintree.gemspec +43 -0
- data/spec/controllers/solidus_paypal_braintree/checkouts_controller_spec.rb +99 -0
- data/spec/controllers/solidus_paypal_braintree/client_tokens_controller_spec.rb +55 -0
- data/spec/controllers/solidus_paypal_braintree/configurations_controller_spec.rb +73 -0
- data/spec/controllers/solidus_paypal_braintree/transactions_controller_spec.rb +183 -0
- data/spec/features/backend/configuration_spec.rb +23 -0
- data/spec/features/backend/new_payment_spec.rb +137 -0
- data/spec/features/frontend/braintree_credit_card_checkout_spec.rb +191 -0
- data/spec/features/frontend/paypal_checkout_spec.rb +166 -0
- data/spec/features/frontend/venmo_checkout_spec.rb +189 -0
- data/spec/fixtures/cassettes/admin/invalid_credit_card.yml +63 -0
- data/spec/fixtures/cassettes/admin/resubmit_credit_card.yml +352 -0
- data/spec/fixtures/cassettes/admin/valid_credit_card.yml +412 -0
- data/spec/fixtures/cassettes/braintree/create_profile.yml +71 -0
- data/spec/fixtures/cassettes/braintree/generate_token.yml +63 -0
- data/spec/fixtures/cassettes/braintree/token.yml +63 -0
- data/spec/fixtures/cassettes/checkout/invalid_credit_card.yml +63 -0
- data/spec/fixtures/cassettes/checkout/resubmit_credit_card.yml +216 -0
- data/spec/fixtures/cassettes/checkout/update.yml +71 -0
- data/spec/fixtures/cassettes/checkout/valid_credit_card.yml +156 -0
- data/spec/fixtures/cassettes/checkout/valid_venmo_transaction.yml +599 -0
- data/spec/fixtures/cassettes/gateway/authorize/credit_card/address.yml +86 -0
- data/spec/fixtures/cassettes/gateway/authorize/merchant_account/EUR.yml +154 -0
- data/spec/fixtures/cassettes/gateway/authorize/paypal/EUR.yml +90 -0
- data/spec/fixtures/cassettes/gateway/authorize/paypal/address.yml +90 -0
- data/spec/fixtures/cassettes/gateway/authorize.yml +86 -0
- data/spec/fixtures/cassettes/gateway/authorized_transaction.yml +73 -0
- data/spec/fixtures/cassettes/gateway/cancel/missing.yml +63 -0
- data/spec/fixtures/cassettes/gateway/cancel/refunds.yml +272 -0
- data/spec/fixtures/cassettes/gateway/cancel/void.yml +201 -0
- data/spec/fixtures/cassettes/gateway/capture.yml +141 -0
- data/spec/fixtures/cassettes/gateway/complete.yml +157 -0
- data/spec/fixtures/cassettes/gateway/credit.yml +208 -0
- data/spec/fixtures/cassettes/gateway/purchase.yml +87 -0
- data/spec/fixtures/cassettes/gateway/settled_transaction.yml +140 -0
- data/spec/fixtures/cassettes/gateway/void.yml +137 -0
- data/spec/fixtures/cassettes/source/card_type.yml +267 -0
- data/spec/fixtures/cassettes/source/last4.yml +267 -0
- data/spec/fixtures/cassettes/transaction/import/valid/capture.yml +224 -0
- data/spec/fixtures/cassettes/transaction/import/valid.yml +71 -0
- data/spec/fixtures/views/spree/orders/edit.html.erb +50 -0
- data/spec/helpers/solidus_paypal_braintree/braintree_admin_helper_spec.rb +17 -0
- data/spec/helpers/solidus_paypal_braintree/braintree_checkout_helper_spec.rb +70 -0
- data/spec/models/solidus_paypal_braintree/address_spec.rb +71 -0
- data/spec/models/solidus_paypal_braintree/avs_result_spec.rb +317 -0
- data/spec/models/solidus_paypal_braintree/gateway_spec.rb +692 -0
- data/spec/models/solidus_paypal_braintree/response_spec.rb +280 -0
- data/spec/models/solidus_paypal_braintree/source_spec.rb +499 -0
- data/spec/models/solidus_paypal_braintree/transaction_address_spec.rb +235 -0
- data/spec/models/solidus_paypal_braintree/transaction_import_spec.rb +300 -0
- data/spec/models/solidus_paypal_braintree/transaction_spec.rb +85 -0
- data/spec/models/spree/store_spec.rb +14 -0
- data/spec/requests/spree/api/orders_controller_spec.rb +36 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/support/capybara.rb +7 -0
- data/spec/support/factories.rb +2 -0
- data/spec/support/gateway_helpers.rb +29 -0
- data/spec/support/order_ready_for_payment.rb +37 -0
- data/spec/support/vcr.rb +42 -0
- data/spec/support/views.rb +1 -0
- metadata +226 -166
- data/app/controllers/solidus_paypal_braintree/client_tokens_controller.rb +0 -21
- data/app/helpers/braintree_admin_helper.rb +0 -18
- data/app/models/spree/store_decorator.rb +0 -11
- data/app/overrides/admin_navigation_menu.rb +0 -6
- data/config/initializers/braintree.rb +0 -1
- data/lib/views/backend/solidus_paypal_braintree/configurations/_admin_tab.html.erb +0 -3
@@ -15,7 +15,9 @@ class AddNullConstraintToSources < SolidusSupport::Migration[4.2]
|
|
15
15
|
|
16
16
|
Spree::Payment.joins(join_sources).find_each do |payment|
|
17
17
|
Rails.logger.info("Updating source #{payment.source_id} with payment method id #{payment.payment_method_id}")
|
18
|
-
SolidusPaypalBraintree::Source.where(id: payment.source_id).update_all(
|
18
|
+
SolidusPaypalBraintree::Source.where(id: payment.source_id).update_all(
|
19
|
+
payment_method_id: payment.payment_method_id
|
20
|
+
)
|
19
21
|
end
|
20
22
|
|
21
23
|
# We use a foreign key constraint on the model,
|
@@ -1,18 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SolidusPaypalBraintree
|
2
|
-
class ConfigurationsController < Spree::Admin::BaseController
|
3
|
-
helper Spree::Core::Engine.routes.url_helpers
|
4
|
+
class ConfigurationsController < ::Spree::Admin::BaseController
|
5
|
+
helper ::Spree::Core::Engine.routes.url_helpers
|
4
6
|
|
5
7
|
def list
|
6
8
|
authorize! :list, SolidusPaypalBraintree::Configuration
|
7
9
|
|
8
|
-
@configurations = Spree::Store.all.map
|
10
|
+
@configurations = ::Spree::Store.all.map { |s| s.braintree_configuration || s.create_braintree_configuration }
|
9
11
|
end
|
10
12
|
|
11
13
|
def update
|
12
14
|
authorize! :update, SolidusPaypalBraintree::Configuration
|
13
15
|
|
14
16
|
params = configurations_params[:configuration_fields]
|
15
|
-
|
17
|
+
results = SolidusPaypalBraintree::Configuration.update(params.keys, params.values)
|
18
|
+
if results.all?(&:valid?)
|
16
19
|
flash[:success] = t('update_success', scope: 'solidus_paypal_braintree.configurations')
|
17
20
|
else
|
18
21
|
flash[:error] = t('update_error', scope: 'solidus_paypal_braintree.configurations')
|
@@ -24,7 +27,22 @@ module SolidusPaypalBraintree
|
|
24
27
|
|
25
28
|
def configurations_params
|
26
29
|
params.require(:configurations).
|
27
|
-
permit(configuration_fields: [
|
30
|
+
permit(configuration_fields: [
|
31
|
+
:paypal,
|
32
|
+
:apple_pay,
|
33
|
+
:venmo,
|
34
|
+
:credit_card,
|
35
|
+
:three_d_secure,
|
36
|
+
:preferred_paypal_button_locale,
|
37
|
+
:preferred_paypal_button_color,
|
38
|
+
:preferred_paypal_button_shape,
|
39
|
+
:preferred_paypal_button_label,
|
40
|
+
:preferred_paypal_button_tagline,
|
41
|
+
:preferred_paypal_button_layout,
|
42
|
+
:preferred_paypal_button_messaging,
|
43
|
+
:preferred_venmo_button_color,
|
44
|
+
:preferred_venmo_button_width
|
45
|
+
])
|
28
46
|
end
|
29
47
|
end
|
30
48
|
end
|
@@ -1,27 +1,31 @@
|
|
1
|
-
|
2
|
-
PERMITTED_PAYMENT_PARAMS = [
|
3
|
-
:payment_method_id,
|
4
|
-
source_attributes: [
|
5
|
-
:nonce,
|
6
|
-
:payment_type
|
7
|
-
]
|
8
|
-
].freeze
|
1
|
+
# frozen_string_literal: true
|
9
2
|
|
10
|
-
|
11
|
-
|
3
|
+
module SolidusPaypalBraintree
|
4
|
+
class CheckoutsController < ::Spree::CheckoutController
|
5
|
+
PERMITTED_PAYMENT_PARAMS = [
|
6
|
+
:payment_method_id,
|
7
|
+
{ source_attributes: [
|
8
|
+
:nonce,
|
9
|
+
:payment_type
|
10
|
+
] }
|
11
|
+
].freeze
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
def update
|
14
|
+
@payment = ::Spree::PaymentCreate.new(@order, payment_params).build
|
15
|
+
|
16
|
+
if @payment.save
|
17
|
+
render plain: "ok"
|
18
|
+
else
|
19
|
+
render plain: "not-ok"
|
20
|
+
end
|
17
21
|
end
|
18
|
-
end
|
19
22
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
def payment_params
|
24
|
+
params.
|
25
|
+
require(:order).
|
26
|
+
require(:payments_attributes).
|
27
|
+
first.
|
28
|
+
permit(PERMITTED_PAYMENT_PARAMS)
|
29
|
+
end
|
26
30
|
end
|
27
31
|
end
|
@@ -1,61 +1,67 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
:
|
11
|
-
:
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SolidusPaypalBraintree
|
4
|
+
class TransactionsController < ::Spree::StoreController
|
5
|
+
class InvalidImportError < StandardError; end
|
6
|
+
|
7
|
+
PERMITTED_BRAINTREE_TRANSACTION_PARAMS = [
|
8
|
+
:nonce,
|
9
|
+
:payment_type,
|
10
|
+
:paypal_funding_source,
|
11
|
+
:phone,
|
12
|
+
:email,
|
13
|
+
{ address_attributes: [
|
14
|
+
:country_code, :country_name, :name, :city, :zip, :state_code,
|
15
|
+
:address_line_1, :address_line_2, :first_name, :last_name
|
16
|
+
] }
|
17
|
+
].freeze
|
18
|
+
|
19
|
+
def create
|
20
|
+
transaction = SolidusPaypalBraintree::Transaction.new transaction_params
|
21
|
+
import = SolidusPaypalBraintree::TransactionImport.new(current_order, transaction)
|
22
|
+
restart_checkout = params[:options] && params[:options][:restart_checkout] == "true"
|
23
|
+
|
24
|
+
respond_to do |format|
|
25
|
+
if import.valid?
|
26
|
+
import.import!(import_state, restart_checkout: restart_checkout)
|
27
|
+
|
28
|
+
format.html { redirect_to redirect_url(import) }
|
29
|
+
format.json { render json: { redirectUrl: redirect_url(import) } }
|
30
|
+
else
|
31
|
+
status = 422
|
32
|
+
format.html { import_error(import) }
|
33
|
+
format.json { render json: { errors: import.errors, status: status }, status: status }
|
34
|
+
end
|
29
35
|
end
|
30
36
|
end
|
31
|
-
end
|
32
37
|
|
33
|
-
|
38
|
+
private
|
34
39
|
|
35
|
-
|
36
|
-
|
37
|
-
|
40
|
+
def import_state
|
41
|
+
params[:state] || 'confirm'
|
42
|
+
end
|
38
43
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
44
|
+
def import_error(import)
|
45
|
+
raise InvalidImportError,
|
46
|
+
"Import invalid: #{import.errors.full_messages.join(', ')}"
|
47
|
+
end
|
43
48
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
+
def redirect_url(import)
|
50
|
+
if import.order.complete?
|
51
|
+
spree.order_url(import.order)
|
52
|
+
else
|
53
|
+
spree.checkout_state_url(import.order.state)
|
54
|
+
end
|
49
55
|
end
|
50
|
-
end
|
51
56
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
+
def transaction_params
|
58
|
+
params.require(:transaction)
|
59
|
+
.permit(PERMITTED_BRAINTREE_TRANSACTION_PARAMS)
|
60
|
+
.merge({ payment_method: payment_method })
|
61
|
+
end
|
57
62
|
|
58
|
-
|
59
|
-
|
63
|
+
def payment_method
|
64
|
+
SolidusPaypalBraintree::Gateway.find(params[:payment_method_id])
|
65
|
+
end
|
60
66
|
end
|
61
67
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SolidusPaypalBraintree
|
2
4
|
module Generators
|
3
5
|
class InstallGenerator < Rails::Generators::Base
|
@@ -5,13 +7,12 @@ module SolidusPaypalBraintree
|
|
5
7
|
|
6
8
|
def add_javascripts
|
7
9
|
append_file 'vendor/assets/javascripts/spree/frontend/all.js', "//= require solidus_paypal_braintree/frontend\n"
|
8
|
-
append_file 'vendor/assets/javascripts/spree/
|
9
|
-
append_file 'vendor/assets/javascripts/spree/backend/all.js', "//= require spree/backend/solidus_paypal_braintree\n"
|
10
|
+
append_file 'vendor/assets/javascripts/spree/backend/all.js', "//= require spree/backend/solidus_paypal_braintree\n" # rubocop:disable Layout/LineLength
|
10
11
|
end
|
11
12
|
|
12
13
|
def add_stylesheets
|
13
|
-
inject_into_file 'vendor/assets/stylesheets/spree/frontend/all.css', " *= require spree/frontend/solidus_paypal_braintree\n", before:
|
14
|
-
inject_into_file 'vendor/assets/stylesheets/spree/backend/all.css', " *= require spree/backend/solidus_paypal_braintree\n", before:
|
14
|
+
inject_into_file 'vendor/assets/stylesheets/spree/frontend/all.css', " *= require spree/frontend/solidus_paypal_braintree\n", before: %r{\*/}, verbose: true # rubocop:disable Layout/LineLength
|
15
|
+
inject_into_file 'vendor/assets/stylesheets/spree/backend/all.css', " *= require spree/backend/solidus_paypal_braintree\n", before: %r{\*/}, verbose: true # rubocop:disable Layout/LineLength
|
15
16
|
end
|
16
17
|
|
17
18
|
def add_migrations
|
@@ -25,11 +26,11 @@ module SolidusPaypalBraintree
|
|
25
26
|
end
|
26
27
|
|
27
28
|
def run_migrations
|
28
|
-
run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask('Would you like to run the migrations now? [Y/n]'))
|
29
|
+
run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask('Would you like to run the migrations now? [Y/n]')) # rubocop:disable Layout/LineLength
|
29
30
|
if run_migrations
|
30
31
|
run 'bundle exec rake db:migrate'
|
31
32
|
else
|
32
|
-
|
33
|
+
say_status :skipping, 'rake db:migrate, don\'t forget to run it!'
|
33
34
|
end
|
34
35
|
end
|
35
36
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SolidusPaypalBraintree
|
2
4
|
module CountryMapper
|
3
5
|
extend ActiveSupport::Concern
|
@@ -12,12 +14,12 @@ module SolidusPaypalBraintree
|
|
12
14
|
"usa",
|
13
15
|
"u.s.",
|
14
16
|
"us"
|
15
|
-
]
|
17
|
+
].freeze
|
16
18
|
|
17
19
|
CANADA_VARIANTS = [
|
18
20
|
"canada",
|
19
21
|
"ca"
|
20
|
-
]
|
22
|
+
].freeze
|
21
23
|
|
22
24
|
# Generates a hash mapping each variant of the country name to the same ISO
|
23
25
|
# ie: { "usa" => "US", "united states" => "US", "canada" => "CA", ... }
|
@@ -1,8 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'solidus_support'
|
4
|
+
|
1
5
|
module SolidusPaypalBraintree
|
2
6
|
class Engine < Rails::Engine
|
7
|
+
include SolidusSupport::EngineExtensions
|
8
|
+
|
3
9
|
isolate_namespace SolidusPaypalBraintree
|
4
10
|
engine_name 'solidus_paypal_braintree'
|
5
11
|
|
12
|
+
ActiveSupport::Inflector.inflections do |inflect|
|
13
|
+
inflect.acronym 'AVS'
|
14
|
+
end
|
15
|
+
|
6
16
|
# use rspec for tests
|
7
17
|
config.generators do |g|
|
8
18
|
g.test_framework :rspec
|
@@ -10,45 +20,47 @@ module SolidusPaypalBraintree
|
|
10
20
|
|
11
21
|
initializer "register_solidus_paypal_braintree_gateway", after: "spree.register.payment_methods" do |app|
|
12
22
|
app.config.spree.payment_methods << SolidusPaypalBraintree::Gateway
|
13
|
-
|
23
|
+
SolidusPaypalBraintree::Gateway.allowed_admin_form_preference_types << :preference_select
|
24
|
+
Spree::PermittedAttributes.source_attributes.concat [:nonce, :payment_type, :paypal_funding_source]
|
14
25
|
end
|
15
26
|
|
16
|
-
|
17
|
-
Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
|
18
|
-
Rails.configuration.cache_classes ? require(c) : load(c)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
config.to_prepare(&method(:activate).to_proc)
|
23
|
-
|
24
|
-
def self.frontend_available?
|
25
|
-
defined?(Spree::Frontend::Engine) == "constant"
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.backend_available?
|
29
|
-
defined?(Spree::Backend::Engine) == "constant"
|
30
|
-
end
|
31
|
-
|
32
|
-
if frontend_available?
|
27
|
+
if SolidusSupport.frontend_available?
|
33
28
|
config.assets.precompile += [
|
34
29
|
'solidus_paypal_braintree/checkout.js',
|
35
30
|
'solidus_paypal_braintree/frontend.js',
|
36
|
-
'spree/frontend/
|
37
|
-
'
|
31
|
+
'spree/frontend/apple_pay_button.js',
|
32
|
+
'solidus_paypal_braintree_manifest.js'
|
38
33
|
]
|
39
34
|
paths["app/controllers"] << "lib/controllers/frontend"
|
40
35
|
paths["app/views"] << "lib/views/frontend"
|
41
36
|
end
|
42
37
|
|
43
|
-
if backend_available?
|
38
|
+
if SolidusSupport.backend_available?
|
44
39
|
config.assets.precompile += ["spree/backend/solidus_paypal_braintree.js"]
|
45
40
|
paths["app/controllers"] << "lib/controllers/backend"
|
46
41
|
|
47
42
|
# We support Solidus v1.2, which requires some different markup in the
|
48
43
|
# source form partial. This will take precedence over lib/views/backend.
|
49
|
-
paths["app/views"] << "lib/views/backend_v1.2" if
|
44
|
+
paths["app/views"] << "lib/views/backend_v1.2" if Spree.solidus_gem_version < Gem::Version.new('1.3')
|
45
|
+
|
46
|
+
# Solidus v2.4 introduced preference field partials but does not ship a hash field type.
|
47
|
+
# This is solved in Solidus v2.5.
|
48
|
+
if Spree.solidus_gem_version <= Gem::Version.new('2.5.0')
|
49
|
+
paths["app/views"] << "lib/views/backend_v2.4"
|
50
|
+
end
|
50
51
|
|
51
52
|
paths["app/views"] << "lib/views/backend"
|
53
|
+
|
54
|
+
initializer "solidus_paypal_braintree_admin_menu_item", after: "register_solidus_paypal_braintree_gateway" do
|
55
|
+
Spree::Backend::Config.configure do |config|
|
56
|
+
config.menu_items << config.class::MenuItem.new(
|
57
|
+
[:braintree],
|
58
|
+
'cc-paypal',
|
59
|
+
url: '/solidus_paypal_braintree/configurations/list',
|
60
|
+
condition: -> { can?(:list, SolidusPaypalBraintree::Configuration) }
|
61
|
+
)
|
62
|
+
end
|
63
|
+
end
|
52
64
|
end
|
53
65
|
end
|
54
66
|
end
|
@@ -1,18 +1,53 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
FactoryBot.define do
|
4
|
+
# Define your Spree extensions Factories within this file to enable applications,
|
5
|
+
# and other extensions to use and override them.
|
3
6
|
#
|
4
7
|
# Example adding this to your spec_helper will load these Factories for use:
|
5
8
|
# require 'solidus_paypal_braintree/factories'
|
9
|
+
|
10
|
+
factory :solidus_paypal_braintree_payment_method, class: SolidusPaypalBraintree::Gateway do
|
11
|
+
name 'Solidus PayPal Braintree Gateway'
|
12
|
+
active true
|
13
|
+
end
|
14
|
+
|
15
|
+
factory :solidus_paypal_braintree_source, class: SolidusPaypalBraintree::Source do
|
16
|
+
association(:payment_method, factory: :solidus_paypal_braintree_payment_method)
|
17
|
+
user
|
18
|
+
|
19
|
+
trait :credit_card do
|
20
|
+
payment_type SolidusPaypalBraintree::Source::CREDIT_CARD
|
21
|
+
end
|
22
|
+
|
23
|
+
trait :paypal do
|
24
|
+
payment_type SolidusPaypalBraintree::Source::PAYPAL
|
25
|
+
end
|
26
|
+
|
27
|
+
trait :apple_pay do
|
28
|
+
payment_type SolidusPaypalBraintree::Source::APPLE_PAY
|
29
|
+
end
|
30
|
+
end
|
6
31
|
end
|
7
32
|
|
8
|
-
|
33
|
+
FactoryBot.modify do
|
9
34
|
# The Solidus address factory randomizes the zipcode.
|
10
35
|
# The OrderWalkThrough we use in the credit card checkout spec uses this factory for the user addresses.
|
11
36
|
# For credit card payments we transmit the billing address to braintree, for paypal payments the shipping address.
|
12
|
-
# As we match the body in our VCR settings VCR can not match the request anymore and therefore cannot replay existing
|
37
|
+
# As we match the body in our VCR settings VCR can not match the request anymore and therefore cannot replay existing
|
38
|
+
# cassettes.
|
13
39
|
#
|
40
|
+
|
14
41
|
factory :address do
|
15
|
-
zipcode '21088-0255'
|
16
|
-
|
42
|
+
zipcode { '21088-0255' }
|
43
|
+
|
44
|
+
if SolidusSupport.combined_first_and_last_name_in_address?
|
45
|
+
transient do
|
46
|
+
firstname { "John" }
|
47
|
+
lastname { "Doe" }
|
48
|
+
end
|
49
|
+
|
50
|
+
name { "#{firstname} #{lastname}" }
|
51
|
+
end
|
17
52
|
end
|
18
53
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_merchant/network_connection_retries'
|
4
|
+
|
5
|
+
module SolidusPaypalBraintree
|
6
|
+
module RequestProtection
|
7
|
+
include ActiveMerchant::NetworkConnectionRetries
|
8
|
+
|
9
|
+
def protected_request
|
10
|
+
raise ArgumentError unless block_given?
|
11
|
+
|
12
|
+
options = {
|
13
|
+
connection_exceptions: {
|
14
|
+
Braintree::BraintreeError => 'Error while connecting to Braintree gateway'
|
15
|
+
},
|
16
|
+
logger: Rails.logger
|
17
|
+
}
|
18
|
+
retry_exceptions(options) { yield }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,7 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'solidus_core'
|
2
|
-
require '
|
4
|
+
require 'solidus_paypal_braintree/version'
|
3
5
|
require 'solidus_paypal_braintree/engine'
|
4
6
|
require 'solidus_paypal_braintree/country_mapper'
|
7
|
+
require 'solidus_paypal_braintree/request_protection'
|
8
|
+
require 'solidus_support'
|
5
9
|
|
6
10
|
module SolidusPaypalBraintree
|
7
11
|
def self.table_name_prefix
|
@@ -6,25 +6,58 @@
|
|
6
6
|
<% @configurations.each do |config| %>
|
7
7
|
<div class="row">
|
8
8
|
<fieldset>
|
9
|
-
<
|
9
|
+
<legend><%= config.store.name %></legend>
|
10
10
|
|
11
11
|
<%= f.fields_for 'configuration_fields[]', config do |c| %>
|
12
12
|
<div class="field">
|
13
|
-
<%= c.label :paypal %>
|
14
13
|
<%= c.check_box :paypal %>
|
14
|
+
<%= c.label :paypal do %>
|
15
|
+
<%= tag.i class: 'fa fa-paypal' %>
|
16
|
+
<%= c.object.class.human_attribute_name(:paypal) %>
|
17
|
+
<% end %>
|
15
18
|
</div>
|
19
|
+
|
16
20
|
<div class="field">
|
17
|
-
<%= c.label :apple_pay %>
|
18
21
|
<%= c.check_box :apple_pay %>
|
22
|
+
<%= c.label :apple_pay do %>
|
23
|
+
<%= tag.i class: 'fa fa-apple' %>
|
24
|
+
<%= c.object.class.human_attribute_name(:apple_pay) %>
|
25
|
+
<% end %>
|
26
|
+
</div>
|
27
|
+
|
28
|
+
<div class="field">
|
29
|
+
<%= c.check_box :venmo %>
|
30
|
+
<%= c.label :venmo do %>
|
31
|
+
<%= tag.i class: 'fa fa-mobile' %>
|
32
|
+
<%= c.object.class.human_attribute_name(:venmo) %>
|
33
|
+
<% end %>
|
19
34
|
</div>
|
35
|
+
|
20
36
|
<div class="field">
|
21
|
-
<%= c.label :credit_card %>
|
22
37
|
<%= c.check_box :credit_card %>
|
38
|
+
<%= c.label :credit_card do %>
|
39
|
+
<%= tag.i class: 'fa fa-credit-card' %>
|
40
|
+
<%= c.object.class.human_attribute_name(:credit_card) %>
|
41
|
+
<% end %>
|
42
|
+
+
|
43
|
+
<%= c.check_box :three_d_secure %>
|
44
|
+
<%= c.label :three_d_secure do %>
|
45
|
+
<%= tag.i class: 'fa fa-shield' %>
|
46
|
+
<%= c.object.class.human_attribute_name(:three_d_secure) %>
|
47
|
+
<% end %>
|
23
48
|
</div>
|
49
|
+
|
50
|
+
<% config.admin_form_preference_names.each do |name| %>
|
51
|
+
<%= render "spree/admin/shared/preference_fields/#{config.preference_type(name)}",
|
52
|
+
form: c, attribute: "preferred_#{name}",
|
53
|
+
label: t(name, scope: 'spree', default: name.to_s.humanize) %>
|
54
|
+
<% end %>
|
24
55
|
<% end %>
|
25
56
|
</fieldset>
|
26
57
|
</div>
|
27
58
|
<% end %>
|
28
59
|
|
29
|
-
|
60
|
+
<div class="form-buttons filter-actions actions">
|
61
|
+
<%= submit_tag "Update", class: 'btn btn-primary' %>
|
62
|
+
</div>
|
30
63
|
<% end %>
|
@@ -6,11 +6,11 @@
|
|
6
6
|
<% previous_cards.each do |card| %>
|
7
7
|
<label><%= radio_button_tag :card, card.id, card == previous_cards.first %> <%= card.display_number %><br /></label>
|
8
8
|
<% end %>
|
9
|
-
<label><%= radio_button_tag :card, "new", false, { id: "card_new#{id}" } %> <%=
|
9
|
+
<label><%= radio_button_tag :card, "new", false, { id: "card_new#{id}" } %> <%= I18n.t("spree.use_new_cc") %></label>
|
10
10
|
<% end %>
|
11
11
|
</div>
|
12
12
|
|
13
13
|
<div id="card_form<%= id %>" data-hook style="display: none;">
|
14
|
-
<%= render partial: "spree/shared/braintree_hosted_fields", locals: {
|
14
|
+
<%= render partial: "spree/shared/braintree_hosted_fields", locals: { payment_method: payment_method } %>
|
15
15
|
</div>
|
16
16
|
</fieldset>
|
@@ -4,10 +4,10 @@
|
|
4
4
|
<div class="row">
|
5
5
|
<div class="alpha six columns">
|
6
6
|
<dl>
|
7
|
-
<dt><%=
|
7
|
+
<dt><%= I18n.t("spree.identifier") %>:</dt>
|
8
8
|
<dd><%= payment.number %></dd>
|
9
9
|
|
10
|
-
<dt><%=
|
10
|
+
<dt><%= I18n.t("spree.response_code") %>:</dt>
|
11
11
|
<dd><%= braintree_transaction_link(payment) %></dd>
|
12
12
|
|
13
13
|
<% if payment.source.token.present? %>
|
@@ -28,6 +28,11 @@
|
|
28
28
|
<dt><%= Spree::CreditCard.human_attribute_name(:last_digits) %>:</dt>
|
29
29
|
<dd><%= payment.source.last_digits %></dd>
|
30
30
|
<% end %>
|
31
|
+
|
32
|
+
<% if payment.source.paypal? %>
|
33
|
+
<dt><%= I18n.t('spree.paypal_funding_source') %>:</dt>
|
34
|
+
<dd><%= payment.source.display_paypal_funding_source %></dd>
|
35
|
+
<% end %>
|
31
36
|
</dl>
|
32
37
|
</div>
|
33
38
|
</div>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<% label = local_assigns[:label].presence %>
|
2
|
+
<% html_options = {class: 'custom-select fullwidth'}.update(local_assigns[:html_options] || {}) %>
|
3
|
+
<% options = form.object.send("#{attribute}_options") %>
|
4
|
+
|
5
|
+
<div class="field">
|
6
|
+
<% if local_assigns[:form] %>
|
7
|
+
<%= form.label attribute, label %>
|
8
|
+
<%= form.select attribute, options, {}, html_options %>
|
9
|
+
<% else %>
|
10
|
+
<%= label_tag name, label %>
|
11
|
+
<%= select_tag name, value, html_options %>
|
12
|
+
<% end %>
|
13
|
+
</div>
|
@@ -6,11 +6,11 @@
|
|
6
6
|
<% previous_cards.each do |card| %>
|
7
7
|
<label><%= radio_button_tag :card, card.id, card == previous_cards.first %> <%= card.display_number %><br /></label>
|
8
8
|
<% end %>
|
9
|
-
<label><%= radio_button_tag :card, "new", false, { id: "card_new#{id}" } %> <%=
|
9
|
+
<label><%= radio_button_tag :card, "new", false, { id: "card_new#{id}" } %> <%= I18n.t("spree.use_new_cc") %></label>
|
10
10
|
<% end %>
|
11
11
|
</div>
|
12
12
|
|
13
13
|
<div id="card_form<%= id %>" data-hook style="display: none;">
|
14
|
-
<%= render partial: "spree/shared/braintree_hosted_fields", locals: {
|
14
|
+
<%= render partial: "spree/shared/braintree_hosted_fields", locals: { payment_method: payment_method } %>
|
15
15
|
</div>
|
16
16
|
</fieldset>
|