From b9852a720860f1c58219ea63236ca5f9def5453c Mon Sep 17 00:00:00 2001 From: Flavio Auciello Date: Fri, 20 Sep 2019 16:51:54 +0200 Subject: [PATCH 1/3] Let PayPal button to receive locale/style parameters [Here a full list of PayPayl button customizations](https://developer.paypal.com/docs/archive/checkout/how-to/customize-button/#interactive-code-demo) --- .../solidus_paypal_braintree/paypal_button.js | 16 +++++++++++---- app/helpers/braintree_checkout_helper.rb | 5 +++++ .../solidus_paypal_braintree/configuration.rb | 20 ++++++++++++++++++- config/initializers/braintree.rb | 4 ++++ ...preferences_to_braintree_configurations.rb | 5 +++++ .../configurations_controller.rb | 12 ++++++++++- .../configurations/list.html.erb | 6 ++++++ .../shared/_paypal_checkout_button.html.erb | 10 +++++++++- 8 files changed, 71 insertions(+), 7 deletions(-) create mode 100644 app/helpers/braintree_checkout_helper.rb create mode 100644 db/migrate/20190705115327_add_paypal_button_preferences_to_braintree_configurations.rb rename {app/views => lib/views/frontend}/spree/shared/_paypal_checkout_button.html.erb (62%) diff --git a/app/assets/javascripts/solidus_paypal_braintree/paypal_button.js b/app/assets/javascripts/solidus_paypal_braintree/paypal_button.js index e1357625..4b86d26c 100644 --- a/app/assets/javascripts/solidus_paypal_braintree/paypal_button.js +++ b/app/assets/javascripts/solidus_paypal_braintree/paypal_button.js @@ -7,6 +7,12 @@ SolidusPaypalBraintree.PaypalButton = function(element, paypalOptions, options) { this._element = element; this._paypalOptions = paypalOptions || {}; + + this.locale = paypalOptions['locale'] || "en_US"; + this.style = paypalOptions['style'] || {}; + delete paypalOptions['locale']; + delete paypalOptions['style']; + this._options = options || {}; this._client = null; this._environment = this._paypalOptions.environment || 'sandbox'; @@ -34,17 +40,19 @@ SolidusPaypalBraintree.PaypalButton.prototype.initialize = function() { SolidusPaypalBraintree.PaypalButton.prototype.initializeCallback = function() { this._paymentMethodId = this._client.paymentMethodId; - paypal.Button.render({ + var render_options = { env: this._environment, - + locale: this.locale, + style: this.style, payment: function () { return this._client.getPaypalInstance().createPayment(this._paypalOptions); }.bind(this), - onAuthorize: function (data, actions) { return this._client.getPaypalInstance().tokenizePayment(data, this._tokenizeCallback.bind(this)); }.bind(this) - }, this._element); + }; + + paypal.Button.render(render_options, this._element); }; /** diff --git a/app/helpers/braintree_checkout_helper.rb b/app/helpers/braintree_checkout_helper.rb new file mode 100644 index 00000000..d481dc58 --- /dev/null +++ b/app/helpers/braintree_checkout_helper.rb @@ -0,0 +1,5 @@ +module BraintreeCheckoutHelper + def paypal_button_preference(key, store:) + store.braintree_configuration.preferences[key] + end +end diff --git a/app/models/solidus_paypal_braintree/configuration.rb b/app/models/solidus_paypal_braintree/configuration.rb index bddbc798..209e8078 100644 --- a/app/models/solidus_paypal_braintree/configuration.rb +++ b/app/models/solidus_paypal_braintree/configuration.rb @@ -1,5 +1,23 @@ -class SolidusPaypalBraintree::Configuration < ApplicationRecord +class SolidusPaypalBraintree::Configuration < Spree::Base + PAYPAL_BUTTON_PREFERENCES = { + color: { availables: %w[gold blue silver white black], default: 'white' }, + size: { availables: %w[small medium large responsive], default: 'small' }, + shape: { availables: %w[pill rect], default: 'rect' }, + label: { availables: %w[checkout credit pay buynow paypal installment], default: 'checkout' }, + tagline: { availables: %w[true false], default: 'false' } + } + belongs_to :store, class_name: 'Spree::Store' validates :store, presence: true + + # Preferences for Paypal button + PAYPAL_BUTTON_PREFERENCES.each do |name, desc| + preference_name = "paypal_button_#{name}".to_sym + attribute_name = "preferred_#{preference_name}".to_sym + + preference preference_name, :string, default: desc[:default] + + validates attribute_name, inclusion: desc[:availables] + end end diff --git a/config/initializers/braintree.rb b/config/initializers/braintree.rb index 3cd773ae..77c51874 100644 --- a/config/initializers/braintree.rb +++ b/config/initializers/braintree.rb @@ -1,3 +1,7 @@ if SolidusSupport.backend_available? Spree::Admin::PaymentsController.helper :braintree_admin end + +if SolidusSupport.frontend_available? + Spree::CheckoutController.helper :braintree_checkout +end diff --git a/db/migrate/20190705115327_add_paypal_button_preferences_to_braintree_configurations.rb b/db/migrate/20190705115327_add_paypal_button_preferences_to_braintree_configurations.rb new file mode 100644 index 00000000..99c57cd6 --- /dev/null +++ b/db/migrate/20190705115327_add_paypal_button_preferences_to_braintree_configurations.rb @@ -0,0 +1,5 @@ +class AddPaypalButtonPreferencesToBraintreeConfigurations < ActiveRecord::Migration[5.1] + def change + add_column :solidus_paypal_braintree_configurations, :preferences, :text + end +end diff --git a/lib/controllers/backend/solidus_paypal_braintree/configurations_controller.rb b/lib/controllers/backend/solidus_paypal_braintree/configurations_controller.rb index 9d28b88e..5619ffe2 100644 --- a/lib/controllers/backend/solidus_paypal_braintree/configurations_controller.rb +++ b/lib/controllers/backend/solidus_paypal_braintree/configurations_controller.rb @@ -24,7 +24,17 @@ def update def configurations_params params.require(:configurations). - permit(configuration_fields: [:paypal, :apple_pay, :credit_card]) + permit(configuration_fields: [ + :paypal, + :apple_pay, + :credit_card, + :preferred_paypal_button_locale, + :preferred_paypal_button_color, + :preferred_paypal_button_size, + :preferred_paypal_button_shape, + :preferred_paypal_button_label, + :preferred_paypal_button_tagline + ]) end end end diff --git a/lib/views/backend/solidus_paypal_braintree/configurations/list.html.erb b/lib/views/backend/solidus_paypal_braintree/configurations/list.html.erb index bf6c6cd7..f16f9d11 100644 --- a/lib/views/backend/solidus_paypal_braintree/configurations/list.html.erb +++ b/lib/views/backend/solidus_paypal_braintree/configurations/list.html.erb @@ -21,6 +21,12 @@ <%= c.label :credit_card %> <%= c.check_box :credit_card %> + + <% config.admin_form_preference_names.each do |name| %> + <%= render "spree/admin/shared/preference_fields/#{config.preference_type(name)}", + form: c, attribute: "preferred_#{name}", + label: t(name, scope: 'spree', default: name.to_s.humanize) %> + <% end %> <% end %> diff --git a/app/views/spree/shared/_paypal_checkout_button.html.erb b/lib/views/frontend/spree/shared/_paypal_checkout_button.html.erb similarity index 62% rename from app/views/spree/shared/_paypal_checkout_button.html.erb rename to lib/views/frontend/spree/shared/_paypal_checkout_button.html.erb index c01da05b..3e3dedcf 100644 --- a/app/views/spree/shared/_paypal_checkout_button.html.erb +++ b/lib/views/frontend/spree/shared/_paypal_checkout_button.html.erb @@ -21,7 +21,15 @@ enableShippingAddress: true, shippingAddressOverride: address, shippingAddressEditable: false, - environment: '<%= Rails.env.production? ? "production" : "sandbox" %>' + environment: '<%= Rails.env.production? ? "production" : "sandbox" %>', + locale: '<%= paypal_button_preference(:paypal_button_locale, store: current_store) %>', + style: { + color: '<%= paypal_button_preference(:paypal_button_color, store: current_store) %>', + size: '<%= paypal_button_preference(:paypal_button_size, store: current_store) %>', + shape: '<%= paypal_button_preference(:paypal_button_shape, store: current_store) %>', + label: '<%= paypal_button_preference(:paypal_button_label, store: current_store) %>', + tagline: '<%= paypal_button_preference(:paypal_button_tagline, store: current_store) %>' + } } var button = new SolidusPaypalBraintree.createPaypalButton(document.querySelector("#paypal-button"), paypalOptions); From a384d554ff06f954e525c7a34237c53dfa2cdb6c Mon Sep 17 00:00:00 2001 From: Flavio Auciello Date: Fri, 20 Sep 2019 16:53:31 +0200 Subject: [PATCH 2/3] Add spec for custom Paypal button style at checkout --- .../features/frontend/paypal_checkout_spec.rb | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/spec/features/frontend/paypal_checkout_spec.rb b/spec/features/frontend/paypal_checkout_spec.rb index f2b569d1..d223eb1c 100644 --- a/spec/features/frontend/paypal_checkout_spec.rb +++ b/spec/features/frontend/paypal_checkout_spec.rb @@ -32,6 +32,26 @@ expect(page).to have_content("Your order has been processed successfully") end end + + context 'using custom paypal button style' do + before do + store.braintree_configuration.tap do |conf| + conf.set_preference(:paypal_button_color, 'blue') + conf.save! + end + end + + it 'should display required PayPal button style' do + pend_if_paypal_slow do + expect_any_instance_of(Spree::Order).to receive(:restart_checkout_flow) + move_through_paypal_popup + + within(find('#paypal-button iframe')) do + expect(page).to have_selector('[class="paypal-button-color-blue]') + end + end + end + end end context "goes through regular checkout using paypal payment method" do From 673e50da2e809cfc513ed23e267a15f94719eda9 Mon Sep 17 00:00:00 2001 From: Flavio Auciello Date: Fri, 27 Sep 2019 16:45:14 +0200 Subject: [PATCH 3/3] Fix configurations controller to correctly display errors on update --- .../configurations_controller.rb | 3 ++- .../configurations_controller_spec.rb | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/controllers/backend/solidus_paypal_braintree/configurations_controller.rb b/lib/controllers/backend/solidus_paypal_braintree/configurations_controller.rb index 5619ffe2..222a51d2 100644 --- a/lib/controllers/backend/solidus_paypal_braintree/configurations_controller.rb +++ b/lib/controllers/backend/solidus_paypal_braintree/configurations_controller.rb @@ -12,7 +12,8 @@ def update authorize! :update, SolidusPaypalBraintree::Configuration params = configurations_params[:configuration_fields] - if SolidusPaypalBraintree::Configuration.update(params.keys, params.values) + results = SolidusPaypalBraintree::Configuration.update(params.keys, params.values) + if results.all? { |r| r.valid? } flash[:success] = t('update_success', scope: 'solidus_paypal_braintree.configurations') else flash[:error] = t('update_error', scope: 'solidus_paypal_braintree.configurations') diff --git a/spec/controllers/solidus_paypal_braintree/configurations_controller_spec.rb b/spec/controllers/solidus_paypal_braintree/configurations_controller_spec.rb index 98e23461..3f87080a 100644 --- a/spec/controllers/solidus_paypal_braintree/configurations_controller_spec.rb +++ b/spec/controllers/solidus_paypal_braintree/configurations_controller_spec.rb @@ -25,12 +25,17 @@ end describe "POST #update" do + let(:paypal_button_color) { 'blue' } let(:configurations_params) do { configurations: { configuration_fields: { store_1_config.id.to_s => { paypal: true, apple_pay: true }, - store_2_config.id.to_s => { paypal: true, apple_pay: false } + store_2_config.id.to_s => { + paypal: true, + apple_pay: false, + preferred_paypal_button_color: paypal_button_color + } } } } @@ -55,7 +60,7 @@ end context "with invalid parameters" do - before { allow(SolidusPaypalBraintree::Configuration).to receive(:update) { false } } + let(:paypal_button_color) { 'invalid-color'} it "displays an error message to the user" do subject