solidus_braintree 1.4.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +12 -0
- data/.gem_release.yml +5 -0
- data/.github_changelog_generator +2 -0
- data/.gitignore +20 -11
- data/.rspec +1 -1
- data/.rubocop.yml +79 -0
- data/CHANGELOG.md +178 -18
- data/Gemfile +31 -23
- data/LICENSE +26 -0
- data/README.md +387 -26
- data/Rakefile +4 -19
- data/app/assets/config/solidus_braintree_manifest.js +1 -0
- data/app/assets/images/solidus_braintree/venmo/venmo_active_blue_button_280x48.svg +19 -0
- data/app/assets/images/solidus_braintree/venmo/venmo_active_blue_button_320x48.svg +19 -0
- data/app/assets/images/solidus_braintree/venmo/venmo_active_blue_button_375x48.svg +19 -0
- data/app/assets/images/solidus_braintree/venmo/venmo_active_white_button_280x48.svg +19 -0
- data/app/assets/images/solidus_braintree/venmo/venmo_active_white_button_320x48.svg +19 -0
- data/app/assets/images/solidus_braintree/venmo/venmo_active_white_button_375x48.svg +19 -0
- data/app/assets/images/solidus_braintree/venmo/venmo_blue_acceptance_mark.svg +15 -0
- data/app/assets/images/solidus_braintree/venmo/venmo_blue_button_280x48.svg +19 -0
- data/app/assets/images/solidus_braintree/venmo/venmo_blue_button_320x48.svg +19 -0
- data/app/assets/images/solidus_braintree/venmo/venmo_blue_button_375x48.svg +19 -0
- data/app/assets/images/solidus_braintree/venmo/venmo_blue_logo.svg +18 -0
- data/app/assets/images/solidus_braintree/venmo/venmo_white_acceptance_mark.svg +20 -0
- data/app/assets/images/solidus_braintree/venmo/venmo_white_button_280x48.svg +19 -0
- data/app/assets/images/solidus_braintree/venmo/venmo_white_button_320x48.svg +19 -0
- data/app/assets/images/solidus_braintree/venmo/venmo_white_button_375x48.svg +19 -0
- data/app/assets/images/solidus_braintree/venmo/venmo_white_logo.svg +18 -0
- data/app/assets/javascripts/solidus_braintree/apple_pay_button.js +179 -0
- data/app/assets/javascripts/solidus_braintree/checkout.js +108 -0
- data/app/assets/javascripts/solidus_braintree/client.js +239 -0
- data/app/assets/javascripts/solidus_braintree/constants.js +89 -0
- data/app/assets/javascripts/solidus_braintree/frontend.js +14 -0
- data/app/assets/javascripts/solidus_braintree/hosted_form.js +46 -0
- data/app/assets/javascripts/solidus_braintree/paypal_button.js +178 -0
- data/app/assets/javascripts/solidus_braintree/paypal_messaging.js +22 -0
- data/app/assets/javascripts/solidus_braintree/promise.js +20 -0
- data/app/assets/javascripts/solidus_braintree/venmo_button.js +86 -0
- data/app/assets/javascripts/spree/backend/solidus_braintree.js +96 -0
- data/app/assets/javascripts/spree/frontend/paypal_button.js +34 -0
- data/app/assets/javascripts/spree/frontend/solidus_braintree.js +1 -0
- data/app/assets/stylesheets/spree/backend/solidus_braintree.scss +28 -0
- data/app/assets/stylesheets/spree/frontend/solidus_braintree.scss +51 -0
- data/app/decorators/controllers/solidus_braintree/admin_payments_controller_decorator.rb +11 -0
- data/app/decorators/controllers/solidus_braintree/checkout_controller_decorator.rb +11 -0
- data/app/decorators/controllers/solidus_braintree/client_tokens_controller.rb +41 -0
- data/app/decorators/controllers/solidus_braintree/orders_controller_decorator.rb +11 -0
- data/app/decorators/models/solidus_braintree/spree/store_decorator.rb +20 -0
- data/app/decorators/models/solidus_braintree/spree/user_decorator.rb +13 -0
- data/app/helpers/solidus_braintree/braintree_admin_helper.rb +23 -0
- data/app/helpers/solidus_braintree/braintree_checkout_helper.rb +60 -0
- data/app/models/application_record.rb +5 -0
- data/app/models/solidus_braintree/address.rb +64 -0
- data/app/models/solidus_braintree/avs_result.rb +69 -0
- data/app/models/solidus_braintree/configuration.rb +39 -0
- data/app/models/solidus_braintree/customer.rb +8 -0
- data/app/models/solidus_braintree/gateway.rb +433 -0
- data/app/models/solidus_braintree/response.rb +80 -0
- data/app/models/solidus_braintree/source.rb +135 -0
- data/app/models/solidus_braintree/transaction.rb +31 -0
- data/app/models/solidus_braintree/transaction_address.rb +88 -0
- data/app/models/solidus_braintree/transaction_import.rb +98 -0
- data/app/overrides/spree/payments/payment/add_paypal_funding_source_to_payment.rb +9 -0
- data/app/views/spree/api/payments/source_views/_braintree.json.jbuilder +1 -1
- data/app/views/spree/checkout/existing_payment/_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_head_scripts.html.erb +26 -0
- data/app/views/spree/shared/_braintree_hosted_fields.html.erb +43 -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 +4 -1
- data/bin/rails +5 -5
- data/bin/rails-engine +13 -0
- data/bin/rails-sandbox +16 -0
- data/bin/rake +7 -0
- data/bin/sandbox +103 -0
- data/bin/setup +5 -4
- data/config/locales/en.yml +94 -2
- data/config/locales/it.yml +56 -0
- data/config/routes.rb +12 -3
- data/db/migrate/20160830061749_create_solidus_paypal_braintree_sources.rb +16 -0
- data/db/migrate/20160906201711_create_solidus_paypal_braintree_customers.rb +13 -0
- data/db/migrate/20161114231422_create_solidus_paypal_braintree_configurations.rb +11 -0
- data/db/migrate/20161125172005_add_braintree_configuration_to_stores.rb +7 -0
- data/db/migrate/20170203191030_add_credit_card_to_braintree_configuration.rb +6 -0
- data/db/migrate/20170505193712_add_null_constraint_to_sources.rb +38 -0
- data/db/migrate/20170508085402_add_not_null_constraint_to_sources_payment_type.rb +14 -0
- 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/db/migrate/20230109080950_rename_solidus_paypal_braintree_source_type.rb +31 -0
- data/lib/controllers/backend/solidus_braintree/configurations_controller.rb +48 -0
- data/lib/controllers/frontend/solidus_braintree/checkouts_controller.rb +31 -0
- data/lib/controllers/frontend/solidus_braintree/transactions_controller.rb +67 -0
- data/lib/generators/solidus_braintree/install/install_generator.rb +54 -18
- data/lib/generators/solidus_braintree/install/templates/initializer.rb +6 -0
- data/lib/solidus_braintree/country_mapper.rb +37 -0
- data/lib/solidus_braintree/engine.rb +55 -10
- data/lib/solidus_braintree/extension_configuration.rb +23 -0
- data/lib/solidus_braintree/request_protection.rb +21 -0
- data/lib/solidus_braintree/testing_support/factories.rb +53 -0
- data/lib/solidus_braintree/version.rb +3 -1
- data/lib/solidus_braintree.rb +14 -2
- data/lib/solidus_paypal_braintree.rb +6 -0
- data/lib/views/backend/solidus_braintree/configurations/list.html.erb +63 -0
- data/lib/views/backend/spree/admin/payments/source_forms/_braintree.html.erb +16 -0
- data/lib/views/backend/spree/admin/payments/source_views/_braintree.html.erb +39 -0
- 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/_braintree.html.erb +16 -0
- data/lib/views/backend_v2.4/spree/admin/shared/preference_fields/_hash.html.erb +12 -0
- data/lib/views/frontend/solidus_braintree/payments/_payment.html.erb +12 -0
- data/lib/views/frontend/spree/checkout/payment/_braintree.html.erb +23 -0
- data/lib/views/frontend/spree/shared/_paypal_checkout_button.html.erb +32 -0
- data/solidus_braintree.gemspec +39 -38
- data/spec/controllers/solidus_braintree/checkouts_controller_spec.rb +99 -0
- data/spec/controllers/solidus_braintree/client_tokens_controller_spec.rb +55 -0
- data/spec/controllers/solidus_braintree/configurations_controller_spec.rb +73 -0
- data/spec/controllers/solidus_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 +194 -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 +171 -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/customer.yml +79 -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/bin.yml +295 -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_braintree/braintree_admin_helper_spec.rb +17 -0
- data/spec/helpers/solidus_braintree/braintree_checkout_helper_spec.rb +70 -0
- data/spec/models/solidus_braintree/address_spec.rb +71 -0
- data/spec/models/solidus_braintree/avs_result_spec.rb +317 -0
- data/spec/models/solidus_braintree/gateway_spec.rb +742 -0
- data/spec/models/solidus_braintree/response_spec.rb +280 -0
- data/spec/models/solidus_braintree/source_spec.rb +539 -0
- data/spec/models/solidus_braintree/transaction_address_spec.rb +235 -0
- data/spec/models/solidus_braintree/transaction_import_spec.rb +302 -0
- data/spec/models/solidus_braintree/transaction_spec.rb +86 -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 +32 -0
- data/spec/support/capybara.rb +7 -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 +276 -224
- data/LICENSE.txt +0 -21
- data/app/controllers/spree/api/braintree_client_token_controller.rb +0 -13
- data/app/decorators/lib/solidus_braintree/spree/permitted_attributes_decorator.rb +0 -9
- data/app/decorators/models/solidus_braintree/spree/credit_card_decorator.rb +0 -11
- data/app/decorators/models/solidus_braintree/spree/payment_decorator.rb +0 -10
- data/app/helpers/braintree_view_helpers.rb +0 -20
- data/app/models/concerns/solidus_braintree/add_name_validation_concern.rb +0 -8
- data/app/models/concerns/solidus_braintree/inject_device_data_concern.rb +0 -18
- data/app/models/concerns/solidus_braintree/payment_braintree_nonce_concern.rb +0 -8
- data/app/models/concerns/solidus_braintree/permitted_attributes_concern.rb +0 -11
- data/app/models/concerns/solidus_braintree/skip_require_card_numbers_concern.rb +0 -14
- data/app/models/concerns/solidus_braintree/use_data_field_concern.rb +0 -23
- data/app/models/solidus/gateway/braintree_gateway.rb +0 -306
- data/app/overrides/spree/checkout/_confirm/braintree_security.html.erb.deface +0 -9
- data/app/views/spree/admin/payments/source_forms/_braintree.html.erb +0 -38
- data/app/views/spree/admin/payments/source_views/_braintree.html.erb +0 -30
- data/app/views/spree/checkout/payment/_braintree.html.erb +0 -55
- data/app/views/spree/checkout/payment/_braintree_initialization.html.erb +0 -12
- data/config/initializers/braintree.rb +0 -3
- data/db/migrate/20150910170527_add_data_to_credit_card.rb +0 -5
- data/db/migrate/20160426221931_add_braintree_device_data_to_order.rb +0 -5
- data/lib/assets/javascripts/spree/backend/braintree/solidus_braintree.js +0 -59
- data/lib/assets/javascripts/spree/frontend/braintree/solidus_braintree.js +0 -144
- data/lib/assets/javascripts/vendor/braintree.js +0 -8
- data/lib/assets/stylesheets/spree/frontend/solidus_braintree.scss +0 -26
@@ -1,24 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'solidus_core'
|
4
|
+
require 'solidus_support'
|
5
|
+
|
1
6
|
module SolidusBraintree
|
2
7
|
class Engine < Rails::Engine
|
8
|
+
include SolidusSupport::EngineExtensions
|
9
|
+
|
10
|
+
isolate_namespace SolidusBraintree
|
3
11
|
engine_name 'solidus_braintree'
|
4
12
|
|
5
|
-
|
6
|
-
|
13
|
+
ActiveSupport::Inflector.inflections do |inflect|
|
14
|
+
inflect.acronym 'AVS'
|
15
|
+
end
|
7
16
|
|
8
|
-
initializer "
|
9
|
-
|
17
|
+
initializer "register_solidus_braintree_gateway", after: "spree.register.payment_methods" do |app|
|
18
|
+
config.to_prepare do
|
19
|
+
app.config.spree.payment_methods << SolidusBraintree::Gateway
|
20
|
+
SolidusBraintree::Gateway.allowed_admin_form_preference_types.push(:preference_select).uniq!
|
21
|
+
::Spree::PermittedAttributes.source_attributes.concat([:nonce, :payment_type, :paypal_funding_source]).uniq!
|
22
|
+
end
|
10
23
|
end
|
11
24
|
|
12
|
-
|
13
|
-
|
14
|
-
'
|
25
|
+
if SolidusSupport.frontend_available?
|
26
|
+
config.assets.precompile += [
|
27
|
+
'solidus_braintree/checkout.js',
|
28
|
+
'solidus_braintree/frontend.js',
|
29
|
+
'spree/frontend/apple_pay_button.js',
|
30
|
+
'solidus_braintree_manifest.js'
|
15
31
|
]
|
32
|
+
paths["app/controllers"] << "lib/controllers/frontend"
|
33
|
+
paths["app/views"] << "lib/views/frontend"
|
34
|
+
end
|
16
35
|
|
17
|
-
|
18
|
-
|
36
|
+
if SolidusSupport.backend_available?
|
37
|
+
config.assets.precompile += ["spree/backend/solidus_braintree.js"]
|
38
|
+
paths["app/controllers"] << "lib/controllers/backend"
|
39
|
+
|
40
|
+
# We support Solidus v1.2, which requires some different markup in the
|
41
|
+
# source form partial. This will take precedence over lib/views/backend.
|
42
|
+
paths["app/views"] << "lib/views/backend_v1.2" if Spree.solidus_gem_version < Gem::Version.new('1.3')
|
43
|
+
|
44
|
+
# Solidus v2.4 introduced preference field partials but does not ship a hash field type.
|
45
|
+
# This is solved in Solidus v2.5.
|
46
|
+
if Spree.solidus_gem_version <= Gem::Version.new('2.5.0')
|
47
|
+
paths["app/views"] << "lib/views/backend_v2.4"
|
48
|
+
end
|
49
|
+
|
50
|
+
paths["app/views"] << "lib/views/backend"
|
51
|
+
|
52
|
+
initializer "solidus_braintree_admin_menu_item", after: "register_solidus_braintree_gateway" do
|
53
|
+
Spree::Backend::Config.configure do |config|
|
54
|
+
config.menu_items << config.class::MenuItem.new(
|
55
|
+
[:braintree],
|
56
|
+
'cc-paypal',
|
57
|
+
url: '/solidus_braintree/configurations/list',
|
58
|
+
condition: -> { can?(:list, SolidusBraintree::Configuration) }
|
59
|
+
)
|
60
|
+
end
|
19
61
|
end
|
20
62
|
end
|
21
63
|
|
22
|
-
|
64
|
+
# use rspec for tests
|
65
|
+
config.generators do |g|
|
66
|
+
g.test_framework :rspec
|
67
|
+
end
|
23
68
|
end
|
24
69
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SolidusBraintree
|
4
|
+
# Deviating from the usual `Configuration` name proposed by
|
5
|
+
# `solidus_dev_support` because it's already taken by a model.
|
6
|
+
class ExtensionConfiguration
|
7
|
+
# Define here the settings for this extension, e.g.:
|
8
|
+
#
|
9
|
+
# attr_accessor :my_setting
|
10
|
+
end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def configuration
|
14
|
+
@configuration ||= ExtensionConfiguration.new
|
15
|
+
end
|
16
|
+
|
17
|
+
alias config configuration
|
18
|
+
|
19
|
+
def configure
|
20
|
+
yield configuration
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_merchant/network_connection_retries'
|
4
|
+
|
5
|
+
module SolidusBraintree
|
6
|
+
module RequestProtection
|
7
|
+
include ActiveMerchant::NetworkConnectionRetries
|
8
|
+
|
9
|
+
def protected_request(&block)
|
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, &block)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,53 @@
|
|
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.
|
6
|
+
#
|
7
|
+
# Example adding this to your spec_helper will load these Factories for use:
|
8
|
+
# require 'solidus_braintree/factories'
|
9
|
+
|
10
|
+
factory :solidus_braintree_payment_method, class: SolidusBraintree::Gateway do
|
11
|
+
name { 'Solidus Braintree Gateway' }
|
12
|
+
active { true }
|
13
|
+
end
|
14
|
+
|
15
|
+
factory :solidus_braintree_source, class: SolidusBraintree::Source do
|
16
|
+
association(:payment_method, factory: :solidus_braintree_payment_method)
|
17
|
+
user
|
18
|
+
|
19
|
+
trait :credit_card do
|
20
|
+
payment_type { SolidusBraintree::Source::CREDIT_CARD }
|
21
|
+
end
|
22
|
+
|
23
|
+
trait :paypal do
|
24
|
+
payment_type { SolidusBraintree::Source::PAYPAL }
|
25
|
+
end
|
26
|
+
|
27
|
+
trait :apple_pay do
|
28
|
+
payment_type { SolidusBraintree::Source::APPLE_PAY }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
FactoryBot.modify do
|
34
|
+
# The Solidus address factory randomizes the zipcode.
|
35
|
+
# The OrderWalkThrough we use in the credit card checkout spec uses this factory for the user addresses.
|
36
|
+
# For credit card payments we transmit the billing address to braintree, for paypal payments the shipping address.
|
37
|
+
# As we match the body in our VCR settings VCR can not match the request anymore and therefore cannot replay existing
|
38
|
+
# cassettes.
|
39
|
+
#
|
40
|
+
|
41
|
+
factory :address do
|
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
|
52
|
+
end
|
53
|
+
end
|
data/lib/solidus_braintree.rb
CHANGED
@@ -1,4 +1,16 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'solidus_core'
|
2
4
|
require 'solidus_support'
|
3
|
-
|
5
|
+
|
6
|
+
require 'solidus_braintree/country_mapper'
|
7
|
+
require 'solidus_braintree/request_protection'
|
8
|
+
require 'solidus_braintree/extension_configuration'
|
9
|
+
require 'solidus_braintree/version'
|
4
10
|
require 'solidus_braintree/engine'
|
11
|
+
|
12
|
+
module SolidusBraintree
|
13
|
+
def self.table_name_prefix
|
14
|
+
'solidus_paypal_braintree_'
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
<% content_for :page_title do %>
|
2
|
+
<%= t(:title, scope: 'solidus_braintree.configurations') %>
|
3
|
+
<% end %>
|
4
|
+
|
5
|
+
<%= form_for :configurations, url: solidus_braintree.configurations_path do |f| %>
|
6
|
+
<% @configurations.each do |config| %>
|
7
|
+
<div class="row">
|
8
|
+
<fieldset>
|
9
|
+
<legend><%= config.store.name %></legend>
|
10
|
+
|
11
|
+
<%= f.fields_for 'configuration_fields[]', config do |c| %>
|
12
|
+
<div class="field">
|
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 %>
|
18
|
+
</div>
|
19
|
+
|
20
|
+
<div class="field">
|
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 %>
|
34
|
+
</div>
|
35
|
+
|
36
|
+
<div class="field">
|
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 %>
|
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 %>
|
55
|
+
<% end %>
|
56
|
+
</fieldset>
|
57
|
+
</div>
|
58
|
+
<% end %>
|
59
|
+
|
60
|
+
<div class="form-buttons filter-actions actions">
|
61
|
+
<%= submit_tag "Update", class: 'btn btn-primary' %>
|
62
|
+
</div>
|
63
|
+
<% end %>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<% id = payment_method.id %>
|
2
|
+
|
3
|
+
<fieldset class="no-border-bottom braintree-hosted-fields" data-braintree-hosted-fields data-id="<%= id %>" data-payment-method-id="<%= id %>">
|
4
|
+
<div class="field" data-hook="previous_cards">
|
5
|
+
<% if previous_cards.any? %>
|
6
|
+
<% previous_cards.each do |card| %>
|
7
|
+
<label><%= radio_button_tag :card, card.id, card == previous_cards.first %> <%= card.display_number %><br /></label>
|
8
|
+
<% end %>
|
9
|
+
<label><%= radio_button_tag :card, "new", false, { id: "card_new#{id}" } %> <%= I18n.t("spree.use_new_cc") %></label>
|
10
|
+
<% end %>
|
11
|
+
</div>
|
12
|
+
|
13
|
+
<div id="card_form<%= id %>" data-hook style="display: none;">
|
14
|
+
<%= render partial: "spree/shared/braintree_hosted_fields", locals: { payment_method: payment_method } %>
|
15
|
+
</div>
|
16
|
+
</fieldset>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<fieldset data-hook="credit_card">
|
2
|
+
<legend align="center"><%= SolidusBraintree::Gateway.model_name.human %></legend>
|
3
|
+
|
4
|
+
<div class="row">
|
5
|
+
<div class="alpha six columns">
|
6
|
+
<dl>
|
7
|
+
<dt><%= I18n.t("spree.identifier") %>:</dt>
|
8
|
+
<dd><%= payment.number %></dd>
|
9
|
+
|
10
|
+
<dt><%= I18n.t("spree.response_code") %>:</dt>
|
11
|
+
<dd><%= braintree_transaction_link(payment) %></dd>
|
12
|
+
|
13
|
+
<% if payment.source.token.present? %>
|
14
|
+
<dt><%= t('solidus_braintree.token') %>:</dt>
|
15
|
+
<dd><%= payment.source.token %></dd>
|
16
|
+
<% else %>
|
17
|
+
<dt><%= t('solidus_braintree.nonce') %>:</dt>
|
18
|
+
<dd><%= payment.source.nonce %></dd>
|
19
|
+
<% end %>
|
20
|
+
|
21
|
+
<dt><%= t('solidus_braintree.payment_type.label') %>:</dt>
|
22
|
+
<dd><%= payment.source.friendly_payment_type %></dd>
|
23
|
+
|
24
|
+
<% if payment.source.credit_card? %>
|
25
|
+
<dt><%= Spree::CreditCard.human_attribute_name(:card_type) %>:</dt>
|
26
|
+
<dd><%= payment.source.card_type %></dd>
|
27
|
+
|
28
|
+
<dt><%= Spree::CreditCard.human_attribute_name(:last_digits) %>:</dt>
|
29
|
+
<dd><%= payment.source.last_digits %></dd>
|
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 %>
|
36
|
+
</dl>
|
37
|
+
</div>
|
38
|
+
</div>
|
39
|
+
</fieldset>
|
@@ -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>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<% id = payment_method.id %>
|
2
|
+
|
3
|
+
<fieldset class="no-border-bottom braintree-hosted-fields" data-braintree-hosted-fields data-id="braintree" data-payment-method-id="<%= id %>">
|
4
|
+
<div class="field" data-hook="previous_cards">
|
5
|
+
<% if previous_cards.any? %>
|
6
|
+
<% previous_cards.each do |card| %>
|
7
|
+
<label><%= radio_button_tag :card, card.id, card == previous_cards.first %> <%= card.display_number %><br /></label>
|
8
|
+
<% end %>
|
9
|
+
<label><%= radio_button_tag :card, "new", false, { id: "card_new#{id}" } %> <%= I18n.t("spree.use_new_cc") %></label>
|
10
|
+
<% end %>
|
11
|
+
</div>
|
12
|
+
|
13
|
+
<div id="card_form<%= id %>" data-hook style="display: none;">
|
14
|
+
<%= render partial: "spree/shared/braintree_hosted_fields", locals: { payment_method: payment_method } %>
|
15
|
+
</div>
|
16
|
+
</fieldset>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<% label = local_assigns[:label].presence %>
|
2
|
+
<% html_options = {class: 'input_hash fullwidth'}.update(local_assigns[:html_options] || {}) %>
|
3
|
+
|
4
|
+
<div class="field">
|
5
|
+
<% if local_assigns[:form] %>
|
6
|
+
<%= form.label attribute, label %>
|
7
|
+
<%= form.text_area attribute, html_options %>
|
8
|
+
<% else %>
|
9
|
+
<%= label_tag name, label %>
|
10
|
+
<%= text_area_tag name, value, html_options %>
|
11
|
+
<% end %>
|
12
|
+
</div>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<br />
|
2
|
+
<%= payment.source.try(:display_payment_type) %>
|
3
|
+
|
4
|
+
<% if payment.source.try(:paypal?) %>
|
5
|
+
<% if payment.source.respond_to?(:paypal_funding_source) && payment.source.paypal_funding_source.present? %>
|
6
|
+
<br />
|
7
|
+
<%= t('spree.paypal_funding', funding: payment.source.display_paypal_funding_source) %>
|
8
|
+
<% end %>
|
9
|
+
<% elsif payment.source.try(:venmo?) %>
|
10
|
+
<br />
|
11
|
+
<%= payment.source.source_description %>
|
12
|
+
<% end %>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<% id = payment_method.id %>
|
2
|
+
|
3
|
+
<%= render "spree/shared/braintree_head_scripts" %>
|
4
|
+
|
5
|
+
<% if current_store.braintree_configuration.paypal? %>
|
6
|
+
<%= render "spree/shared/paypal_checkout_button" %>
|
7
|
+
<% end %>
|
8
|
+
|
9
|
+
<% if current_store.braintree_configuration.credit_card? %>
|
10
|
+
<fieldset class="braintree-hosted-fields" data-braintree-hosted-fields data-id="<%= id %>">
|
11
|
+
<%= render "spree/shared/braintree_hosted_fields", payment_method: payment_method %>
|
12
|
+
</fieldset>
|
13
|
+
<% end %>
|
14
|
+
|
15
|
+
<% if current_store.braintree_configuration.apple_pay? %>
|
16
|
+
<%= render "spree/shared/apple_pay_button", id: id %>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
<% if current_store.braintree_configuration.venmo? %>
|
20
|
+
<%= render "spree/shared/venmo_button", payment_method: payment_method %>
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<%= render "spree/shared/braintree_errors" %>
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<div id="paypal-button"></div>
|
2
|
+
<div data-pp-message data-pp-placement="payment" data-pp-amount="<%= @order.total %>"></div>
|
3
|
+
|
4
|
+
<script>
|
5
|
+
var address = <%= sanitize SolidusBraintree::Address.new(current_order.ship_address).to_json %>
|
6
|
+
|
7
|
+
var paypalOptions = {
|
8
|
+
flow: '<%= SolidusBraintree::Gateway.first.preferred_paypal_flow %>',
|
9
|
+
amount: '<%= current_order.total %>',
|
10
|
+
currency: '<%= current_order.currency %>',
|
11
|
+
enableShippingAddress: true,
|
12
|
+
venmoFunding: <%= SolidusBraintree::Gateway.first.preferred_enable_venmo_funding %>,
|
13
|
+
buyerCountry: '<%= SolidusBraintree::Gateway.first.preferred_force_buyer_country %>',
|
14
|
+
shippingAddressOverride: address,
|
15
|
+
shippingAddressEditable: false,
|
16
|
+
environment: '<%= Rails.env.production? ? "production" : "sandbox" %>',
|
17
|
+
locale: '<%= paypal_button_preference(:paypal_button_locale, store: current_store) %>',
|
18
|
+
style: {
|
19
|
+
color: '<%= paypal_button_preference(:paypal_button_color, store: current_store) %>',
|
20
|
+
shape: '<%= paypal_button_preference(:paypal_button_shape, store: current_store) %>',
|
21
|
+
label: '<%= paypal_button_preference(:paypal_button_label, store: current_store) %>',
|
22
|
+
layout: '<%= paypal_button_preference(:paypal_button_layout, store: current_store) %>',
|
23
|
+
<% if paypal_button_preference(:paypal_button_layout, store: current_store) == "horizontal" %>
|
24
|
+
tagline: '<%= paypal_button_preference(:paypal_button_tagline, store: current_store) %>',
|
25
|
+
<% end %>
|
26
|
+
messaging: '<%= paypal_button_preference(:paypal_button_messaging, store: current_store) %>'
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
var button = new SolidusBraintree.createPaypalButton(document.querySelector("#paypal-button"), paypalOptions);
|
31
|
+
button.initialize();
|
32
|
+
</script>
|
data/solidus_braintree.gemspec
CHANGED
@@ -1,43 +1,44 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
require 'solidus_braintree/version'
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/solidus_braintree/version'
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
8
|
-
spec.version
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
11
|
-
|
12
|
-
spec.summary
|
13
|
-
spec.description
|
14
|
-
spec.homepage
|
15
|
-
spec.license
|
16
|
-
|
17
|
-
spec.
|
18
|
-
spec.
|
19
|
-
spec.
|
6
|
+
spec.name = 'solidus_braintree'
|
7
|
+
spec.version = SolidusBraintree::VERSION
|
8
|
+
spec.authors = ['Stembolt']
|
9
|
+
spec.email = 'braintree+gemfile@stembolt.com'
|
10
|
+
|
11
|
+
spec.summary = 'Officially supported Braintree extension'
|
12
|
+
spec.description = 'Uses the javascript API for seamless braintree payments'
|
13
|
+
spec.homepage = 'https://github.com/solidusio/solidus_braintree'
|
14
|
+
spec.license = 'BSD-3-Clause'
|
15
|
+
|
16
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
17
|
+
spec.metadata['source_code_uri'] = 'https://github.com/solidusio/solidus_braintree'
|
18
|
+
spec.metadata['changelog_uri'] = 'https://github.com/solidusio/solidus_braintree/blob/master/CHANGELOG.md'
|
19
|
+
|
20
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.5', '< 4')
|
21
|
+
|
22
|
+
# Specify which files should be added to the gem when it is released.
|
23
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
24
|
+
files = Dir.chdir(__dir__) { `git ls-files -z`.split("\x0") }
|
25
|
+
|
26
|
+
spec.files = files.grep_v(%r{^(test|spec|features)/})
|
27
|
+
spec.test_files = files.grep(%r{^(test|spec|features)/})
|
28
|
+
spec.bindir = "exe"
|
29
|
+
spec.executables = files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
30
|
spec.require_paths = ["lib"]
|
21
31
|
|
22
|
-
spec.add_dependency
|
23
|
-
spec.add_dependency
|
24
|
-
spec.add_dependency
|
25
|
-
spec.add_dependency
|
26
|
-
|
27
|
-
|
28
|
-
spec.add_development_dependency
|
29
|
-
spec.add_development_dependency '
|
30
|
-
spec.add_development_dependency '
|
31
|
-
spec.add_development_dependency '
|
32
|
-
|
33
|
-
spec.
|
34
|
-
spec.add_development_dependency 'ffaker'
|
35
|
-
spec.add_development_dependency "rspec"
|
36
|
-
spec.add_development_dependency "pry"
|
37
|
-
spec.add_development_dependency "byebug"
|
38
|
-
spec.add_development_dependency 'sqlite3'
|
39
|
-
spec.add_development_dependency 'database_cleaner', '~> 1.2'
|
40
|
-
spec.add_development_dependency "vcr", '~> 3.0'
|
41
|
-
spec.add_development_dependency "webmock"
|
42
|
-
spec.add_development_dependency 'simplecov'
|
32
|
+
spec.add_dependency 'activemerchant', '~> 1.48'
|
33
|
+
spec.add_dependency 'braintree', '~> 3.4'
|
34
|
+
spec.add_dependency 'solidus_api', ['>= 2.4.0', '< 4']
|
35
|
+
spec.add_dependency 'solidus_core', ['>= 2.4.0', '< 4']
|
36
|
+
spec.add_dependency 'solidus_support', ['>= 0.8.1', '< 1']
|
37
|
+
|
38
|
+
spec.add_development_dependency 'rails-controller-testing'
|
39
|
+
spec.add_development_dependency 'solidus_dev_support', '~> 2.5'
|
40
|
+
spec.add_development_dependency 'vcr'
|
41
|
+
spec.add_development_dependency 'webmock'
|
42
|
+
|
43
|
+
spec.post_install_message = "If you're upgrading to v2.0.0, please see the README for upgrade instructions."
|
43
44
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'support/order_ready_for_payment'
|
3
|
+
|
4
|
+
RSpec.describe SolidusBraintree::CheckoutsController, type: :controller do
|
5
|
+
routes { SolidusBraintree::Engine.routes }
|
6
|
+
|
7
|
+
include_context 'when order is ready for payment'
|
8
|
+
|
9
|
+
describe 'PATCH update' do
|
10
|
+
subject(:patch_update) { patch :update, params: params }
|
11
|
+
|
12
|
+
let(:params) do
|
13
|
+
{
|
14
|
+
"state" => "payment",
|
15
|
+
"order" => {
|
16
|
+
"payments_attributes" => [
|
17
|
+
{
|
18
|
+
"payment_method_id" => payment_method.id,
|
19
|
+
"source_attributes" => {
|
20
|
+
"nonce" => "fake-paypal-billing-agreement-nonce",
|
21
|
+
"payment_type" => SolidusBraintree::Source::PAYPAL
|
22
|
+
}
|
23
|
+
}
|
24
|
+
],
|
25
|
+
"use_billing" => "1",
|
26
|
+
"use_postmates_shipping" => "0"
|
27
|
+
},
|
28
|
+
"reuse_credit" => "1",
|
29
|
+
"order_bill_address" => "",
|
30
|
+
"reuse_bill_address" => "1"
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
let!(:payment_method) do
|
35
|
+
create_gateway
|
36
|
+
end
|
37
|
+
|
38
|
+
before do
|
39
|
+
allow(controller).to receive(:try_spree_current_user) { user }
|
40
|
+
allow(controller).to receive(:spree_current_user) { user }
|
41
|
+
allow(controller).to receive(:current_order) { order }
|
42
|
+
end
|
43
|
+
|
44
|
+
context "when a payment is created successfully", vcr: {
|
45
|
+
cassette_name: 'checkout/update',
|
46
|
+
match_requests_on: [:braintree_uri]
|
47
|
+
} do
|
48
|
+
it 'creates a payment' do
|
49
|
+
expect { patch_update }.
|
50
|
+
to change { order.payments.count }.
|
51
|
+
from(0).
|
52
|
+
to(1)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'creates a payment source' do
|
56
|
+
expect { patch_update }.
|
57
|
+
to change(SolidusBraintree::Source, :count).
|
58
|
+
from(0).
|
59
|
+
to(1)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'assigns @order' do
|
63
|
+
patch_update
|
64
|
+
expect(assigns(:order)).to eq order
|
65
|
+
end
|
66
|
+
|
67
|
+
it "is successful" do
|
68
|
+
expect(patch_update).to be_successful
|
69
|
+
end
|
70
|
+
|
71
|
+
it "renders 'ok'" do
|
72
|
+
expect(patch_update.body).to eql("ok")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "when a payment is not created successfully" do
|
77
|
+
before do
|
78
|
+
allow_any_instance_of(::Spree::Payment).to receive(:save).and_return(false)
|
79
|
+
end
|
80
|
+
|
81
|
+
# No idea why this is the case, but I'm just adding the tests here
|
82
|
+
it "is successful" do
|
83
|
+
expect(patch_update).to be_successful
|
84
|
+
end
|
85
|
+
|
86
|
+
it "renders 'not-ok'" do
|
87
|
+
expect(patch_update.body).to eq('not-ok')
|
88
|
+
end
|
89
|
+
|
90
|
+
it "does not change the number of payments in the system" do
|
91
|
+
expect{ patch_update }.not_to(change(::Spree::Payment, :count))
|
92
|
+
end
|
93
|
+
|
94
|
+
it "does not change the number of sources in the system" do
|
95
|
+
expect{ patch_update }.not_to(change(SolidusBraintree::Source, :count))
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|