solidus_paypal_braintree 0.4.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +44 -0
  3. data/.gem_release.yml +5 -0
  4. data/.github/stale.yml +17 -0
  5. data/.gitignore +19 -0
  6. data/.rspec +2 -0
  7. data/.rubocop.yml +76 -0
  8. data/CHANGELOG.md +327 -0
  9. data/Gemfile +38 -0
  10. data/LICENSE +2 -2
  11. data/README.md +170 -25
  12. data/Rakefile +4 -25
  13. data/app/assets/config/solidus_paypal_braintree_manifest.js +1 -0
  14. data/app/assets/images/solidus_paypal_braintree/venmo/venmo_active_blue_button_280x48.svg +19 -0
  15. data/app/assets/images/solidus_paypal_braintree/venmo/venmo_active_blue_button_320x48.svg +19 -0
  16. data/app/assets/images/solidus_paypal_braintree/venmo/venmo_active_blue_button_375x48.svg +19 -0
  17. data/app/assets/images/solidus_paypal_braintree/venmo/venmo_active_white_button_280x48.svg +19 -0
  18. data/app/assets/images/solidus_paypal_braintree/venmo/venmo_active_white_button_320x48.svg +19 -0
  19. data/app/assets/images/solidus_paypal_braintree/venmo/venmo_active_white_button_375x48.svg +19 -0
  20. data/app/assets/images/solidus_paypal_braintree/venmo/venmo_blue_acceptance_mark.svg +15 -0
  21. data/app/assets/images/solidus_paypal_braintree/venmo/venmo_blue_button_280x48.svg +19 -0
  22. data/app/assets/images/solidus_paypal_braintree/venmo/venmo_blue_button_320x48.svg +19 -0
  23. data/app/assets/images/solidus_paypal_braintree/venmo/venmo_blue_button_375x48.svg +19 -0
  24. data/app/assets/images/solidus_paypal_braintree/venmo/venmo_blue_logo.svg +18 -0
  25. data/app/assets/images/solidus_paypal_braintree/venmo/venmo_white_acceptance_mark.svg +20 -0
  26. data/app/assets/images/solidus_paypal_braintree/venmo/venmo_white_button_280x48.svg +19 -0
  27. data/app/assets/images/solidus_paypal_braintree/venmo/venmo_white_button_320x48.svg +19 -0
  28. data/app/assets/images/solidus_paypal_braintree/venmo/venmo_white_button_375x48.svg +19 -0
  29. data/app/assets/images/solidus_paypal_braintree/venmo/venmo_white_logo.svg +18 -0
  30. data/app/assets/javascripts/solidus_paypal_braintree/checkout.js +32 -3
  31. data/app/assets/javascripts/solidus_paypal_braintree/client.js +57 -4
  32. data/app/assets/javascripts/solidus_paypal_braintree/constants.js +27 -0
  33. data/app/assets/javascripts/solidus_paypal_braintree/frontend.js +2 -0
  34. data/app/assets/javascripts/solidus_paypal_braintree/hosted_form.js +15 -5
  35. data/app/assets/javascripts/solidus_paypal_braintree/paypal_button.js +71 -21
  36. data/app/assets/javascripts/solidus_paypal_braintree/paypal_messaging.js +22 -0
  37. data/app/assets/javascripts/solidus_paypal_braintree/venmo_button.js +86 -0
  38. data/app/assets/javascripts/spree/backend/solidus_paypal_braintree.js +2 -2
  39. data/app/assets/javascripts/spree/frontend/paypal_button.js +3 -3
  40. data/app/assets/stylesheets/spree/frontend/solidus_paypal_braintree.css +12 -0
  41. data/app/decorators/controllers/solidus_paypal_braintree/admin_payments_controller_decorator.rb +11 -0
  42. data/app/decorators/controllers/solidus_paypal_braintree/checkout_controller_decorator.rb +11 -0
  43. data/app/decorators/controllers/solidus_paypal_braintree/client_tokens_controller.rb +41 -0
  44. data/app/decorators/controllers/solidus_paypal_braintree/orders_controller_decorator.rb +11 -0
  45. data/app/decorators/models/solidus_paypal_braintree/spree/store_decorator.rb +20 -0
  46. data/app/decorators/models/solidus_paypal_braintree/spree/user_decorator.rb +13 -0
  47. data/app/helpers/solidus_paypal_braintree/braintree_admin_helper.rb +23 -0
  48. data/app/helpers/solidus_paypal_braintree/braintree_checkout_helper.rb +60 -0
  49. data/app/models/application_record.rb +2 -0
  50. data/app/models/solidus_paypal_braintree/address.rb +64 -0
  51. data/app/models/solidus_paypal_braintree/avs_result.rb +3 -0
  52. data/app/models/solidus_paypal_braintree/configuration.rb +39 -3
  53. data/app/models/solidus_paypal_braintree/customer.rb +7 -3
  54. data/app/models/solidus_paypal_braintree/gateway.rb +80 -21
  55. data/app/models/solidus_paypal_braintree/response.rb +3 -2
  56. data/app/models/solidus_paypal_braintree/source.rb +51 -8
  57. data/app/models/solidus_paypal_braintree/transaction.rb +5 -3
  58. data/app/models/solidus_paypal_braintree/transaction_address.rb +34 -12
  59. data/app/models/solidus_paypal_braintree/transaction_import.rb +17 -12
  60. data/app/overrides/spree/payments/payment/add_paypal_funding_source_to_payment.rb +9 -0
  61. data/app/views/spree/api/payments/source_views/_paypal_braintree.json.jbuilder +3 -0
  62. data/app/views/spree/checkout/existing_payment/_paypal_braintree.html.erb +10 -0
  63. data/app/views/spree/shared/_apple_pay_button.html.erb +2 -2
  64. data/app/views/spree/shared/_braintree_errors.html.erb +14 -17
  65. data/app/views/spree/shared/_braintree_hosted_fields.html.erb +24 -9
  66. data/app/views/spree/shared/_paypal_braintree_head_scripts.html.erb +13 -6
  67. data/app/views/spree/shared/_paypal_cart_button.html.erb +18 -2
  68. data/app/views/spree/shared/_paypal_messaging.html.erb +13 -0
  69. data/app/views/spree/shared/_venmo_button.html.erb +33 -0
  70. data/bin/console +17 -0
  71. data/bin/rails +15 -0
  72. data/bin/setup +8 -0
  73. data/config/locales/en.yml +44 -0
  74. data/config/locales/it.yml +53 -8
  75. data/config/routes.rb +2 -0
  76. data/db/migrate/20160906201711_create_solidus_paypal_braintree_customers.rb +3 -1
  77. data/db/migrate/20161125172005_add_braintree_configuration_to_stores.rb +5 -7
  78. data/db/migrate/20170505193712_add_null_constraint_to_sources.rb +3 -1
  79. data/db/migrate/20190705115327_add_paypal_button_preferences_to_braintree_configurations.rb +5 -0
  80. data/db/migrate/20190911141712_add_3d_secure_to_braintree_configuration.rb +5 -0
  81. data/db/migrate/20211222170950_add_paypal_funding_source_to_solidus_paypal_braintree_sources.rb +5 -0
  82. data/db/migrate/20220104150301_add_venmo_to_braintree_configuration.rb +5 -0
  83. data/lib/controllers/backend/solidus_paypal_braintree/configurations_controller.rb +23 -5
  84. data/lib/controllers/frontend/solidus_paypal_braintree/checkouts_controller.rb +25 -21
  85. data/lib/controllers/frontend/solidus_paypal_braintree/transactions_controller.rb +56 -51
  86. data/lib/generators/solidus_paypal_braintree/install/install_generator.rb +7 -5
  87. data/lib/solidus_paypal_braintree/country_mapper.rb +4 -2
  88. data/lib/solidus_paypal_braintree/engine.rb +17 -13
  89. data/lib/solidus_paypal_braintree/factories.rb +39 -4
  90. data/lib/solidus_paypal_braintree/request_protection.rb +3 -0
  91. data/lib/solidus_paypal_braintree/version.rb +3 -1
  92. data/lib/solidus_paypal_braintree.rb +4 -0
  93. data/lib/views/backend/solidus_paypal_braintree/configurations/list.html.erb +38 -5
  94. data/lib/views/backend/spree/admin/payments/source_forms/_paypal_braintree.html.erb +2 -2
  95. data/lib/views/backend/spree/admin/payments/source_views/_paypal_braintree.html.erb +7 -2
  96. data/lib/views/backend/spree/admin/shared/preference_fields/_preference_select.html.erb +13 -0
  97. data/lib/views/backend_v1.2/spree/admin/payments/source_forms/_paypal_braintree.html.erb +2 -2
  98. data/lib/views/frontend/solidus_paypal_braintree/payments/_payment.html.erb +12 -0
  99. data/lib/views/frontend/spree/checkout/payment/_paypal_braintree.html.erb +8 -2
  100. data/lib/views/frontend/spree/shared/_paypal_checkout_button.html.erb +32 -0
  101. data/solidus_paypal_braintree.gemspec +42 -0
  102. metadata +95 -188
  103. data/app/controllers/solidus_paypal_braintree/client_tokens_controller.rb +0 -22
  104. data/app/helpers/braintree_admin_helper.rb +0 -18
  105. data/app/models/spree/store_decorator.rb +0 -11
  106. data/app/views/spree/shared/_paypal_checkout_button.html.erb +0 -27
  107. data/config/initializers/braintree.rb +0 -1
@@ -0,0 +1,86 @@
1
+ //= require solidus_paypal_braintree/constants
2
+ /**
3
+ * Constructor for Venmo button object
4
+ * @constructor
5
+ * @param {object} element - The DOM element of your Venmo button
6
+ */
7
+ SolidusPaypalBraintree.VenmoButton = function(element, venmoOptions) {
8
+ this._element = element;
9
+ this._client = null;
10
+ this._venmoOptions = venmoOptions || {};
11
+
12
+ if(!this._element) {
13
+ throw new Error("Element for the Venmo button must be present on the page");
14
+ }
15
+ };
16
+
17
+ /**
18
+ * Creates the Venmo session using the provided options and enables the button
19
+ *
20
+ * @param {object} options - The options passed to tokenize when constructing
21
+ * the Venmo instance
22
+ *
23
+ * See {@link https://braintree.github.io/braintree-web/3.84.0/module-braintree-web_venmo.html#.create}
24
+ */
25
+ SolidusPaypalBraintree.VenmoButton.prototype.initialize = function() {
26
+ this._client = new SolidusPaypalBraintree.createClient({
27
+ useVenmo: true,
28
+ newBrowserTabSupported: this._venmoOptions.newBrowserTabSupported,
29
+ flow: this._venmoOptions.flow
30
+ });
31
+
32
+ return this._client.initialize().then(this.initializeCallback.bind(this));
33
+ };
34
+
35
+ SolidusPaypalBraintree.VenmoButton.prototype.initializeCallback = function() {
36
+ this._venmoInstance = this._client.getVenmoInstance();
37
+
38
+ this._element.classList.add('visible');
39
+
40
+ // Check if tokenization results already exist. This occurs when your
41
+ // checkout page is relaunched in a new tab.
42
+ if (!this._venmoOptions.newBrowserTabSupported && this._venmoInstance.hasTokenizationResult()) {
43
+ this.tokenize();
44
+ }
45
+
46
+ this._element.addEventListener('click', function(event) {
47
+ event.preventDefault();
48
+ this._element.disabled = true;
49
+ this.initializeVenmoSession();
50
+ }.bind(this), false);
51
+ };
52
+
53
+ SolidusPaypalBraintree.VenmoButton.prototype.initializeVenmoSession = function() {
54
+ this.tokenize();
55
+ };
56
+
57
+ SolidusPaypalBraintree.VenmoButton.prototype.tokenize = function() {
58
+ var venmoButton = this._element;
59
+ this._venmoInstance.tokenize().then(handleVenmoSuccess).catch(handleVenmoError).then(function () {
60
+ venmoButton.removeAttribute('disabled');
61
+ });
62
+ };
63
+
64
+ function handleVenmoSuccess(payload) {
65
+ var $paymentForm = $("#checkout_form_payment");
66
+ var $nonceField = $("#venmo_payment_method_nonce", $paymentForm);
67
+
68
+ // Disable hostedFields' and enable Venmo's inputs as they use the same fields.
69
+ // Otherwise, they will clash. (Disabled inputs are not used on form submission)
70
+ $('.hosted-fields input').each(function(_index, input) {
71
+ input.disabled = true;
72
+ });
73
+ $('.venmo-fields input').each(function(_index, input) {
74
+ input.removeAttribute('disabled');
75
+ });
76
+
77
+ // remove hostedFields submit listener, otherwise empty credit card errors occur
78
+ $paymentForm.off('submit');
79
+
80
+ $nonceField.val(payload.nonce);
81
+ $paymentForm.submit();
82
+ }
83
+
84
+ function handleVenmoError(error) {
85
+ SolidusPaypalBraintree.config.braintreeErrorHandle(error);
86
+ }
@@ -68,8 +68,8 @@ $(function() {
68
68
  if (!$paymentForm.length || !$hostedFields.length) { return; }
69
69
 
70
70
  $.when(
71
- $.getScript("https://js.braintreegateway.com/web/3.34.0/js/client.min.js"),
72
- $.getScript("https://js.braintreegateway.com/web/3.34.0/js/hosted-fields.min.js")
71
+ $.getScript("https://js.braintreegateway.com/web/3.84.0/js/client.min.js"),
72
+ $.getScript("https://js.braintreegateway.com/web/3.84.0/js/hosted-fields.min.js")
73
73
  ).done(function() {
74
74
  $hostedFields.each(function() {
75
75
  var $this = $(this),
@@ -4,9 +4,9 @@
4
4
  $(document).ready(function() {
5
5
  if (document.getElementById("empty-cart")) {
6
6
  $.when(
7
- $.getScript("https://js.braintreegateway.com/web/3.31.0/js/client.min.js"),
8
- $.getScript("https://js.braintreegateway.com/web/3.31.0/js/paypal-checkout.min.js"),
9
- $.getScript("https://js.braintreegateway.com/web/3.31.0/js/data-collector.min.js")
7
+ $.getScript("https://js.braintreegateway.com/3.84.0/js/client.min.js"),
8
+ $.getScript("https://js.braintreegateway.com/3.84.0/js/paypal-checkout.min.js"),
9
+ $.getScript("https://js.braintreegateway.com/3.84.0/js/data-collector.min.js")
10
10
  ).done(function() {
11
11
  $("#content").append('<div id="paypal-button"/>');
12
12
  $('<script/>').attr({
@@ -37,3 +37,15 @@ the installer will append this file to the app vendored assets here: 'vendor/ass
37
37
  .apple-pay-button.visible {
38
38
  visibility: visible;
39
39
  }
40
+
41
+ .venmo-button {
42
+ visibility: hidden;
43
+ border: none;
44
+ height: 48px;
45
+ background-color: transparent;
46
+ background-repeat: no-repeat;
47
+ }
48
+
49
+ .venmo-button.visible {
50
+ visibility: visible;
51
+ }
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPaypalBraintree
4
+ module AdminPaymentsControllerDecorator
5
+ def self.prepended(base)
6
+ base.helper ::SolidusPaypalBraintree::BraintreeAdminHelper
7
+ end
8
+
9
+ ::Spree::Admin::PaymentsController.prepend(self)
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPaypalBraintree
4
+ module CheckoutControllerDecorator
5
+ def self.prepended(base)
6
+ base.helper ::SolidusPaypalBraintree::BraintreeCheckoutHelper
7
+ end
8
+
9
+ ::Spree::CheckoutController.prepend(self) if SolidusSupport.frontend_available?
10
+ end
11
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPaypalBraintree
4
+ class ClientTokensController < ::Spree::Api::BaseController
5
+ skip_before_action :authenticate_user
6
+
7
+ before_action :load_gateway
8
+
9
+ def create
10
+ token = @gateway.generate_token
11
+ if token
12
+ render json: { client_token: token, payment_method_id: @gateway.id }
13
+ else
14
+ render json: { error: Gateway::TOKEN_GENERATION_DISABLED_MESSAGE }, status: :unprocessable_entity
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def load_gateway
21
+ if params[:payment_method_id]
22
+ @gateway = ::SolidusPaypalBraintree::Gateway.find(params[:payment_method_id])
23
+ else
24
+ store_payment_methods_scope =
25
+ if current_store.payment_methods.empty?
26
+ ::SolidusPaypalBraintree::Gateway.all
27
+ else
28
+ ::SolidusPaypalBraintree::Gateway.where(id: current_store.payment_method_ids)
29
+ end
30
+ @gateway = ::SolidusPaypalBraintree::Gateway.where(active: true).merge(store_payment_methods_scope).first!
31
+ end
32
+ end
33
+
34
+ def generate_token
35
+ @gateway.generate_token
36
+ rescue ::SolidusPaypalBraintree::Gateway::TokenGenerationDisabledError => e
37
+ Rails.logger.error e
38
+ nil
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPaypalBraintree
4
+ module OrdersControllerDecorator
5
+ def self.prepended(base)
6
+ base.helper ::SolidusPaypalBraintree::BraintreeCheckoutHelper
7
+ end
8
+
9
+ ::Spree::OrdersController.prepend(self) if SolidusSupport.frontend_available?
10
+ end
11
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPaypalBraintree
4
+ module Spree
5
+ module StoreDecorator
6
+ def self.prepended(base)
7
+ base.has_one :braintree_configuration, class_name: "SolidusPaypalBraintree::Configuration", dependent: :destroy
8
+ base.before_create :build_default_configuration
9
+ end
10
+
11
+ private
12
+
13
+ def build_default_configuration
14
+ build_braintree_configuration unless braintree_configuration
15
+ end
16
+
17
+ ::Spree::Store.prepend self
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPaypalBraintree
4
+ module Spree
5
+ module UserDecorator
6
+ def self.prepended(base)
7
+ base.has_one :braintree_customer, class_name: 'SolidusPaypalBraintree::Customer', inverse_of: :user
8
+ end
9
+
10
+ ::Spree.user_class.prepend self
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPaypalBraintree
4
+ module BraintreeAdminHelper
5
+ # Returns a link to the Braintree web UI for the given Braintree payment
6
+ def braintree_transaction_link(payment)
7
+ environment = payment.payment_method.preferred_environment == 'sandbox' ? 'sandbox' : 'www'
8
+ merchant_id = payment.payment_method.preferred_merchant_id
9
+ response_code = payment.response_code
10
+
11
+ return if response_code.blank?
12
+ return response_code if merchant_id.blank?
13
+
14
+ link_to(
15
+ response_code,
16
+ "https://#{environment}.braintreegateway.com/merchants/#{merchant_id}/transactions/#{response_code}",
17
+ title: 'Show payment on Braintree',
18
+ target: '_blank',
19
+ rel: 'noopener'
20
+ )
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPaypalBraintree
4
+ module BraintreeCheckoutHelper
5
+ def braintree_3ds_options_for(order)
6
+ ship_address = SolidusPaypalBraintree::Address.new(order.ship_address)
7
+ bill_address = SolidusPaypalBraintree::Address.new(order.bill_address)
8
+ {
9
+ nonce: nil, # populated after tokenization
10
+ bin: nil, # populated after tokenization
11
+ onLookupComplete: nil, # populated after tokenization
12
+ amount: order.total,
13
+ email: order.email,
14
+ billingAddress: {
15
+ givenName: bill_address.firstname,
16
+ surname: bill_address.lastname,
17
+ phoneNumber: bill_address.phone,
18
+ streetAddress: bill_address.address1,
19
+ extendedAddress: bill_address.address2,
20
+ locality: bill_address.city,
21
+ region: bill_address.state&.abbr,
22
+ postalCode: bill_address.zipcode,
23
+ countryCodeAlpha2: bill_address.country&.iso,
24
+ },
25
+ additionalInformation: {
26
+ shippingGivenName: ship_address.firstname,
27
+ shippingSurname: ship_address.lastname,
28
+ shippingPhone: ship_address.phone,
29
+ shippingAddress: {
30
+ streedAddress: ship_address.address1,
31
+ extendedAddress: ship_address.address2,
32
+ locality: ship_address.city,
33
+ region: ship_address.state&.abbr,
34
+ postalCode: ship_address.zipcode,
35
+ countryCodeAlpha2: ship_address.country&.iso,
36
+ }
37
+ }
38
+ }
39
+ end
40
+
41
+ def paypal_button_preference(key, store:)
42
+ store.braintree_configuration.preferences[key]
43
+ end
44
+
45
+ def venmo_button_style(store)
46
+ configuration = store.braintree_configuration
47
+ color = configuration.preferred_venmo_button_color
48
+ width = configuration.preferred_venmo_button_width
49
+
50
+ { width: width, color: color }
51
+ end
52
+
53
+ def venmo_button_asset_url(style, active: false)
54
+ prefix = 'solidus_paypal_braintree/venmo/venmo_'
55
+ active_string = active ? 'active_' : ''
56
+ path = "#{prefix}#{active_string}#{style[:color]}_button_#{style[:width]}x48.svg"
57
+ asset_path(path)
58
+ end
59
+ end
60
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ApplicationRecord < ActiveRecord::Base
2
4
  self.abstract_class = true
3
5
  end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPaypalBraintree
4
+ class Address
5
+ delegate :address1,
6
+ :address2,
7
+ :city,
8
+ :country,
9
+ :phone,
10
+ :state,
11
+ :zipcode,
12
+ to: :spree_address
13
+
14
+ def self.split_name(name)
15
+ if defined?(Spree::Address::Name)
16
+ address_name = Spree::Address::Name.new(name)
17
+ [address_name.first_name, address_name.last_name]
18
+ else
19
+ name.strip.split(' ', 2)
20
+ end
21
+ end
22
+
23
+ def initialize(spree_address)
24
+ @spree_address = spree_address
25
+ end
26
+
27
+ def to_json(*_args)
28
+ address_hash = {
29
+ line1: address1,
30
+ line2: address2,
31
+ city: city,
32
+ postalCode: zipcode,
33
+ countryCode: country.iso,
34
+ phone: phone,
35
+ recipientName: "#{firstname} #{lastname}"
36
+ }
37
+
38
+ if ::Spree::Config.address_requires_state && country.states_required
39
+ address_hash[:state] = state.name
40
+ end
41
+ address_hash.to_json
42
+ end
43
+
44
+ def firstname
45
+ if SolidusSupport.combined_first_and_last_name_in_address?
46
+ self.class.split_name(spree_address.name).first
47
+ else
48
+ spree_address.firstname
49
+ end
50
+ end
51
+
52
+ def lastname
53
+ if SolidusSupport.combined_first_and_last_name_in_address?
54
+ self.class.split_name(spree_address.name).last
55
+ else
56
+ spree_address.lastname
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ attr_reader :spree_address
63
+ end
64
+ end
@@ -41,6 +41,9 @@ module SolidusPaypalBraintree
41
41
  'I' => 'I',
42
42
  'A' => 'I'
43
43
  },
44
+ 'B' => {
45
+ 'B' => 'B'
46
+ },
44
47
  nil => { nil => nil }
45
48
  }.freeze
46
49
 
@@ -1,5 +1,41 @@
1
- class SolidusPaypalBraintree::Configuration < ApplicationRecord
2
- belongs_to :store, class_name: 'Spree::Store'
1
+ # frozen_string_literal: true
3
2
 
4
- validates :store, presence: true
3
+ module SolidusPaypalBraintree
4
+ class Configuration < ::Spree::Base
5
+ PAYPAL_BUTTON_PREFERENCES = {
6
+ color: { availables: %w[gold blue silver white black], default: 'white' },
7
+ shape: { availables: %w[pill rect], default: 'rect' },
8
+ label: { availables: %w[checkout credit pay buynow paypal installment], default: 'checkout' },
9
+ tagline: { availables: %w[true false], default: 'false' },
10
+ layout: { availables: %w[horizontal vertical], default: 'horizontal' },
11
+ messaging: { availables: %w[true false], default: 'false' }
12
+ }.freeze
13
+
14
+ unless respond_to?(:preference)
15
+ include ::Spree::Preferences::Persistable
16
+ end
17
+
18
+ belongs_to :store, class_name: 'Spree::Store', optional: false
19
+
20
+ # Preferences for Paypal button
21
+ PAYPAL_BUTTON_PREFERENCES.each do |name, desc|
22
+ preference_name = "paypal_button_#{name}".to_sym
23
+ attribute_name = "preferred_#{preference_name}".to_sym
24
+
25
+ preference preference_name, :string, default: desc[:default]
26
+
27
+ validates attribute_name, inclusion: desc[:availables]
28
+ end
29
+
30
+ preference :venmo_button_color, :preference_select, default: 'blue'
31
+ preference :venmo_button_width, :preference_select, default: '320'
32
+
33
+ def preferred_venmo_button_color_options
34
+ [["Blue", "blue"], ["White", "white"]]
35
+ end
36
+
37
+ def preferred_venmo_button_width_options
38
+ [["280", "280"], ["320", "320"], ["375", "375"]]
39
+ end
40
+ end
5
41
  end
@@ -1,4 +1,8 @@
1
- class SolidusPaypalBraintree::Customer < ApplicationRecord
2
- belongs_to :user, class_name: Spree::UserClassHandle.new
3
- has_many :sources, class_name: "SolidusPaypalBraintree::Source", inverse_of: :customer
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPaypalBraintree
4
+ class Customer < ApplicationRecord
5
+ belongs_to :user, class_name: ::Spree::UserClassHandle.new, optional: true
6
+ has_many :sources, class_name: "SolidusPaypalBraintree::Source", inverse_of: :customer, dependent: :destroy
7
+ end
4
8
  end